summaryrefslogtreecommitdiffstats
path: root/xbmc/guilib/D3DResource.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/guilib/D3DResource.h')
-rw-r--r--xbmc/guilib/D3DResource.h293
1 files changed, 293 insertions, 0 deletions
diff --git a/xbmc/guilib/D3DResource.h b/xbmc/guilib/D3DResource.h
new file mode 100644
index 0000000..e7f6517
--- /dev/null
+++ b/xbmc/guilib/D3DResource.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "GUIColorManager.h"
+#include "utils/ColorUtils.h"
+#include "utils/Geometry.h"
+
+#include <map>
+
+#include <DirectXMath.h>
+#include <d3dx11effect.h>
+#include <wrl/client.h>
+
+#define KODI_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT 4
+
+typedef enum SHADER_METHOD {
+ SHADER_METHOD_RENDER_DEFAULT,
+ SHADER_METHOD_RENDER_TEXTURE_NOBLEND,
+ SHADER_METHOD_RENDER_FONT,
+ SHADER_METHOD_RENDER_TEXTURE_BLEND,
+ SHADER_METHOD_RENDER_MULTI_TEXTURE_BLEND,
+ SHADER_METHOD_RENDER_STEREO_INTERLACED_LEFT,
+ SHADER_METHOD_RENDER_STEREO_INTERLACED_RIGHT,
+ SHADER_METHOD_RENDER_STEREO_CHECKERBOARD_LEFT,
+ SHADER_METHOD_RENDER_STEREO_CHECKERBOARD_RIGHT,
+ SHADER_METHOD_RENDER_COUNT
+} _SHADER_METHOD;
+
+class ID3DResource
+{
+public:
+ virtual ~ID3DResource() {}
+
+ virtual void OnDestroyDevice(bool fatal)=0;
+ virtual void OnCreateDevice()=0;
+
+protected:
+ void Register();
+ void Unregister();
+
+ bool m_bRegistered = false;
+};
+
+class CD3DHelper
+{
+public:
+ static inline void XMStoreColor(float* floats, DWORD dword)
+ {
+ floats[0] = float((dword >> 16) & 0xFF) * (1.0f / 255.0f); // r
+ floats[1] = float((dword >> 8) & 0xFF) * (1.0f / 255.0f); // g
+ floats[2] = float((dword >> 0) & 0xFF) * (1.0f / 255.0f); // b
+ floats[3] = float((dword >> 24) & 0xFF) * (1.0f / 255.0f); // a
+ }
+
+ static inline void XMStoreColor(DirectX::XMFLOAT4* floats, DWORD dword)
+ {
+ XMStoreColor(reinterpret_cast<float*>(floats), dword);
+ }
+
+ static inline void XMStoreColor(float* floats, unsigned char a, unsigned char r, unsigned char g, unsigned char b)
+ {
+ floats[0] = r * (1.0f / 255.0f);
+ floats[1] = g * (1.0f / 255.0f);
+ floats[2] = b * (1.0f / 255.0f);
+ floats[3] = a * (1.0f / 255.0f);
+ }
+
+ static inline void XMStoreColor(DirectX::XMFLOAT4* floats, unsigned char a, unsigned char r, unsigned char g, unsigned char b)
+ {
+ XMStoreColor(reinterpret_cast<float*>(floats), a, r, g, b);
+ }
+
+ // helper function to properly "clear" shader resources
+ static inline void PSClearShaderResources(ID3D11DeviceContext* pContext)
+ {
+ ID3D11ShaderResourceView* shader_resource_views[KODI_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
+ pContext->PSSetShaderResources(0, ARRAYSIZE(shader_resource_views), shader_resource_views);
+ }
+
+ static size_t BitsPerPixel(DXGI_FORMAT fmt);
+};
+
+class CD3DTexture : public ID3DResource
+{
+public:
+ CD3DTexture();
+ virtual ~CD3DTexture();
+
+ bool Create(UINT width, UINT height, UINT mipLevels, D3D11_USAGE usage, DXGI_FORMAT format, const void* pInitData = nullptr, unsigned int srcPitch = 0);
+
+ void Release();
+ bool GetDesc(D3D11_TEXTURE2D_DESC *desc) const;
+ bool LockRect(UINT subresource, D3D11_MAPPED_SUBRESOURCE *res, D3D11_MAP mapType) const;
+ bool UnlockRect(UINT subresource) const;
+
+ // Accessors
+ ID3D11Texture2D* Get() const { return m_texture.Get(); }
+ ID3D11ShaderResourceView* GetShaderResource(DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN);
+ ID3D11ShaderResourceView** GetAddressOfSRV(DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN);
+ ID3D11RenderTargetView* GetRenderTarget();
+ ID3D11RenderTargetView** GetAddressOfRTV();
+ UINT GetWidth() const { return m_width; }
+ UINT GetHeight() const { return m_height; }
+ DXGI_FORMAT GetFormat() const { return m_format; }
+ void GenerateMipmaps();
+
+ // static methods
+ static void DrawQuad(const CPoint points[4],
+ UTILS::COLOR::Color color,
+ CD3DTexture* texture,
+ const CRect* texCoords,
+ SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
+
+ static void DrawQuad(const CPoint points[4],
+ UTILS::COLOR::Color color,
+ unsigned numViews,
+ ID3D11ShaderResourceView** view,
+ const CRect* texCoords,
+ SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
+
+ static void DrawQuad(const CRect& coords,
+ UTILS::COLOR::Color color,
+ CD3DTexture* texture,
+ const CRect* texCoords,
+ SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
+
+ static void DrawQuad(const CRect& coords,
+ UTILS::COLOR::Color color,
+ unsigned numViews,
+ ID3D11ShaderResourceView** view,
+ const CRect* texCoords,
+ SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND);
+
+ void OnDestroyDevice(bool fatal) override;
+ void OnCreateDevice() override;
+
+protected:
+ ID3D11RenderTargetView* GetRenderTargetInternal(unsigned idx = 0);
+ unsigned int GetMemoryUsage(unsigned int pitch) const;
+ bool CreateInternal(const void* pInitData = nullptr, unsigned int srcPitch = 0);
+
+ void SaveTexture();
+ void RestoreTexture();
+
+ // saved data
+ BYTE* m_data;
+ // creation parameters
+ UINT m_width;
+ UINT m_height;
+ UINT m_mipLevels;
+ UINT m_pitch;
+ UINT m_bindFlags;
+ UINT m_cpuFlags;
+ UINT m_viewIdx;
+ D3D11_USAGE m_usage;
+ DXGI_FORMAT m_format;
+
+ // created texture
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> m_texture;
+ Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_renderTargets[2];
+ // store views in different formats
+ std::map<DXGI_FORMAT, Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>> m_views;
+};
+
+typedef std::map<std::string, std::string> DefinesMap;
+
+class CD3DEffect : public ID3DResource, public ID3DInclude
+{
+public:
+ CD3DEffect();
+ virtual ~CD3DEffect();
+ bool Create(const std::string &effectString, DefinesMap* defines);
+ void Release();
+ bool SetFloatArray(LPCSTR handle, const float* val, unsigned int count);
+ bool SetMatrix(LPCSTR handle, const float* mat);
+ bool SetTechnique(LPCSTR handle);
+ bool SetTexture(LPCSTR handle, CD3DTexture &texture);
+ bool SetResources(LPCSTR handle, ID3D11ShaderResourceView** ppSRViews, size_t count);
+ bool SetConstantBuffer(LPCSTR handle, ID3D11Buffer *buffer);
+ bool SetScalar(LPCSTR handle, float value);
+ bool Begin(UINT *passes, DWORD flags);
+ bool BeginPass(UINT pass);
+ bool EndPass();
+ bool End();
+
+ ID3DX11Effect* Get() const { return m_effect.Get(); }
+
+ void OnDestroyDevice(bool fatal) override;
+ void OnCreateDevice() override;
+
+ // ID3DInclude interface
+ __declspec(nothrow) HRESULT __stdcall Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) override;
+ __declspec(nothrow) HRESULT __stdcall Close(LPCVOID pData) override;
+
+private:
+ bool CreateEffect();
+
+ std::string m_effectString;
+ DefinesMap m_defines;
+ Microsoft::WRL::ComPtr<ID3DX11Effect> m_effect;
+ Microsoft::WRL::ComPtr<ID3DX11EffectTechnique> m_techniquie;
+ Microsoft::WRL::ComPtr<ID3DX11EffectPass> m_currentPass;
+};
+
+class CD3DBuffer : public ID3DResource
+{
+public:
+ CD3DBuffer();
+ virtual ~CD3DBuffer();
+ bool Create(D3D11_BIND_FLAG type, UINT count, UINT stride, DXGI_FORMAT format, D3D11_USAGE usage, const void* initData = nullptr);
+ bool Map(void** resource);
+ bool Unmap();
+ void Release();
+ unsigned int GetStride() { return m_stride; }
+ DXGI_FORMAT GetFormat() { return m_format; }
+ ID3D11Buffer* Get() const { return m_buffer.Get(); }
+
+ void OnDestroyDevice(bool fatal) override;
+ void OnCreateDevice() override;
+
+private:
+ bool CreateBuffer(const void *pData);
+
+ // saved data
+ BYTE* m_data;
+ UINT m_length;
+ UINT m_stride;
+ UINT m_cpuFlags;
+ DXGI_FORMAT m_format;
+ D3D11_USAGE m_usage;
+ D3D11_BIND_FLAG m_type;
+ Microsoft::WRL::ComPtr<ID3D11Buffer> m_buffer;
+};
+
+class CD3DVertexShader : public ID3DResource
+{
+public:
+ CD3DVertexShader();
+ ~CD3DVertexShader();
+
+ bool Create(const std::wstring& vertexFile, D3D11_INPUT_ELEMENT_DESC* vertexLayout, unsigned int vertexLayoutSize);
+ bool Create(const void* code, size_t codeLength, D3D11_INPUT_ELEMENT_DESC* vertexLayout, unsigned int vertexLayoutSize);
+ void ReleaseShader();
+ void BindShader();
+ void UnbindShader();
+ void Release();
+ bool IsInited() { return m_inited; }
+
+ void OnDestroyDevice(bool fatal) override;
+ void OnCreateDevice() override;
+
+private:
+ bool CreateInternal();
+
+ bool m_inited;
+ unsigned int m_vertexLayoutSize;
+ D3D11_INPUT_ELEMENT_DESC* m_vertexLayout;
+ Microsoft::WRL::ComPtr<ID3DBlob> m_VSBuffer;
+ Microsoft::WRL::ComPtr<ID3D11VertexShader> m_VS;
+ Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
+};
+
+class CD3DPixelShader : public ID3DResource
+{
+public:
+ CD3DPixelShader();
+ ~CD3DPixelShader();
+
+ bool Create(const std::wstring& wstrFile);
+ bool Create(const void* code, size_t codeLength);
+ void ReleaseShader();
+ void BindShader();
+ void UnbindShader();
+ void Release();
+ bool IsInited() { return m_inited; }
+
+ void OnDestroyDevice(bool fatal) override;
+ void OnCreateDevice() override;
+
+private:
+ bool CreateInternal();
+
+ bool m_inited;
+ Microsoft::WRL::ComPtr<ID3DBlob> m_PSBuffer;
+ Microsoft::WRL::ComPtr<ID3D11PixelShader> m_PS;
+};