/* * Copyright 2011-2023 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE */ #ifndef BGFX_RENDERER_D3D11_H_HEADER_GUARD #define BGFX_RENDERER_D3D11_H_HEADER_GUARD #define USE_D3D11_DYNAMIC_LIB (BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS) #define USE_D3D11_STAGING_BUFFER 0 #if !USE_D3D11_DYNAMIC_LIB # undef BGFX_CONFIG_DEBUG_ANNOTATION # define BGFX_CONFIG_DEBUG_ANNOTATION 0 #endif // !USE_D3D11_DYNAMIC_LIB BX_PRAGMA_DIAGNOSTIC_PUSH(); BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunknown-pragmas" ); BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC("-Wpragmas"); BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4005) // warning C4005: '' : macro redefinition #include #include #define D3D11_NO_HELPERS #if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS # include #elif BX_PLATFORM_WINRT # define __D3D10_1SHADER_H__ // BK - not used keep quiet! # include #else # if !BGFX_CONFIG_DEBUG # define D3DCOMPILE_NO_DEBUG_AND_ALL_FAST_SEMANTICS 1 # endif // !BGFX_CONFIG_DEBUG # include #endif // BX_PLATFORM_* BX_PRAGMA_DIAGNOSTIC_POP() #include "renderer.h" #include "renderer_d3d.h" #include "shader_dxbc.h" #include "debug_renderdoc.h" #include "nvapi.h" #include "dxgi.h" #define BGFX_D3D11_BLEND_STATE_MASK (0 \ | BGFX_STATE_BLEND_MASK \ | BGFX_STATE_BLEND_EQUATION_MASK \ | BGFX_STATE_BLEND_INDEPENDENT \ | BGFX_STATE_BLEND_ALPHA_TO_COVERAGE \ | BGFX_STATE_WRITE_A \ | BGFX_STATE_WRITE_RGB \ ) #define BGFX_D3D11_DEPTH_STENCIL_MASK (0 \ | BGFX_STATE_WRITE_Z \ | BGFX_STATE_DEPTH_TEST_MASK \ ) #define BGFX_D3D11_PROFILER_BEGIN(_view, _abgr) \ BX_MACRO_BLOCK_BEGIN \ PIX_BEGINEVENT(_abgr, s_viewNameW[_view]); \ BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \ BX_MACRO_BLOCK_END #define BGFX_D3D11_PROFILER_BEGIN_LITERAL(_name, _abgr) \ BX_MACRO_BLOCK_BEGIN \ PIX_BEGINEVENT(_abgr, L"" _name); \ BGFX_PROFILER_BEGIN_LITERAL("" _name, _abgr); \ BX_MACRO_BLOCK_END #define BGFX_D3D11_PROFILER_END() \ BX_MACRO_BLOCK_BEGIN \ BGFX_PROFILER_END(); \ PIX_ENDEVENT(); \ BX_MACRO_BLOCK_END namespace bgfx { namespace d3d11 { struct BufferD3D11 { BufferD3D11() : m_ptr(NULL) #if USE_D3D11_STAGING_BUFFER , m_staging(NULL) #endif // USE_D3D11_STAGING_BUFFER , m_srv(NULL) , m_uav(NULL) , m_flags(BGFX_BUFFER_NONE) , m_dynamic(false) { } void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false); void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false); void destroy() { if (NULL != m_ptr) { DX_RELEASE(m_ptr, 0); m_dynamic = false; } #if USE_D3D11_STAGING_BUFFER DX_RELEASE(m_staging, 0); #endif // USE_D3D11_STAGING_BUFFER DX_RELEASE(m_srv, 0); DX_RELEASE(m_uav, 0); } ID3D11Buffer* m_ptr; #if USE_D3D11_STAGING_BUFFER ID3D11Buffer* m_staging; #endif // USE_D3D11_STAGING_BUFFER ID3D11ShaderResourceView* m_srv; ID3D11UnorderedAccessView* m_uav; uint32_t m_size; uint16_t m_flags; bool m_dynamic; }; typedef BufferD3D11 IndexBufferD3D11; struct VertexBufferD3D11 : public BufferD3D11 { VertexBufferD3D11() : BufferD3D11() { } void create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags); VertexLayoutHandle m_layoutHandle; }; struct ShaderD3D11 { ShaderD3D11() : m_ptr(NULL) , m_code(NULL) , m_buffer(NULL) , m_constantBuffer(NULL) , m_hash(0) , m_numUniforms(0) , m_numPredefined(0) , m_hasDepthOp(false) { } void create(const Memory* _mem); void destroy() { if (NULL != m_constantBuffer) { UniformBuffer::destroy(m_constantBuffer); m_constantBuffer = NULL; } m_numPredefined = 0; if (NULL != m_buffer) { DX_RELEASE(m_buffer, 0); } DX_RELEASE(m_ptr, 0); if (NULL != m_code) { release(m_code); m_code = NULL; m_hash = 0; } } union { ID3D11ComputeShader* m_computeShader; ID3D11PixelShader* m_pixelShader; ID3D11VertexShader* m_vertexShader; ID3D11DeviceChild* m_ptr; }; const Memory* m_code; ID3D11Buffer* m_buffer; UniformBuffer* m_constantBuffer; PredefinedUniform m_predefined[PredefinedUniform::Count]; uint16_t m_attrMask[Attrib::Count]; uint32_t m_hash; uint16_t m_numUniforms; uint8_t m_numPredefined; bool m_hasDepthOp; }; struct ProgramD3D11 { ProgramD3D11() : m_vsh(NULL) , m_fsh(NULL) { } void create(const ShaderD3D11* _vsh, const ShaderD3D11* _fsh) { BX_ASSERT(NULL != _vsh->m_ptr, "Vertex shader doesn't exist."); m_vsh = _vsh; bx::memCopy(&m_predefined[0], _vsh->m_predefined, _vsh->m_numPredefined*sizeof(PredefinedUniform) ); m_numPredefined = _vsh->m_numPredefined; if (NULL != _fsh) { BX_ASSERT(NULL != _fsh->m_ptr, "Fragment shader doesn't exist."); m_fsh = _fsh; bx::memCopy(&m_predefined[m_numPredefined], _fsh->m_predefined, _fsh->m_numPredefined*sizeof(PredefinedUniform) ); m_numPredefined += _fsh->m_numPredefined; } } void destroy() { m_numPredefined = 0; m_vsh = NULL; m_fsh = NULL; } const ShaderD3D11* m_vsh; const ShaderD3D11* m_fsh; PredefinedUniform m_predefined[PredefinedUniform::Count*2]; uint8_t m_numPredefined; }; struct IntelDirectAccessResourceDescriptor { void* ptr; uint32_t xoffset; uint32_t yoffset; uint32_t tileFormat; uint32_t pitch; uint32_t size; }; struct DirectAccessResourceD3D11 { DirectAccessResourceD3D11() : m_ptr(NULL) , m_descriptor(NULL) { } void* createTexture2D(const D3D11_TEXTURE2D_DESC* _gpuDesc, const D3D11_SUBRESOURCE_DATA* _srd, ID3D11Texture2D** _gpuTexture2d); void* createTexture3D(const D3D11_TEXTURE3D_DESC* _gpuDesc, const D3D11_SUBRESOURCE_DATA* _srd, ID3D11Texture3D** _gpuTexture3d); void destroy(); union { ID3D11Resource* m_ptr; ID3D11Texture2D* m_texture2d; ID3D11Texture3D* m_texture3d; }; IntelDirectAccessResourceDescriptor* m_descriptor; }; struct TextureD3D11 { enum Enum { Texture2D, Texture3D, TextureCube, }; TextureD3D11() : m_ptr(NULL) , m_rt(NULL) , m_srv(NULL) , m_uav(NULL) , m_numMips(0) { } void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip); void destroy(); void overrideInternal(uintptr_t _ptr); void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem); void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]); void resolve(uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) const; TextureHandle getHandle() const; DXGI_FORMAT getSrvFormat() const; union { ID3D11Resource* m_ptr; ID3D11Texture2D* m_texture2d; ID3D11Texture3D* m_texture3d; }; DirectAccessResourceD3D11 m_dar; union { ID3D11Resource* m_rt; ID3D11Texture2D* m_rt2d; }; ID3D11ShaderResourceView* m_srv; ID3D11UnorderedAccessView* m_uav; uint64_t m_flags; uint32_t m_width; uint32_t m_height; uint32_t m_depth; uint32_t m_numLayers; uint8_t m_type; uint8_t m_requestedFormat; uint8_t m_textureFormat; uint8_t m_numMips; }; struct FrameBufferD3D11 { FrameBufferD3D11() : m_dsv(NULL) , m_swapChain(NULL) , m_nwh(NULL) , m_width(0) , m_height(0) , m_denseIdx(UINT16_MAX) , m_num(0) , m_numTh(0) , m_numUav(0) , m_needPresent(false) { } void create(uint8_t _num, const Attachment* _attachment); void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat); uint16_t destroy(); void preReset(bool _force = false); void postReset(); void resolve(); void clear(const Clear& _clear, const float _palette[][4]); void set(); HRESULT present(uint32_t _syncInterval); ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11DepthStencilView* m_dsv; Dxgi::SwapChainI* m_swapChain; void* m_nwh; uint32_t m_width; uint32_t m_height; Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; uint16_t m_denseIdx; uint8_t m_num; uint8_t m_numTh; uint8_t m_numUav; bool m_needPresent; }; struct TimerQueryD3D11 { TimerQueryD3D11() : m_control(BX_COUNTOF(m_query) ) { } void postReset(); void preReset(); uint32_t begin(uint32_t _resultIdx, uint32_t _frameNum); void end(uint32_t _idx); bool update(); struct Query { ID3D11Query* m_disjoint; ID3D11Query* m_begin; ID3D11Query* m_end; uint32_t m_resultIdx; uint32_t m_frameNum; bool m_ready; }; struct Result { void reset() { m_begin = 0; m_end = 0; m_frequency = 1; m_pending = 0; m_frameNum = 0; } uint64_t m_begin; uint64_t m_end; uint64_t m_frequency; uint32_t m_pending; uint32_t m_frameNum; }; Result m_result[BGFX_CONFIG_MAX_VIEWS+1]; Query m_query[BGFX_CONFIG_MAX_VIEWS*4]; bx::RingBufferControl m_control; }; struct OcclusionQueryD3D11 { OcclusionQueryD3D11() : m_control(BX_COUNTOF(m_query) ) { } void postReset(); void preReset(); void begin(Frame* _render, OcclusionQueryHandle _handle); void end(); void resolve(Frame* _render, bool _wait = false); void invalidate(OcclusionQueryHandle _handle); struct Query { ID3D11Query* m_ptr; OcclusionQueryHandle m_handle; }; Query m_query[BGFX_CONFIG_MAX_OCCLUSION_QUERIES]; bx::RingBufferControl m_control; }; } /* namespace d3d11 */ } // namespace bgfx #endif // BGFX_RENDERER_D3D11_H_HEADER_GUARD