| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- /*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
- */
- #ifndef BGFX_RENDERER_D3D12_H_HEADER_GUARD
- #define BGFX_RENDERER_D3D12_H_HEADER_GUARD
- #define USE_D3D12_DYNAMIC_LIB BX_PLATFORM_WINDOWS
- #include <sal.h>
- #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
- # include <d3d12.h>
- #else
- # if !BGFX_CONFIG_DEBUG
- # define D3DCOMPILE_NO_DEBUG 1
- # endif // !BGFX_CONFIG_DEBUG
- # include <d3d12_x.h>
- #endif // BX_PLATFORM_XBOXONE
- #if defined(__MINGW32__) // BK - temp workaround for MinGW until I nuke d3dx12 usage.
- extern "C++" {
- __extension__ template<typename Ty>
- const GUID& __mingw_uuidof();
- template<>
- const GUID& __mingw_uuidof<ID3D12Device>()
- {
- static const GUID IID_ID3D12Device0 = { 0x189819f1, 0x1db6, 0x4b57, { 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7 } };
- return IID_ID3D12Device0;
- }
- }
- #endif // defined(__MINGW32__)
- BX_PRAGMA_DIAGNOSTIC_PUSH();
- BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wmissing-field-initializers");
- #if BX_PLATFORM_XBOXONE
- # include <d3dx12_x.h>
- #else
- # include <d3dx12.h>
- #endif // BX_PLATFORM_XBOXONE
- BX_PRAGMA_DIAGNOSTIC_POP();
- #ifndef D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
- # define D3D12_TEXTURE_DATA_PITCH_ALIGNMENT 1024
- #endif // D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
- #include "renderer.h"
- #include "renderer_d3d.h"
- #include "shader_dxbc.h"
- #include "debug_renderdoc.h"
- #include "nvapi.h"
- #include "dxgi.h"
- #if BGFX_CONFIG_DEBUG_PIX
- # if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
- typedef struct PIXEventsThreadInfo* (WINAPI* PFN_PIX_GET_THREAD_INFO)();
- typedef uint64_t (WINAPI* PFN_PIX_EVENTS_REPLACE_BLOCK)(bool _getEarliestTime);
- extern PFN_PIX_GET_THREAD_INFO bgfx_PIXGetThreadInfo;
- extern PFN_PIX_EVENTS_REPLACE_BLOCK bgfx_PIXEventsReplaceBlock;
- # define PIXGetThreadInfo bgfx_PIXGetThreadInfo
- # define PIXEventsReplaceBlock bgfx_PIXEventsReplaceBlock
- # else
- extern "C" struct PIXEventsThreadInfo* WINAPI bgfx_PIXGetThreadInfo();
- extern "C" uint64_t WINAPI bgfx_PIXEventsReplaceBlock(bool _getEarliestTime);
- # endif // BX_PLATFORM_WINDOWS
- # include <pix3.h>
- # define _PIX3_BEGINEVENT(_commandList, _color, _name) PIXBeginEvent(_commandList, _color, _name)
- # define _PIX3_SETMARKER(_commandList, _color, _name) PIXSetMarker(_commandList, _color, _name)
- # define _PIX3_ENDEVENT(_commandList) PIXEndEvent(_commandList)
- # define PIX3_BEGINEVENT(_commandList, _color, _name) _PIX3_BEGINEVENT(_commandList, _color, _name)
- # define PIX3_SETMARKER(_commandList, _color, _name) _PIX3_SETMARKER(_commandList, _color, _name)
- # define PIX3_ENDEVENT(_commandList) _PIX3_ENDEVENT(_commandList)
- #else
- # define PIX3_BEGINEVENT(_commandList, _color, _name) BX_UNUSED(_commandList, _color, _name)
- # define PIX3_SETMARKER(_commandList, _color, _name) BX_UNUSED(_commandList, _color, _name)
- # define PIX3_ENDEVENT(_commandList) BX_UNUSED(_commandList)
- #endif // BGFX_CONFIG_DEBUG_PIX
- namespace bgfx { namespace d3d12
- {
- typedef HRESULT (WINAPI* PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(uint32_t _numFeatures, const IID* _iids, void* _configurationStructs, uint32_t* _configurationStructSizes);
- struct Rdt
- {
- enum Enum
- {
- Sampler,
- SRV,
- CBV,
- UAV,
- Count
- };
- };
- class ScratchBufferD3D12
- {
- public:
- ScratchBufferD3D12()
- {
- }
- ~ScratchBufferD3D12()
- {
- }
- void create(uint32_t _size, uint32_t _maxDescriptors);
- void destroy();
- void reset(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle);
- void allocEmpty(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle);
- void* allocCbv(D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress, uint32_t _size);
- void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0);
- void allocSrv(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer);
- void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct TextureD3D12& _texture, uint8_t _mip = 0);
- void allocUav(D3D12_GPU_DESCRIPTOR_HANDLE& _gpuHandle, struct BufferD3D12& _buffer);
- ID3D12DescriptorHeap* getHeap()
- {
- return m_heap;
- }
- private:
- ID3D12DescriptorHeap* m_heap;
- ID3D12Resource* m_upload;
- D3D12_GPU_VIRTUAL_ADDRESS m_gpuVA;
- D3D12_CPU_DESCRIPTOR_HANDLE m_cpuHandle;
- D3D12_GPU_DESCRIPTOR_HANDLE m_gpuHandle;
- uint32_t m_incrementSize;
- uint8_t* m_data;
- uint32_t m_size;
- uint32_t m_pos;
- };
- class DescriptorAllocatorD3D12
- {
- public:
- DescriptorAllocatorD3D12()
- : m_numDescriptorsPerBlock(1)
- {
- }
- ~DescriptorAllocatorD3D12()
- {
- }
- void create(D3D12_DESCRIPTOR_HEAP_TYPE _type, uint16_t _maxDescriptors, uint16_t _numDescriptorsPerBlock = 1);
- void destroy();
- uint16_t alloc(ID3D12Resource* _ptr, const D3D12_SHADER_RESOURCE_VIEW_DESC* _desc);
- uint16_t alloc(const uint32_t* _flags, uint32_t _num, const float _palette[][4]);
- void free(uint16_t _handle);
- void reset();
- D3D12_GPU_DESCRIPTOR_HANDLE get(uint16_t _handle);
- ID3D12DescriptorHeap* getHeap()
- {
- return m_heap;
- }
- private:
- ID3D12DescriptorHeap* m_heap;
- bx::HandleAlloc* m_handleAlloc;
- D3D12_CPU_DESCRIPTOR_HANDLE m_cpuHandle;
- D3D12_GPU_DESCRIPTOR_HANDLE m_gpuHandle;
- uint32_t m_incrementSize;
- uint16_t m_numDescriptorsPerBlock;
- };
- struct BufferD3D12
- {
- BufferD3D12()
- : m_ptr(NULL)
- , m_state(D3D12_RESOURCE_STATE_COMMON)
- , m_size(0)
- , m_flags(BGFX_BUFFER_NONE)
- , m_dynamic(false)
- {
- }
- void create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride = 0);
- void update(ID3D12GraphicsCommandList* _commandList, uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
- void destroy();
- D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
- D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
- D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
- ID3D12Resource* m_ptr;
- D3D12_GPU_VIRTUAL_ADDRESS m_gpuVA;
- D3D12_RESOURCE_STATES m_state;
- uint32_t m_size;
- uint16_t m_flags;
- bool m_dynamic;
- };
- struct VertexBufferD3D12 : public BufferD3D12
- {
- void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags);
- VertexDeclHandle m_decl;
- };
- struct ShaderD3D12
- {
- ShaderD3D12()
- : m_code(NULL)
- , m_constantBuffer(NULL)
- , m_hash(0)
- , m_numUniforms(0)
- , m_numPredefined(0)
- {
- }
- void create(const Memory* _mem);
- void destroy()
- {
- if (NULL != m_constantBuffer)
- {
- UniformBuffer::destroy(m_constantBuffer);
- m_constantBuffer = NULL;
- }
- m_numPredefined = 0;
- if (NULL != m_code)
- {
- release(m_code);
- m_code = NULL;
- m_hash = 0;
- }
- }
- const Memory* m_code;
- UniformBuffer* m_constantBuffer;
- PredefinedUniform m_predefined[PredefinedUniform::Count];
- uint16_t m_attrMask[Attrib::Count];
- uint32_t m_hash;
- uint16_t m_numUniforms;
- uint16_t m_size;
- uint8_t m_numPredefined;
- };
- struct ProgramD3D12
- {
- ProgramD3D12()
- : m_vsh(NULL)
- , m_fsh(NULL)
- {
- }
- void create(const ShaderD3D12* _vsh, const ShaderD3D12* _fsh)
- {
- BX_CHECK(NULL != _vsh->m_code, "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_CHECK(NULL != _fsh->m_code, "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 ShaderD3D12* m_vsh;
- const ShaderD3D12* m_fsh;
- PredefinedUniform m_predefined[PredefinedUniform::Count * 2];
- uint8_t m_numPredefined;
- };
- struct TextureD3D12
- {
- enum Enum
- {
- Texture2D,
- Texture3D,
- TextureCube,
- };
- TextureD3D12()
- : m_ptr(NULL)
- , m_directAccessPtr(NULL)
- , m_state(D3D12_RESOURCE_STATE_COMMON)
- , m_numMips(0)
- {
- bx::memSet(&m_srvd, 0, sizeof(m_srvd) );
- bx::memSet(&m_uavd, 0, sizeof(m_uavd) );
- }
- void* create(const Memory* _mem, uint64_t _flags, uint8_t _skip);
- void destroy();
- void update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
- void resolve(uint8_t _resolve) const;
- D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
- D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
- D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
- ID3D12Resource* m_ptr;
- void* m_directAccessPtr;
- D3D12_RESOURCE_STATES m_state;
- uint64_t m_flags;
- uint32_t m_width;
- uint32_t m_height;
- uint32_t m_depth;
- uint16_t m_samplerIdx;
- uint8_t m_type;
- uint8_t m_requestedFormat;
- uint8_t m_textureFormat;
- uint8_t m_numMips;
- };
- struct FrameBufferD3D12
- {
- FrameBufferD3D12()
- : m_swapChain(NULL)
- , m_nwh(NULL)
- , m_width(0)
- , m_height(0)
- , m_denseIdx(UINT16_MAX)
- , m_num(0)
- , m_numTh(0)
- , m_state(D3D12_RESOURCE_STATE_PRESENT)
- , m_needPresent(false)
- {
- m_depth.idx = bgfx::kInvalidHandle;
- }
- 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();
- HRESULT present(uint32_t _syncInterval, uint32_t _flags);
- void preReset();
- void postReset();
- void resolve();
- void clear(ID3D12GraphicsCommandList* _commandList, const Clear& _clear, const float _palette[][4], const D3D12_RECT* _rect = NULL, uint32_t _num = 0);
- D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, uint8_t _idx, D3D12_RESOURCE_STATES _state);
- TextureHandle m_texture[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
- TextureHandle m_depth;
- Dxgi::SwapChainI* m_swapChain;
- void* m_nwh;
- uint32_t m_width;
- uint32_t m_height;
- uint16_t m_denseIdx;
- uint8_t m_num;
- uint8_t m_numTh;
- Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
- D3D12_RESOURCE_STATES m_state;
- bool m_needPresent;
- };
- struct CommandQueueD3D12
- {
- CommandQueueD3D12()
- : m_currentFence(0)
- , m_completedFence(0)
- , m_control(BX_COUNTOF(m_commandList) )
- {
- BX_STATIC_ASSERT(BX_COUNTOF(m_commandList) == BX_COUNTOF(m_release) );
- }
- void init(ID3D12Device* _device);
- void shutdown();
- ID3D12GraphicsCommandList* alloc();
- uint64_t kick();
- void finish(uint64_t _waitFence = UINT64_MAX, bool _finishAll = false);
- bool tryFinish(uint64_t _waitFence);
- void release(ID3D12Resource* _ptr);
- bool consume(uint32_t _ms = INFINITE);
- struct CommandList
- {
- ID3D12GraphicsCommandList* m_commandList;
- ID3D12CommandAllocator* m_commandAllocator;
- HANDLE m_event;
- };
- ID3D12CommandQueue* m_commandQueue;
- uint64_t m_currentFence;
- uint64_t m_completedFence;
- ID3D12Fence* m_fence;
- CommandList m_commandList[256];
- typedef stl::vector<ID3D12Resource*> ResourceArray;
- ResourceArray m_release[256];
- bx::RingBufferControl m_control;
- };
- struct BatchD3D12
- {
- enum Enum
- {
- Draw,
- DrawIndexed,
- Count
- };
- BatchD3D12()
- : m_currIndirect(0)
- , m_maxDrawPerBatch(0)
- , m_minIndirect(0)
- , m_flushPerBatch(0)
- {
- bx::memSet(m_num, 0, sizeof(m_num) );
- }
- ~BatchD3D12()
- {
- }
- void create(uint32_t _maxDrawPerBatch);
- void destroy();
- template<typename Ty>
- Ty& getCmd(Enum _type);
- uint32_t draw(ID3D12GraphicsCommandList* _commandList, D3D12_GPU_VIRTUAL_ADDRESS _cbv, const RenderDraw& _draw);
- void flush(ID3D12GraphicsCommandList* _commandList, Enum _type);
- void flush(ID3D12GraphicsCommandList* _commandList, bool _clean = false);
- void begin();
- void end(ID3D12GraphicsCommandList* _commandList);
- void setSeqMode(bool _enabled)
- {
- m_flushPerBatch = _enabled ? 1 : m_maxDrawPerBatch;
- }
- void setIndirectMode(bool _enabled)
- {
- m_minIndirect = _enabled ? 64 : UINT32_MAX;
- }
- ID3D12CommandSignature* m_commandSignature[Count];
- uint32_t m_num[Count];
- void* m_cmds[Count];
- struct DrawIndirectCommand
- {
- D3D12_VERTEX_BUFFER_VIEW vbv[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1 /* instanced buffer */];
- D3D12_GPU_VIRTUAL_ADDRESS cbv;
- D3D12_DRAW_ARGUMENTS args;
- };
- struct DrawIndexedIndirectCommand
- {
- D3D12_VERTEX_BUFFER_VIEW vbv[BGFX_CONFIG_MAX_VERTEX_STREAMS + 1 /* instanced buffer */];
- D3D12_INDEX_BUFFER_VIEW ibv;
- D3D12_GPU_VIRTUAL_ADDRESS cbv;
- D3D12_DRAW_INDEXED_ARGUMENTS args;
- };
- struct Stats
- {
- uint32_t m_numImmediate[Count];
- uint32_t m_numIndirect[Count];
- };
- BufferD3D12 m_indirect[32];
- uint32_t m_currIndirect;
- DrawIndexedIndirectCommand m_current;
- Stats m_stats;
- uint32_t m_maxDrawPerBatch;
- uint32_t m_minIndirect;
- uint32_t m_flushPerBatch;
- };
- struct TimerQueryD3D12
- {
- TimerQueryD3D12()
- : m_control(BX_COUNTOF(m_query) )
- {
- }
- void init();
- void shutdown();
- uint32_t begin(uint32_t _resultIdx);
- void end(uint32_t _idx);
- bool update();
- struct Query
- {
- uint32_t m_resultIdx;
- bool m_ready;
- uint64_t m_fence;
- };
- struct Result
- {
- void reset()
- {
- m_begin = 0;
- m_end = 0;
- m_pending = 0;
- }
- uint64_t m_begin;
- uint64_t m_end;
- uint32_t m_pending;
- };
- uint64_t m_frequency;
- Result m_result[BGFX_CONFIG_MAX_VIEWS+1];
- Query m_query[BGFX_CONFIG_MAX_VIEWS*4];
- ID3D12Resource* m_readback;
- ID3D12QueryHeap* m_queryHeap;
- uint64_t* m_queryResult;
- bx::RingBufferControl m_control;
- };
- struct OcclusionQueryD3D12
- {
- OcclusionQueryD3D12()
- : m_control(BX_COUNTOF(m_handle) )
- {
- }
- void init();
- void shutdown();
- void begin(ID3D12GraphicsCommandList* _commandList, Frame* _render, OcclusionQueryHandle _handle);
- void end(ID3D12GraphicsCommandList* _commandList);
- void invalidate(OcclusionQueryHandle _handle);
- ID3D12Resource* m_readback;
- ID3D12QueryHeap* m_queryHeap;
- OcclusionQueryHandle m_handle[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
- uint64_t* m_result;
- bx::RingBufferControl m_control;
- };
- } /* namespace d3d12 */ } // namespace bgfx
- #endif // BGFX_RENDERER_D3D12_H_HEADER_GUARD
|