From 0837e7451a84f95c29dbdb9bd6b8b931fee1635d Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Sun, 13 Oct 2019 13:50:38 +0200 Subject: WIP: sync bgfx, bx and bimg with latest upstream (#5723) * Sync with bgfx upstream revision b91d0b6 * Sync with bx upstream revision d60912b * Sync with bimg upstream revision bd81f60 * Add astc-codec decoder * Rename VertexDecl to VertexLayout * Rename UniformType enum Int1 to Sampler. * Add NVN stub * Fix unused-const-variable error on macOS * Drop redundant explicit language parameters buildoptions_cpp are only applied to c++ files and buildoptions_objcpp are only applied to objective c++ files. As such, hardcoding -x offers no benefit while preventing overrides (such as one needed by 3rdparty/bgfx/src/renderer_vk.cpp on macOS) from working. * Re-introduce -x c++ in places where C code is compiled as C++ to prevent clang from throwing a warning * Build bgfx as Objective-C++ on macOS It is needed due to included headers * Enable Direct3D12 and Vulkan bgfx rendering backends * Enable building of spirv shaders * Properly escape /c in cmd call * Comment out dx12 bgfx renderer * Honor VERBOSE setting during shaders build * Only invert hlsl shader XYZ_TO_sRGB matrix for opengl * Add spirv shaders * OpenGL ES needs transposed matrix too * Metal needs transposed matrix as well --- 3rdparty/bgfx/src/renderer_d3d12.cpp | 802 ++++++++++++++++++++--------------- 1 file changed, 455 insertions(+), 347 deletions(-) (limited to '3rdparty/bgfx/src/renderer_d3d12.cpp') diff --git a/3rdparty/bgfx/src/renderer_d3d12.cpp b/3rdparty/bgfx/src/renderer_d3d12.cpp index d577e63b609..64b43d0b9df 100644 --- a/3rdparty/bgfx/src/renderer_d3d12.cpp +++ b/3rdparty/bgfx/src/renderer_d3d12.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ @@ -15,15 +15,23 @@ # endif // BX_PLATFORM_WINRT #endif // !BX_PLATFORM_WINDOWS -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) +#if BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) PFN_PIX_GET_THREAD_INFO bgfx_PIXGetThreadInfo; PFN_PIX_EVENTS_REPLACE_BLOCK bgfx_PIXEventsReplaceBlock; -#endif // BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS +#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) namespace bgfx { namespace d3d12 { static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; + inline void setViewType(ViewId _view, const bx::StringView _str) + { + if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION || BGFX_CONFIG_PROFILER) ) + { + bx::memCopy(&s_viewName[_view][3], _str.getPtr(), _str.getLength() ); + } + } + struct PrimInfo { D3D_PRIMITIVE_TOPOLOGY m_topology; @@ -324,19 +332,19 @@ namespace bgfx { namespace d3d12 }; BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); - static D3D12_INPUT_ELEMENT_DESC* fillVertexDecl(uint8_t _stream, D3D12_INPUT_ELEMENT_DESC* _out, const VertexDecl& _decl) + static D3D12_INPUT_ELEMENT_DESC* fillVertexLayout(uint8_t _stream, D3D12_INPUT_ELEMENT_DESC* _out, const VertexLayout& _layout) { D3D12_INPUT_ELEMENT_DESC* elem = _out; for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { - if (UINT16_MAX != _decl.m_attributes[attr]) + if (UINT16_MAX != _layout.m_attributes[attr]) { bx::memCopy(elem, &s_attrib[attr], sizeof(D3D12_INPUT_ELEMENT_DESC) ); elem->InputSlot = _stream; - if (0 == _decl.m_attributes[attr]) + if (0 == _layout.m_attributes[attr]) { elem->AlignedByteOffset = 0; } @@ -346,9 +354,9 @@ namespace bgfx { namespace d3d12 AttribType::Enum type; bool normalized; bool asInt; - _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); + _layout.decode(Attrib::Enum(attr), num, type, normalized, asInt); elem->Format = s_attribType[type][num-1][normalized]; - elem->AlignedByteOffset = _decl.m_offset[attr]; + elem->AlignedByteOffset = _layout.m_offset[attr]; } ++elem; @@ -623,7 +631,7 @@ namespace bgfx { namespace d3d12 #endif // BX_COMPILER_MSVC } -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) +#if BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) static PIXEventsThreadInfo s_pixEventsThreadInfo; PIXEventsThreadInfo* WINAPI stubPIXGetThreadInfo() @@ -636,7 +644,7 @@ namespace bgfx { namespace d3d12 BX_UNUSED(_getEarliestTime); return 0; } -#endif // BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS +#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) struct RendererContextD3D12 : public RendererContextI { @@ -680,7 +688,7 @@ namespace bgfx { namespace d3d12 ErrorState::Enum errorState = ErrorState::Default; // LUID luid; -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) +#if BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) m_winPixEvent = bx::dlopen("WinPixEventRuntime.dll"); if (NULL != m_winPixEvent) @@ -695,7 +703,7 @@ namespace bgfx { namespace d3d12 bgfx_PIXGetThreadInfo = stubPIXGetThreadInfo; bgfx_PIXEventsReplaceBlock = stubPIXEventsReplaceBlock; } -#endif // BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS +#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) if (_init.debug || _init.profile) @@ -767,54 +775,40 @@ namespace bgfx { namespace d3d12 HRESULT hr; - if (_init.debug - || _init.profile) { - ID3D12Debug* debug0; - hr = D3D12GetDebugInterface(IID_ID3D12Debug, (void**)&debug0); - - if (SUCCEEDED(hr) ) +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT + if (_init.debug + || _init.profile) { - uint32_t debugFlags = 0; + ID3D12Debug* debug0; + hr = D3D12GetDebugInterface(IID_ID3D12Debug, (void**)&debug0); - if (_init.debug) + if (SUCCEEDED(hr) ) { -#if BX_PLATFORM_WINDOWS - debug0->EnableDebugLayer(); - + if (_init.debug) { - ID3D12Debug1* debug1; - hr = debug0->QueryInterface(IID_ID3D12Debug1, (void**)&debug1); +#if BX_PLATFORM_WINDOWS + debug0->EnableDebugLayer(); - if (SUCCEEDED(hr) ) { -// debug1->SetEnableGPUBasedValidation(true); -// debug1->SetEnableSynchronizedCommandQueueValidation(true); - } + ID3D12Debug1* debug1; + hr = debug0->QueryInterface(IID_ID3D12Debug1, (void**)&debug1); - DX_RELEASE(debug1, 1); - } -#elif BX_PLATFORM_XBOXONE - debugFlags |= D3D12_PROCESS_DEBUG_FLAG_DEBUG_LAYER_ENABLED; -#endif // BX_PLATFORM_WINDOWS - } + if (SUCCEEDED(hr)) + { +// debug1->SetEnableGPUBasedValidation(true); +// debug1->SetEnableSynchronizedCommandQueueValidation(true); + } -#if BX_PLATFORM_XBOXONE - // https://github.com/Microsoft/Xbox-ATG-Samples/blob/76d236e3bd372aceec18b2ad0556a7879dbd9628/XDKSamples/IntroGraphics/SimpleTriangle12/DeviceResources.cpp#L67 - debugFlags |= _init.profile ? D3D12XBOX_PROCESS_DEBUG_FLAG_INSTRUMENTED : 0; + DX_RELEASE(debug1, 1); + } +#endif // BX_PLATFORM_WINDOWS + } - if (0 != debugFlags) - { - debug0->SetProcessDebugFlags(D3D12XBOX_PROCESS_DEBUG_FLAGS(debugFlags) ); + DX_RELEASE(debug0, 0); } -#endif // BX_PLATFORM_XBOXONE - BX_UNUSED(debugFlags); - - DX_RELEASE(debug0, 0); } - } - { D3D_FEATURE_LEVEL featureLevel[] = { D3D_FEATURE_LEVEL_12_1, @@ -837,6 +831,35 @@ namespace bgfx { namespace d3d12 ); m_featureLevel = featureLevel[ii]; } +#else + // Reference(s): + // - https://github.com/Microsoft/Xbox-ATG-Samples/blob/1271bfd61b4883c775f395b6f13aeabea70290ca/XDKSamples/Graphics/AdvancedESRAM12/DeviceResources.cpp#L64 + D3D12XBOX_CREATE_DEVICE_PARAMETERS params = {}; + params.Version = D3D12_SDK_VERSION; + params.ProcessDebugFlags = D3D12XBOX_PROCESS_DEBUG_FLAGS(0 + | (_init.debug ? D3D12XBOX_PROCESS_DEBUG_FLAG_DEBUG : 0) + | (_init.profile ? D3D12XBOX_PROCESS_DEBUG_FLAG_INSTRUMENTED : 0) + ); + params.GraphicsCommandQueueRingSizeBytes = UINT32_MAX; + params.GraphicsScratchMemorySizeBytes = UINT32_MAX; + params.ComputeScratchMemorySizeBytes = UINT32_MAX; + params.DisableGeometryShaderAllocations = true; + params.DisableTessellationShaderAllocations = true; + + hr = D3D12XboxCreateDevice( + m_dxgi.m_adapter + , ¶ms + , IID_ID3D12Device + , (void**)&m_device + ); + m_featureLevel = D3D_FEATURE_LEVEL_12_1; + + if (SUCCEEDED(hr) ) + { + m_device->SetDebugErrorFilterX(0x73EC9EAF, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_BREAKS); + m_device->SetDebugErrorFilterX(0x8EC9B15C, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_OUTPUT); + } +#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT } if (FAILED(hr) ) @@ -866,11 +889,6 @@ namespace bgfx { namespace d3d12 } } -#if BX_PLATFORM_XBOXONE - m_device->SetDebugErrorFilterX(0x73EC9EAF, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_BREAKS); - m_device->SetDebugErrorFilterX(0x8EC9B15C, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_OUTPUT); -#endif // BX_PLATFORM_XBOXONE - if (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId) { m_nvapi.shutdown(); @@ -916,7 +934,10 @@ namespace bgfx { namespace d3d12 bx::memSet(&m_scd, 0, sizeof(m_scd) ); m_scd.width = _init.resolution.width; m_scd.height = _init.resolution.height; - m_scd.format = s_textureFormat[_init.resolution.format].m_fmt; + m_scd.format = (_init.resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) + ? s_textureFormat[_init.resolution.format].m_fmtSrgb + : s_textureFormat[_init.resolution.format].m_fmt + ; m_scd.stereo = false; updateMsaa(m_scd.format); @@ -1509,20 +1530,20 @@ namespace bgfx { namespace d3d12 m_indexBuffers[_handle.idx].destroy(); } - void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) override + void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override { - VertexDecl& decl = m_vertexDecls[_handle.idx]; - bx::memCopy(&decl, &_decl, sizeof(VertexDecl) ); - dump(decl); + VertexLayout& layout = m_vertexLayouts[_handle.idx]; + bx::memCopy(&layout, &_layout, sizeof(VertexLayout) ); + dump(layout); } - void destroyVertexDecl(VertexDeclHandle /*_handle*/) override + void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override { } - void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) override + void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags); + m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override @@ -1547,8 +1568,8 @@ namespace bgfx { namespace d3d12 void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - VertexDeclHandle decl = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags); + VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; + m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1859,29 +1880,39 @@ namespace bgfx { namespace d3d12 bx::memCopy(m_uniforms[_loc], _data, _size); } - void setMarker(const char* _marker, uint32_t /*_size*/) override + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override { - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - PIX3_SETMARKER(m_commandList, D3DCOLOR_MARKER, _marker); - } + m_occlusionQuery.invalidate(_handle); } - void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override + void setMarker(const char* _marker, uint16_t _len) override { - m_occlusionQuery.invalidate(_handle); + BX_UNUSED(_len); + + if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) + { + PIX3_SETMARKER(m_commandList, kColorMarker, _marker); + } } - virtual void setName(Handle _handle, const char* _name) override + virtual void setName(Handle _handle, const char* _name, uint16_t _len) override { switch (_handle.type) { + case Handle::IndexBuffer: + setDebugObjectName(m_indexBuffers[_handle.idx].m_ptr, "%.*s", _len, _name); + break; + case Handle::Shader: -// setDebugObjectName(m_shaders[_handle.idx].m_ptr, "%s", _name); +// setDebugObjectName(m_shaders[_handle.idx].m_ptr, "%.*s", _len, _name); break; case Handle::Texture: - setDebugObjectName(m_textures[_handle.idx].m_ptr, "%s", _name); + setDebugObjectName(m_textures[_handle.idx].m_ptr, "%.*s", _len, _name); + break; + + case Handle::VertexBuffer: + setDebugObjectName(m_vertexBuffers[_handle.idx].m_ptr, "%.*s", _len, _name); break; default: @@ -1923,12 +1954,12 @@ namespace bgfx { namespace d3d12 | BGFX_STATE_DEPTH_TEST_ALWAYS ; - const VertexDecl* decls[1] = { &m_vertexDecls[_blitter.m_vb->decl.idx] }; + const VertexLayout* layouts[1] = { &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx] }; ID3D12PipelineState* pso = getPipelineState(state , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) , 1 - , decls - , _blitter.m_program.idx + , layouts + , _blitter.m_program , 0 ); m_commandList->SetPipelineState(pso); @@ -1942,7 +1973,7 @@ namespace bgfx { namespace d3d12 setShaderUniform(flags, predefined.m_loc, proj, 4); D3D12_GPU_VIRTUAL_ADDRESS gpuAddress; - commitShaderConstants(_blitter.m_program.idx, gpuAddress); + commitShaderConstants(_blitter.m_program, gpuAddress); ScratchBufferD3D12& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; ID3D12DescriptorHeap* heaps[] = @@ -1961,11 +1992,11 @@ namespace bgfx { namespace d3d12 scratchBuffer.allocSrv(srvHandle, texture); m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle); - VertexBufferD3D12& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; - const VertexDecl& vertexDecl = m_vertexDecls[_blitter.m_vb->decl.idx]; + VertexBufferD3D12& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; + const VertexLayout& layout = m_vertexLayouts[_blitter.m_vb->layoutHandle.idx]; D3D12_VERTEX_BUFFER_VIEW viewDesc; viewDesc.BufferLocation = vb.m_gpuVA; - viewDesc.StrideInBytes = vertexDecl.m_stride; + viewDesc.StrideInBytes = layout.m_stride; viewDesc.SizeInBytes = vb.m_size; m_commandList->IASetVertexBuffers(0, 1, &viewDesc); @@ -1985,7 +2016,7 @@ namespace bgfx { namespace d3d12 if (0 < numVertices) { m_indexBuffers [_blitter.m_ib->handle.idx].update(m_commandList, 0, _numIndices*2, _blitter.m_ib->data); - m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandList, 0, numVertices*_blitter.m_decl.m_stride, _blitter.m_vb->data, true); + m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandList, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true); m_commandList->DrawIndexedInstanced(_numIndices , 1 @@ -2216,7 +2247,7 @@ namespace bgfx { namespace d3d12 BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(presentQueue) ); DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd, nodeMask, presentQueue) ); #elif BX_PLATFORM_WINRT - DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd); + DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd)); m_backBufferColorIdx = m_scd.bufferCount-1; #endif // BX_PLATFORM_WINDOWS } @@ -2292,9 +2323,9 @@ namespace bgfx { namespace d3d12 setShaderUniform(_flags, _regIndex, _val, _numRegs); } - void commitShaderConstants(uint16_t _programIdx, D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress) + void commitShaderConstants(ProgramHandle _program, D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress) { - const ProgramD3D12& program = m_program[_programIdx]; + const ProgramD3D12& program = m_program[_program.idx]; uint32_t total = bx::strideAlign(0 + program.m_vsh->m_size + (NULL != program.m_fsh ? program.m_fsh->m_size : 0) @@ -2573,7 +2604,7 @@ namespace bgfx { namespace d3d12 _desc.BackFace.StencilFunc = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT]; } - uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, uint8_t _numStreams, const VertexDecl** _vertexDecls, const ProgramD3D12& _program, uint16_t _numInstanceData) + uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, uint8_t _numStreams, const VertexLayout** _layouts, const ProgramD3D12& _program, uint16_t _numInstanceData) { uint16_t attrMask[Attrib::Count]; bx::memCopy(attrMask, _program.m_vsh->m_attrMask, sizeof(attrMask)); @@ -2582,19 +2613,19 @@ namespace bgfx { namespace d3d12 for (uint8_t stream = 0; stream < _numStreams; ++stream) { - VertexDecl decl; - bx::memCopy(&decl, _vertexDecls[stream], sizeof(VertexDecl)); + VertexLayout layout; + bx::memCopy(&layout, _layouts[stream], sizeof(VertexLayout)); const bool last = stream == _numStreams-1; for (uint32_t ii = 0; ii < Attrib::Count; ++ii) { uint16_t mask = attrMask[ii]; - uint16_t attr = (decl.m_attributes[ii] & mask); + uint16_t attr = (layout.m_attributes[ii] & mask); if (0 == attr || UINT16_MAX == attr) { - decl.m_attributes[ii] = last ? ~attr : UINT16_MAX; + layout.m_attributes[ii] = last ? ~attr : UINT16_MAX; } else { @@ -2602,7 +2633,7 @@ namespace bgfx { namespace d3d12 } } - elem = fillVertexDecl(stream, elem, decl); + elem = fillVertexLayout(stream, elem, layout); } uint32_t num = uint32_t(elem-_vertexElements); @@ -2640,10 +2671,10 @@ namespace bgfx { namespace d3d12 return uint32_t(elem-_vertexElements); } - uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, const VertexDecl& _vertexDecl, const ProgramD3D12& _program, uint16_t _numInstanceData) + uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, const VertexLayout& _layout, const ProgramD3D12& _program, uint16_t _numInstanceData) { - const VertexDecl* decls[1] = { &_vertexDecl }; - return setInputLayout(_vertexElements, BX_COUNTOF(decls), decls, _program, _numInstanceData); + const VertexLayout* layouts[1] = { &_layout }; + return setInputLayout(_vertexElements, BX_COUNTOF(layouts), layouts, _program, _numInstanceData); } static void patchCb0(DxbcInstruction& _instruction, void* _userData) @@ -2677,9 +2708,9 @@ namespace bgfx { namespace d3d12 } } - ID3D12PipelineState* getPipelineState(uint16_t _programIdx) + ID3D12PipelineState* getPipelineState(ProgramHandle _program) { - ProgramD3D12& program = m_program[_programIdx]; + ProgramD3D12& program = m_program[_program.idx]; const uint32_t hash = program.m_vsh->m_hash; @@ -2693,17 +2724,67 @@ namespace bgfx { namespace d3d12 D3D12_COMPUTE_PIPELINE_STATE_DESC desc; bx::memSet(&desc, 0, sizeof(desc) ); - desc.pRootSignature = m_rootSignature; - + desc.pRootSignature = m_rootSignature; desc.CS.pShaderBytecode = program.m_vsh->m_code->data; desc.CS.BytecodeLength = program.m_vsh->m_code->size; + desc.NodeMask = 1; + desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + uint32_t length = g_callback->cacheReadSize(hash); + const bool cached = length > 0; + + void* cachedData = NULL; + + if (cached) + { + cachedData = BX_ALLOC(g_allocator, length); + if (g_callback->cacheRead(hash, cachedData, length) ) + { + BX_TRACE("Loading cached compute PSO (size %d).", length); + bx::MemoryReader reader(cachedData, length); + + desc.CachedPSO.pCachedBlob = reader.getDataPtr(); + desc.CachedPSO.CachedBlobSizeInBytes = (size_t)reader.remaining(); + + HRESULT hr = m_device->CreateComputePipelineState(&desc + , IID_ID3D12PipelineState + , (void**)&pso + ); + if (FAILED(hr) ) + { + BX_TRACE("Failed to load cached compute PSO (HRESULT 0x%08x).", hr); + bx::memSet(&desc.CachedPSO, 0, sizeof(desc.CachedPSO) ); + } + } + } + + if (NULL == pso) + { + DX_CHECK(m_device->CreateComputePipelineState(&desc + , IID_ID3D12PipelineState + , (void**)&pso + ) ); + } - DX_CHECK(m_device->CreateComputePipelineState(&desc - , IID_ID3D12PipelineState - , (void**)&pso - ) ); m_pipelineStateCache.add(hash, pso); + ID3DBlob* blob; + HRESULT hr = pso->GetCachedBlob(&blob); + if (SUCCEEDED(hr) ) + { + void* data = blob->GetBufferPointer(); + length = (uint32_t)blob->GetBufferSize(); + + g_callback->cacheWrite(hash, data, length); + + DX_RELEASE(blob, 0); + } + + if (NULL != cachedData) + { + BX_FREE(g_allocator, cachedData); + } + return pso; } @@ -2711,12 +2792,12 @@ namespace bgfx { namespace d3d12 uint64_t _state , uint64_t _stencil , uint8_t _numStreams - , const VertexDecl** _vertexDecls - , uint16_t _programIdx + , const VertexLayout** _layouts + , ProgramHandle _program , uint8_t _numInstanceData ) { - ProgramD3D12& program = m_program[_programIdx]; + ProgramD3D12& program = m_program[_program.idx]; _state &= 0 | BGFX_STATE_WRITE_RGB @@ -2736,17 +2817,17 @@ namespace bgfx { namespace d3d12 _stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK); - VertexDecl decl; + VertexLayout layout; if (0 < _numStreams) { - bx::memCopy(&decl, _vertexDecls[0], sizeof(VertexDecl) ); + bx::memCopy(&layout, _layouts[0], sizeof(VertexLayout) ); const uint16_t* attrMask = program.m_vsh->m_attrMask; for (uint32_t ii = 0; ii < Attrib::Count; ++ii) { uint16_t mask = attrMask[ii]; - uint16_t attr = (decl.m_attributes[ii] & mask); - decl.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; + uint16_t attr = (layout.m_attributes[ii] & mask); + layout.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; } } @@ -2764,10 +2845,10 @@ namespace bgfx { namespace d3d12 for (uint32_t ii = 0; ii < _numStreams; ++ii) { - murmur.add(_vertexDecls[ii]->m_hash); + murmur.add(_layouts[ii]->m_hash); } - murmur.add(decl.m_attributes, sizeof(decl.m_attributes) ); + murmur.add(layout.m_attributes, sizeof(layout.m_attributes) ); murmur.add(m_fbh.idx); murmur.add(_numInstanceData); const uint32_t hash = murmur.end(); @@ -2883,7 +2964,7 @@ namespace bgfx { namespace d3d12 setDepthStencilState(desc.DepthStencilState, _state, _stencil); D3D12_INPUT_ELEMENT_DESC vertexElements[Attrib::Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; - desc.InputLayout.NumElements = setInputLayout(vertexElements, _numStreams, _vertexDecls, program, _numInstanceData); + desc.InputLayout.NumElements = setInputLayout(vertexElements, _numStreams, _layouts, program, _numInstanceData); desc.InputLayout.pInputElementDescs = 0 == desc.InputLayout.NumElements ? NULL : vertexElements @@ -2930,7 +3011,7 @@ namespace bgfx { namespace d3d12 desc.SampleDesc = m_scd.sampleDesc; uint32_t length = g_callback->cacheReadSize(hash); - bool cached = length > 0; + const bool cached = length > 0; void* cachedData = NULL; @@ -2939,7 +3020,7 @@ namespace bgfx { namespace d3d12 cachedData = BX_ALLOC(g_allocator, length); if (g_callback->cacheRead(hash, cachedData, length) ) { - BX_TRACE("Loading cached PSO (size %d).", length); + BX_TRACE("Loading cached graphics PSO (size %d).", length); bx::MemoryReader reader(cachedData, length); desc.CachedPSO.pCachedBlob = reader.getDataPtr(); @@ -2951,7 +3032,7 @@ namespace bgfx { namespace d3d12 ); if (FAILED(hr) ) { - BX_TRACE("Failed to load cached PSO (HRESULT 0x%08x).", hr); + BX_TRACE("Failed to load cached graphics PSO (HRESULT 0x%08x).", hr); bx::memSet(&desc.CachedPSO, 0, sizeof(desc.CachedPSO) ); } } @@ -3081,9 +3162,9 @@ namespace bgfx { namespace d3d12 } break; - CASE_IMPLEMENT_UNIFORM(Int1, I, int); - CASE_IMPLEMENT_UNIFORM(Vec4, F, float); - CASE_IMPLEMENT_UNIFORM(Mat4, F, float); + CASE_IMPLEMENT_UNIFORM(Sampler, I, int); + CASE_IMPLEMENT_UNIFORM(Vec4, F, float); + CASE_IMPLEMENT_UNIFORM(Mat4, F, float); case UniformType::End: break; @@ -3275,7 +3356,7 @@ namespace bgfx { namespace d3d12 ShaderD3D12 m_shaders[BGFX_CONFIG_MAX_SHADERS]; ProgramD3D12 m_program[BGFX_CONFIG_MAX_PROGRAMS]; TextureD3D12 m_textures[BGFX_CONFIG_MAX_TEXTURES]; - VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS]; + VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; FrameBufferD3D12 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; @@ -3874,13 +3955,14 @@ namespace bgfx { namespace d3d12 if (UINT8_MAX != _draw.m_streamMask) { - for (uint32_t idx = 0, streamMask = _draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + for (uint32_t idx = 0, streamMask = _draw.m_streamMask ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ; streamMask >>= 1, idx += 1, ++numStreams ) { + const uint32_t ntz = bx::uint32_cnttz(streamMask); streamMask >>= ntz; - idx += ntz; + idx += ntz; const Stream& stream = _draw.m_stream[idx]; @@ -3888,13 +3970,13 @@ namespace bgfx { namespace d3d12 VertexBufferD3D12& vb = s_renderD3D12->m_vertexBuffers[handle]; vb.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - uint16_t decl = !isValid(vb.m_decl) ? stream.m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = s_renderD3D12->m_vertexDecls[decl]; - uint32_t stride = vertexDecl.m_stride; + const uint16_t layoutIdx = !isValid(vb.m_layoutHandle) ? stream.m_layoutHandle.idx : vb.m_layoutHandle.idx; + const VertexLayout& layout = s_renderD3D12->m_vertexLayouts[layoutIdx]; + uint32_t stride = layout.m_stride; D3D12_VERTEX_BUFFER_VIEW& vbv = _vbv[numStreams]; vbv.BufferLocation = vb.m_gpuVA + stream.m_startVertex * stride; - vbv.StrideInBytes = vertexDecl.m_stride; + vbv.StrideInBytes = layout.m_stride; vbv.SizeInBytes = vb.m_size; _outNumVertices = bx::uint32_min(UINT32_MAX == _draw.m_numVertices @@ -4214,15 +4296,15 @@ namespace bgfx { namespace d3d12 static const UavFormat s_uavFormat[] = { // BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT { { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, 0 }, // ignored - { { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN }, 1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x1 - { { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x2 - { { DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x4 - { { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_FLOAT }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_16x1 - { { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_16x2 - { { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_16x4 - { { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x1 - { { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x2 - { { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_FLOAT }, 16 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x4 + { { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN }, 1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X1 + { { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X2 + { { DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X4 + { { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_FLOAT }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X1 + { { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X2 + { { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X4 + { { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X1 + { { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X2 + { { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_FLOAT }, 16 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X4 }; void BufferD3D12::create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride) @@ -4360,10 +4442,10 @@ namespace bgfx { namespace d3d12 return _state; } - void VertexBufferD3D12::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags) + void VertexBufferD3D12::create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags) { BufferD3D12::create(_size, _data, _flags, true); - m_decl = _declHandle; + m_layoutHandle = _layoutHandle; } void ShaderD3D12::create(const Memory* _mem) @@ -4518,18 +4600,27 @@ namespace bgfx { namespace d3d12 if (bimg::imageParse(imageContainer, _mem->data, _mem->size) ) { - uint8_t numMips = imageContainer.m_numMips; - const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) ); - numMips -= startLod; const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(imageContainer.m_format); - const uint32_t textureWidth = bx::uint32_max(blockInfo.blockWidth, imageContainer.m_width >>startLod); - const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod); - const uint16_t numLayers = imageContainer.m_numLayers; - - m_flags = _flags; - m_width = textureWidth; - m_height = textureHeight; - m_depth = imageContainer.m_depth; + const uint8_t startLod = bx::min(_skip, imageContainer.m_numMips-1); + + bimg::TextureInfo ti; + bimg::imageGetSize( + &ti + , uint16_t(imageContainer.m_width >>startLod) + , uint16_t(imageContainer.m_height>>startLod) + , uint16_t(imageContainer.m_depth >>startLod) + , imageContainer.m_cubeMap + , 1 < imageContainer.m_numMips + , imageContainer.m_numLayers + , imageContainer.m_format + ); + ti.numMips = bx::min(imageContainer.m_numMips-startLod, ti.numMips); + + m_flags = _flags; + m_width = ti.width; + m_height = ti.height; + m_depth = ti.depth; + m_numLayers = ti.numLayers; m_requestedFormat = uint8_t(imageContainer.m_format); m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); const bool convert = m_textureFormat != m_requestedFormat; @@ -4548,9 +4639,9 @@ namespace bgfx { namespace d3d12 m_type = Texture2D; } - m_numMips = numMips; - const uint16_t numSides = numLayers * (imageContainer.m_cubeMap ? 6 : 1); - const uint32_t numSrd = numSides * numMips; + m_numMips = ti.numMips; + const uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1); + const uint32_t numSrd = numSides * ti.numMips; D3D12_SUBRESOURCE_DATA* srd = (D3D12_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D12_SUBRESOURCE_DATA) ); uint32_t kk = 0; @@ -4567,8 +4658,8 @@ namespace bgfx { namespace d3d12 , this - s_renderD3D12->m_textures , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) - , textureWidth - , textureHeight + , ti.width + , ti.height , imageContainer.m_cubeMap ? "x6" : "" , renderTarget ? 'x' : ' ' , writeOnly ? 'x' : ' ' @@ -4578,7 +4669,7 @@ namespace bgfx { namespace d3d12 for (uint8_t side = 0; side < numSides; ++side) { - for (uint8_t lod = 0; lod < numMips; ++lod) + for (uint8_t lod = 0; lod < ti.numMips; ++lod) { bimg::ImageMip mip; if (bimg::imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) ) @@ -4667,9 +4758,9 @@ namespace bgfx { namespace d3d12 D3D12_RESOURCE_DESC resourceDesc; resourceDesc.Alignment = 1 < msaa.Count ? D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : 0; - resourceDesc.Width = textureWidth; - resourceDesc.Height = textureHeight; - resourceDesc.MipLevels = numMips; + resourceDesc.Width = ti.width; + resourceDesc.Height = ti.height; + resourceDesc.MipLevels = ti.numMips; resourceDesc.Format = format; resourceDesc.SampleDesc = msaa; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; @@ -4730,56 +4821,40 @@ namespace bgfx { namespace d3d12 switch (m_type) { case Texture2D: - case TextureCube: resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - if (imageContainer.m_cubeMap) + + if (1 < ti.numLayers) { - if (1 < numLayers) - { - m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY; - m_srvd.TextureCubeArray.MostDetailedMip = 0; - m_srvd.TextureCubeArray.MipLevels = numMips; - m_srvd.TextureCubeArray.ResourceMinLODClamp = 0.0f; - m_srvd.TextureCubeArray.NumCubes = numLayers; - } - else - { - m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; - m_srvd.TextureCube.MostDetailedMip = 0; - m_srvd.TextureCube.MipLevels = numMips; - m_srvd.TextureCube.ResourceMinLODClamp = 0.0f; - } + m_srvd.ViewDimension = 1 < msaa.Count + ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY + : D3D12_SRV_DIMENSION_TEXTURE2DARRAY + ; + m_srvd.Texture2DArray.MostDetailedMip = 0; + m_srvd.Texture2DArray.MipLevels = ti.numMips; + m_srvd.Texture2DArray.FirstArraySlice = 0; + m_srvd.Texture2DArray.ArraySize = ti.numLayers; + m_srvd.Texture2DArray.PlaneSlice = 0; + m_srvd.Texture2DArray.ResourceMinLODClamp = 0.0f; } else { - if (1 < numLayers) - { - m_srvd.ViewDimension = 1 < msaa.Count - ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY - : D3D12_SRV_DIMENSION_TEXTURE2DARRAY - ; - m_srvd.Texture2DArray.MostDetailedMip = 0; - m_srvd.Texture2DArray.MipLevels = numMips; - m_srvd.Texture2DArray.ResourceMinLODClamp = 0.0f; - m_srvd.Texture2DArray.ArraySize = numLayers; - } - else - { - m_srvd.ViewDimension = 1 < msaa.Count - ? D3D12_SRV_DIMENSION_TEXTURE2DMS - : D3D12_SRV_DIMENSION_TEXTURE2D - ; - m_srvd.Texture2D.MostDetailedMip = 0; - m_srvd.Texture2D.MipLevels = numMips; - m_srvd.Texture2D.ResourceMinLODClamp = 0.0f; - } + m_srvd.ViewDimension = 1 < msaa.Count + ? D3D12_SRV_DIMENSION_TEXTURE2DMS + : D3D12_SRV_DIMENSION_TEXTURE2D + ; + m_srvd.Texture2D.MostDetailedMip = 0; + m_srvd.Texture2D.MipLevels = ti.numMips; + m_srvd.Texture2D.PlaneSlice = 0; + m_srvd.Texture2D.ResourceMinLODClamp = 0.0f; } - if (1 < numLayers) + if (1 < ti.numLayers) { m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; - m_uavd.Texture2DArray.MipSlice = 0; - m_uavd.Texture2DArray.PlaneSlice = 0; + m_uavd.Texture2DArray.MipSlice = 0; + m_uavd.Texture2DArray.FirstArraySlice = 0; + m_uavd.Texture2DArray.ArraySize = ti.numLayers; + m_uavd.Texture2DArray.PlaneSlice = 0; } else { @@ -4787,14 +4862,6 @@ namespace bgfx { namespace d3d12 m_uavd.Texture2D.MipSlice = 0; m_uavd.Texture2D.PlaneSlice = 0; } - - if (TextureCube == m_type) - { - m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; - m_uavd.Texture2DArray.MipSlice = 0; - m_uavd.Texture2DArray.ArraySize = 6; - } - break; case Texture3D: @@ -4802,13 +4869,39 @@ namespace bgfx { namespace d3d12 resourceDesc.DepthOrArraySize = uint16_t(m_depth); m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; m_srvd.Texture3D.MostDetailedMip = 0; - m_srvd.Texture3D.MipLevels = numMips; + m_srvd.Texture3D.MipLevels = ti.numMips; m_srvd.Texture3D.ResourceMinLODClamp = 0.0f; m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; m_uavd.Texture3D.MipSlice = 0; m_uavd.Texture3D.FirstWSlice = 0; - m_uavd.Texture3D.WSize = 0; + m_uavd.Texture3D.WSize = m_depth; + break; + + case TextureCube: + resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + + if (1 < ti.numLayers) + { + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY; + m_srvd.TextureCubeArray.MostDetailedMip = 0; + m_srvd.TextureCubeArray.MipLevels = ti.numMips; + m_srvd.TextureCubeArray.ResourceMinLODClamp = 0.0f; + m_srvd.TextureCubeArray.NumCubes = ti.numLayers; + } + else + { + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + m_srvd.TextureCube.MostDetailedMip = 0; + m_srvd.TextureCube.MipLevels = ti.numMips; + m_srvd.TextureCube.ResourceMinLODClamp = 0.0f; + } + + m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; + m_uavd.Texture2DArray.MipSlice = 0; + m_uavd.Texture2DArray.FirstArraySlice = 0; + m_uavd.Texture2DArray.ArraySize = 6; + m_uavd.Texture2DArray.PlaneSlice = 0; break; } @@ -4853,7 +4946,7 @@ namespace bgfx { namespace d3d12 kk = 0; for (uint8_t side = 0; side < numSides; ++side) { - for (uint32_t lod = 0, num = numMips; lod < num; ++lod) + for (uint32_t lod = 0, num = ti.numMips; lod < num; ++lod) { BX_FREE(g_allocator, const_cast(srd[kk].pData) ); ++kk; @@ -4977,10 +5070,11 @@ namespace bgfx { namespace d3d12 #if BX_PLATFORM_WINDOWS SwapChainDesc scd; bx::memCopy(&scd, &s_renderD3D12->m_scd, sizeof(DXGI_SWAP_CHAIN_DESC) ); - scd.format = TextureFormat::Count == _format ? scd.format : s_textureFormat[_format].m_fmt; - scd.width = _width; - scd.height = _height; - scd.nwh = _nwh; + scd.format = TextureFormat::Count == _format ? scd.format : s_textureFormat[_format].m_fmt; + scd.width = _width; + scd.height = _height; + scd.nwh = _nwh; + scd.sampleDesc = s_msaa[0]; HRESULT hr; hr = s_renderD3D12->m_dxgi.createSwapChain( @@ -5135,9 +5229,20 @@ namespace bgfx { namespace d3d12 // } // else { - desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - desc.Texture2D.MipSlice = at.mip; - desc.Texture2D.PlaneSlice = 0; + if (1 < texture.m_numLayers) + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.FirstArraySlice = at.layer; + desc.Texture2DArray.ArraySize = 1; + desc.Texture2DArray.MipSlice = at.mip; + desc.Texture2DArray.PlaneSlice = 0; + } + else + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = at.mip; + desc.Texture2D.PlaneSlice = 0; + } } break; @@ -5613,8 +5718,6 @@ namespace bgfx { namespace d3d12 void RendererContextD3D12::submit(Frame* _render, ClearQuad& /*_clearQuad*/, TextVideoMemBlitter& _textVideoMemBlitter) { - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_FRAME, "rendererSubmit"); - if (m_lost || updateResolution(_render->m_resolution) ) { @@ -5626,6 +5729,8 @@ namespace bgfx { namespace d3d12 renderDocTriggerCapture(); } + BGFX_D3D12_PROFILER_BEGIN_LITERAL("rendererSubmit", kColorFrame); + int64_t timeBegin = bx::getHPCounter(); int64_t captureElapsed = 0; @@ -5633,12 +5738,14 @@ namespace bgfx { namespace d3d12 if (0 < _render->m_iboffset) { + BGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource); TransientIndexBuffer* ib = _render->m_transientIb; m_indexBuffers[ib->handle.idx].update(m_commandList, 0, _render->m_iboffset, ib->data); } if (0 < _render->m_vboffset) { + BGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource); TransientVertexBuffer* vb = _render->m_transientVb; m_vertexBuffers[vb->handle.idx].update(m_commandList, 0, _render->m_vboffset, vb->data); } @@ -5653,15 +5760,14 @@ namespace bgfx { namespace d3d12 RenderBind currentBind; currentBind.clear(); - const bool hmdEnabled = false; static ViewState viewState; - viewState.reset(_render, hmdEnabled); + viewState.reset(_render); // bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME); // setDebugWireframe(wireframe); uint16_t currentSamplerStateIdx = kInvalidHandle; - uint16_t currentProgramIdx = kInvalidHandle; + ProgramHandle currentProgram = BGFX_INVALID_HANDLE; uint32_t currentBindHash = 0; bool hasPredefined = false; bool commandListChanged = false; @@ -5753,12 +5859,10 @@ namespace bgfx { namespace d3d12 m_batch.begin(); -// uint8_t eye = 0; -// uint8_t restartState = 0; viewState.m_rect = _render->m_view[0].m_rect; - int32_t numItems = _render->m_numRenderItems; - for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;) + + for (int32_t item = 0; item < numItems;) { const uint64_t encodedKey = _render->m_sortKeys[item]; const bool isCompute = key.decode(encodedKey, _render->m_viewRemap); @@ -5784,19 +5888,23 @@ namespace bgfx { namespace d3d12 view = key.m_view; currentPso = NULL; currentSamplerStateIdx = kInvalidHandle; - currentProgramIdx = kInvalidHandle; + currentProgram = BGFX_INVALID_HANDLE; hasPredefined = false; - fbh = _render->m_view[view].m_fbh; - setFrameBuffer(fbh); - if (item > 1) { profiler.end(); } + BGFX_D3D12_PROFILER_END(); + setViewType(view, " "); + BGFX_D3D12_PROFILER_BEGIN(view, kColorView); + profiler.begin(view); + fbh = _render->m_view[view].m_fbh; + setFrameBuffer(fbh); + viewState.m_rect = _render->m_view[view].m_rect; const Rect& rect = _render->m_view[view].m_rect; const Rect& scissorRect = _render->m_view[view].m_scissor; @@ -5839,13 +5947,9 @@ namespace bgfx { namespace d3d12 { wasCompute = true; - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - char* viewName = s_viewName[view]; - viewName[3] = L'C'; - PIX3_ENDEVENT(m_commandList); - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_COMPUTE, viewName); - } + setViewType(view, "C"); + BGFX_D3D12_PROFILER_END(); + BGFX_D3D12_PROFILER_BEGIN(view, kColorCompute); commandListChanged = true; } @@ -5880,90 +5984,100 @@ namespace bgfx { namespace d3d12 Bind* bindCached = bindLru.find(bindHash); if (NULL == bindCached) { + uint32_t numSet = 0; D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_MAX_COMPUTE_BINDINGS] = {}; uint32_t samplerFlags[BGFX_MAX_COMPUTE_BINDINGS] = {}; - - for (uint8_t stage = 0; stage < maxComputeBindings; ++stage) { - const Binding& bind = renderBind.m_bind[stage]; - if (kInvalidHandle != bind.m_idx) + for (uint8_t stage = 0; stage < maxComputeBindings; ++stage) { - switch (bind.m_type) + const Binding& bind = renderBind.m_bind[stage]; + if (kInvalidHandle != bind.m_idx) { - case Binding::Image: + switch (bind.m_type) { - TextureD3D12& texture = m_textures[bind.m_idx]; - - if (Access::Read != bind.m_access) + case Binding::Image: { - texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip); + TextureD3D12& texture = m_textures[bind.m_idx]; + + if (Access::Read != bind.m_access) + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip); + } + else + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip); + samplerFlags[stage] = uint32_t(texture.m_flags); + } + + ++numSet; } - else + break; + + case Binding::Texture: { + TextureD3D12& texture = m_textures[bind.m_idx]; texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip); - samplerFlags[stage] = uint32_t(texture.m_flags); + scratchBuffer.allocSrv(srvHandle[stage], texture); + samplerFlags[stage] = (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags) + ? bind.m_samplerFlags + : texture.m_flags + ) & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK | BGFX_SAMPLER_COMPARE_MASK) + ; + + ++numSet; } - } - break; + break; - case Binding::Texture: - { - TextureD3D12& texture = m_textures[bind.m_idx]; - texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], texture); - samplerFlags[stage] = (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags) - ? bind.m_samplerFlags - : texture.m_flags - ) & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK | BGFX_SAMPLER_COMPARE_MASK) - ; - } - break; + case Binding::IndexBuffer: + case Binding::VertexBuffer: + { + BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type + ? m_indexBuffers[bind.m_idx] + : m_vertexBuffers[bind.m_idx] + ; - case Binding::IndexBuffer: - case Binding::VertexBuffer: - { - BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type - ? m_indexBuffers[bind.m_idx] - : m_vertexBuffers[bind.m_idx] - ; + if (Access::Read != bind.m_access) + { + buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], buffer); + } + else + { + buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], buffer); + } - if (Access::Read != bind.m_access) - { - buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], buffer); - } - else - { - buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], buffer); + ++numSet; } + break; } - break; + } + else + { + samplerFlags[stage] = 0; + scratchBuffer.allocEmpty(srvHandle[stage]); } } - else + + if (0 != numSet) { - samplerFlags[stage] = 0; - scratchBuffer.allocEmpty(srvHandle[stage]); - } - } + Bind bind; + bind.m_srvHandle = srvHandle[0]; + bind.m_samplerStateIdx = getSamplerState(samplerFlags, maxComputeBindings, _render->m_colorPalette); + bindCached = bindLru.add(bindHash, bind, 0); - uint16_t samplerStateIdx = getSamplerState(samplerFlags, maxComputeBindings, _render->m_colorPalette); - if (samplerStateIdx != currentSamplerStateIdx) - { - currentSamplerStateIdx = samplerStateIdx; - m_commandList->SetComputeRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); + uint16_t samplerStateIdx = bindCached->m_samplerStateIdx; + if (samplerStateIdx != currentSamplerStateIdx) + { + currentSamplerStateIdx = samplerStateIdx; + m_commandList->SetComputeRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); + } + m_commandList->SetComputeRootDescriptorTable(Rdt::SRV, bindCached->m_srvHandle); + m_commandList->SetComputeRootDescriptorTable(Rdt::UAV, bindCached->m_srvHandle); + } } - - m_commandList->SetComputeRootDescriptorTable(Rdt::SRV, srvHandle[0]); - m_commandList->SetComputeRootDescriptorTable(Rdt::UAV, srvHandle[0]); - - Bind bind; - bind.m_srvHandle = srvHandle[0]; - bind.m_samplerStateIdx = samplerStateIdx; - bindLru.add(bindHash, bind, 0); } else { @@ -5980,12 +6094,12 @@ namespace bgfx { namespace d3d12 bool constantsChanged = false; if (compute.m_uniformBegin < compute.m_uniformEnd - || currentProgramIdx != key.m_program) + || currentProgram.idx != key.m_program.idx) { rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); - currentProgramIdx = key.m_program; - ProgramD3D12& program = m_program[currentProgramIdx]; + currentProgram = key.m_program; + ProgramD3D12& program = m_program[currentProgram.idx]; UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) @@ -6000,8 +6114,8 @@ namespace bgfx { namespace d3d12 if (constantsChanged || hasPredefined) { - ProgramD3D12& program = m_program[currentProgramIdx]; - viewState.setPredefined<4>(this, view, 0, program, _render, compute); + ProgramD3D12& program = m_program[currentProgram.idx]; + viewState.setPredefined<4>(this, view, program, _render, compute); commitShaderConstants(key.m_program, gpuAddress); m_commandList->SetComputeRootConstantBufferView(Rdt::CBV, gpuAddress); } @@ -6038,14 +6152,9 @@ namespace bgfx { namespace d3d12 { wasCompute = false; - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - BX_UNUSED(s_viewName); - char* viewName = s_viewName[view]; - viewName[3] = ' '; - PIX3_ENDEVENT(m_commandList); - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_DRAW, viewName); - } + setViewType(view, " "); + BGFX_D3D12_PROFILER_END(); + BGFX_D3D12_PROFILER_BEGIN(view, kColorDraw); commandListChanged = true; } @@ -6113,7 +6222,7 @@ namespace bgfx { namespace d3d12 currentPso = NULL; currentBindHash = 0; currentSamplerStateIdx = kInvalidHandle; - currentProgramIdx = kInvalidHandle; + currentProgram = BGFX_INVALID_HANDLE; currentState.clear(); currentState.m_scissor = !draw.m_scissor; changedFlags = BGFX_STATE_MASK; @@ -6145,29 +6254,32 @@ namespace bgfx { namespace d3d12 || f3 == (state & f3) ; - const VertexDecl* decls[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + const VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS]; uint8_t numStreams = 0; if (UINT8_MAX != draw.m_streamMask) { - for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + for (uint32_t idx = 0, streamMask = draw.m_streamMask ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ; streamMask >>= 1, idx += 1, ++numStreams ) { + const uint32_t ntz = bx::uint32_cnttz(streamMask); streamMask >>= ntz; - idx += ntz; + idx += ntz; - currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; - currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; - currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; + currentState.m_stream[idx].m_layoutHandle = draw.m_stream[idx].m_layoutHandle; + currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; + currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; uint16_t handle = draw.m_stream[idx].m_handle.idx; const VertexBufferD3D12& vb = m_vertexBuffers[handle]; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = m_vertexDecls[decl]; + const uint16_t layoutIdx = isValid(draw.m_stream[idx].m_layoutHandle) + ? draw.m_stream[idx].m_layoutHandle.idx + : vb.m_layoutHandle.idx; + const VertexLayout& layout = m_vertexLayouts[layoutIdx]; - decls[numStreams] = &vertexDecl; + layouts[numStreams] = &layout; } } @@ -6175,7 +6287,7 @@ namespace bgfx { namespace d3d12 getPipelineState(state , draw.m_stencil , numStreams - , decls + , layouts , key.m_program , uint8_t(draw.m_instanceDataStride/16) ); @@ -6263,20 +6375,20 @@ namespace bgfx { namespace d3d12 if (0 != numSet) { - uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, _render->m_colorPalette); + Bind bind; + bind.m_srvHandle = srvHandle[0]; + bind.m_samplerStateIdx = getSamplerState(samplerFlags, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, _render->m_colorPalette); + bindCached = bindLru.add(bindHash, bind, 0); + + uint16_t samplerStateIdx = bindCached->m_samplerStateIdx; if (samplerStateIdx != currentSamplerStateIdx) { currentSamplerStateIdx = samplerStateIdx; m_commandList->SetGraphicsRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); } - m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle[0]); - m_commandList->SetGraphicsRootDescriptorTable(Rdt::UAV, srvHandle[0]); - - Bind bind; - bind.m_srvHandle = srvHandle[0]; - bind.m_samplerStateIdx = samplerStateIdx; - bindLru.add(bindHash, bind, 0); + m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, bindCached->m_srvHandle); + m_commandList->SetGraphicsRootDescriptorTable(Rdt::UAV, bindCached->m_srvHandle); } } else @@ -6366,11 +6478,11 @@ namespace bgfx { namespace d3d12 } if (constantsChanged - || currentProgramIdx != key.m_program + || currentProgram.idx != key.m_program.idx || BGFX_STATE_ALPHA_REF_MASK & changedFlags) { - currentProgramIdx = key.m_program; - ProgramD3D12& program = m_program[currentProgramIdx]; + currentProgram = key.m_program; + ProgramD3D12& program = m_program[currentProgram.idx]; UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) @@ -6394,10 +6506,10 @@ namespace bgfx { namespace d3d12 if (constantsChanged || hasPredefined) { - ProgramD3D12& program = m_program[currentProgramIdx]; + ProgramD3D12& program = m_program[currentProgram.idx]; uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT; viewState.m_alphaRef = ref/255.0f; - viewState.setPredefined<4>(this, view, 0, program, _render, draw); + viewState.setPredefined<4>(this, view, program, _render, draw); commitShaderConstants(key.m_program, gpuAddress); } @@ -6424,13 +6536,9 @@ namespace bgfx { namespace d3d12 if (wasCompute) { - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - char* viewName = s_viewName[view]; - viewName[3] = L'C'; - PIX3_ENDEVENT(m_commandList); - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_DRAW, viewName); - } + setViewType(view, "C"); + BGFX_D3D12_PROFILER_END(); + BGFX_D3D12_PROFILER_BEGIN(view, kColorCompute); } submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); @@ -6450,7 +6558,7 @@ namespace bgfx { namespace d3d12 } } - PIX3_ENDEVENT(m_commandList); + BGFX_D3D12_PROFILER_END(); int64_t timeEnd = bx::getHPCounter(); int64_t frameTime = timeEnd - timeBegin; @@ -6512,7 +6620,7 @@ namespace bgfx { namespace d3d12 if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) { - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_FRAME, "debugstats"); + BGFX_D3D12_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame); // m_needPresent = true; TextVideoMem& tvm = m_textVideoMem; @@ -6676,15 +6784,15 @@ namespace bgfx { namespace d3d12 blit(this, _textVideoMemBlitter, tvm); - PIX3_ENDEVENT(m_commandList); + BGFX_D3D12_PROFILER_END(); } else if (_render->m_debug & BGFX_DEBUG_TEXT) { - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_FRAME, "debugtext"); + BGFX_D3D12_PROFILER_BEGIN_LITERAL("debugtext", kColorFrame); blit(this, _textVideoMemBlitter, _render->m_textVideoMem); - PIX3_ENDEVENT(m_commandList); + BGFX_D3D12_PROFILER_END(); } m_commandList->OMSetRenderTargets(0, NULL, false, NULL); -- cgit v1.2.3-70-g09d2