static void ReflectShaderVertexAttributes( ID3D12ShaderReflection* reflection, const D3D12_SHADER_DESC& shaderDesc, ShaderReflectionDescriptor& reflectionDesc) { for (UINT i = 0; i < shaderDesc.InputParameters; ++i) { /* Get signature parameter descriptor */ D3D12_SIGNATURE_PARAMETER_DESC paramDesc; auto hr = reflection->GetInputParameterDesc(i, ¶mDesc); if (FAILED(hr)) { std::string info = "failed to retrieve D3D12 signature parameter descriptor " + std::to_string(i + 1) + " of " + std::to_string(shaderDesc.InputParameters); DXThrowIfFailed(hr, info.c_str()); } /* Add vertex attribute to output list */ VertexAttribute vertexAttrib; { vertexAttrib.name = std::string(paramDesc.SemanticName); vertexAttrib.format = DXGetSignatureParameterType(paramDesc.ComponentType, paramDesc.Mask); vertexAttrib.semanticIndex = paramDesc.SemanticIndex; vertexAttrib.systemValue = DXTypes::Unmap(paramDesc.SystemValueType); } reflectionDesc.vertexAttributes.push_back(vertexAttrib); } }
void D3D12CommandQueue::Submit(Fence& fence) { /* Schedule signal command into the queue */ auto& fenceD3D = LLGL_CAST(D3D12Fence&, fence); auto hr = native_->Signal(fenceD3D.GetNative(), fenceD3D.NextValue()); DXThrowIfFailed(hr, "failed to signal D3D12 fence with command queue"); }
void D3D12Shader::ReflectShaderByteCode(ShaderReflectionDescriptor& reflectionDesc) const { HRESULT hr = 0; /* Get shader reflection */ ComPtr<ID3D12ShaderReflection> reflection; hr = D3DReflect(byteCode_.data(), byteCode_.size(), IID_PPV_ARGS(reflection.ReleaseAndGetAddressOf())); DXThrowIfFailed(hr, "failed to retrieve D3D12 shader reflection"); D3D12_SHADER_DESC shaderDesc; hr = reflection->GetDesc(&shaderDesc); DXThrowIfFailed(hr, "failed to retrieve D3D12 shader descriptor"); /* Get input parameter descriptors */ if (GetType() == ShaderType::Vertex) ReflectShaderVertexAttributes(reflection.Get(), shaderDesc, reflectionDesc); /* Get input bindings */ ReflectShaderInputBindings(reflection.Get(), shaderDesc, GetStageFlags(), reflectionDesc); }
std::string D3D12Shader::Disassemble(int flags) { if (!byteCode_.empty()) { ComPtr<ID3DBlob> disasm; auto hr = D3DDisassemble(byteCode_.data(), byteCode_.size(), DXGetDisassemblerFlags(flags), nullptr, &disasm); DXThrowIfFailed(hr, "failed to disassemble D3D12 shader byte code"); return DXGetBlobString(disasm.Get()); } return ""; }
static void ReflectShaderInputBindings( ID3D12ShaderReflection* reflection, const D3D12_SHADER_DESC& shaderDesc, long stageFlags, ShaderReflectionDescriptor& reflectionDesc) { UINT cbufferIdx = 0; for (UINT i = 0; i < shaderDesc.BoundResources; ++i) { /* Get shader input resource descriptor */ D3D12_SHADER_INPUT_BIND_DESC inputBindDesc; auto hr = reflection->GetResourceBindingDesc(i, &inputBindDesc); DXThrowIfFailed(hr, "failed to retrieve D3D12 shader input binding descriptor"); /* Reflect shader resource view */ switch (inputBindDesc.Type) { case D3D_SIT_CBUFFER: ReflectShaderConstantBuffer(reflection, reflectionDesc, shaderDesc, inputBindDesc, stageFlags, cbufferIdx); break; case D3D_SIT_TBUFFER: case D3D_SIT_TEXTURE: ReflectShaderResourceGeneric(inputBindDesc, reflectionDesc, ResourceType::Texture, BindFlags::SampleBuffer, stageFlags); break; case D3D_SIT_SAMPLER: ReflectShaderResourceGeneric(inputBindDesc, reflectionDesc, ResourceType::Sampler, 0, stageFlags); break; case D3D_SIT_STRUCTURED: case D3D_SIT_BYTEADDRESS: ReflectShaderResourceGeneric(inputBindDesc, reflectionDesc, ResourceType::Buffer, BindFlags::SampleBuffer, stageFlags); break; case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: case D3D_SIT_UAV_RWBYTEADDRESS: case D3D_SIT_UAV_APPEND_STRUCTURED: case D3D_SIT_UAV_CONSUME_STRUCTURED: case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: ReflectShaderResourceGeneric(inputBindDesc, reflectionDesc, ResourceType::Buffer, BindFlags::RWStorageBuffer, stageFlags); break; default: break; } } }
static void ReflectShaderConstantBuffer( ID3D12ShaderReflection* reflection, ShaderReflectionDescriptor& reflectionDesc, const D3D12_SHADER_DESC& shaderDesc, const D3D12_SHADER_INPUT_BIND_DESC& inputBindDesc, long stageFlags, UINT& cbufferIdx) { /* Initialize resource view descriptor for constant buffer */ auto resourceView = FetchOrInsertResource(reflectionDesc, inputBindDesc.Name, ResourceType::Buffer, inputBindDesc.BindPoint); { resourceView->bindFlags |= BindFlags::ConstantBuffer; resourceView->stageFlags |= stageFlags; resourceView->arraySize = inputBindDesc.BindCount; } /* Determine constant buffer size */ if (cbufferIdx < shaderDesc.ConstantBuffers) { auto cbufferReflection = reflection->GetConstantBufferByIndex(cbufferIdx++); D3D12_SHADER_BUFFER_DESC shaderBufferDesc; auto hr = cbufferReflection->GetDesc(&shaderBufferDesc); DXThrowIfFailed(hr, "failed to retrieve D3D12 shader buffer descriptor"); if (shaderBufferDesc.Type == D3D_CT_CBUFFER) { /* Store constant buffer size in output descriptor */ resourceView->constantBufferSize = shaderBufferDesc.Size; } else { /* Type mismatch in descriptors */ throw std::runtime_error( "failed to match D3D12 shader buffer descriptor \"" + std::string(shaderBufferDesc.Name) + "\" with input binding descriptor for constant buffer \"" + std::string(inputBindDesc.Name) + "\"" ); } } else { /* Resource index mismatch in descriptor */ throw std::runtime_error( "failed to find D3D12 shader buffer descriptor for input binding descriptor \"" + std::string(inputBindDesc.Name) + "\"" ); } }
D3D12_CPU_DESCRIPTOR_HANDLE D3D12ResourceHeap::CreateHeapTypeCbvSrvUav(ID3D12Device* device, const ResourceHeapDescriptor& desc) { /* Determine number of view descriptors */ UINT numDescriptors = 0; for (const auto& resourceView : desc.resourceViews) { if (auto resource = resourceView.resource) { /* Search SRV/UAV/CBV resources */ auto resType = resource->QueryResourceType(); if (resType == ResourceType::Buffer || resType == ResourceType::Texture) ++numDescriptors; } else ErrNullPointerInResource(); } if (numDescriptors > 0) { /* Create descriptor heap for views (CBV, SRV, UAV) */ D3D12_DESCRIPTOR_HEAP_DESC heapDesc; { heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; heapDesc.NumDescriptors = numDescriptors; heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; heapDesc.NodeMask = 0; } auto hr = device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(heapTypeCbvSrvUav_.ReleaseAndGetAddressOf())); DXThrowIfFailed(hr, "failed to create D3D12 descriptor heap of type D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV"); #ifdef LLGL_DEBUG heapTypeCbvSrvUav_->SetName(L"LLGL::D3D12ResourceHeap::heapTypeCbvSrvUav"); #endif /* Store in array for quick access */ AppendDescriptorHeapToArray(heapTypeCbvSrvUav_.Get()); return heapTypeCbvSrvUav_->GetCPUDescriptorHandleForHeapStart(); } return {}; }
void GBuffer::Initialize(const ComPtr<ID3D11Device1> &spD3DDevice1, D3D11_TEXTURE2D_DESC &bufferDesc){ // // Depth Stencil // // Create the depth stencil render target bufferDesc.Format = m_DepthStencilTextureFormat; bufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; bufferDesc.MipLevels = 1; bufferDesc.ArraySize = 1; DXThrowIfFailed( spD3DDevice1->CreateTexture2D( &bufferDesc, nullptr, &m_spDepthStencilRT ) ); // Create the depth stencil render target view D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilRTVDesc = { m_DepthStencilRTVFormat, D3D11_DSV_DIMENSION_TEXTURE2D, 0 }; DXThrowIfFailed( spD3DDevice1->CreateDepthStencilView( m_spDepthStencilRT.Get(), &depthStencilRTVDesc, &m_spDepthStencilView ) ); // Create read only depth stencil render target view depthStencilRTVDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL; DXThrowIfFailed( spD3DDevice1->CreateDepthStencilView( m_spDepthStencilRT.Get(), &depthStencilRTVDesc, &m_spDepthStencilViewReadOnly ) ); // Create the depth stencil shader resource view D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = { m_DepthStencilSRVFormat, D3D11_SRV_DIMENSION_TEXTURE2D, 0, 0 }; SRVDesc.Texture2D.MipLevels = 1; DXThrowIfFailed( spD3DDevice1->CreateShaderResourceView( m_spDepthStencilRT.Get(), &SRVDesc, &m_spDepthStencilSRV ) ); // Create the depth stencil state D3D11_DEPTH_STENCIL_DESC depthStencilDesc; depthStencilDesc.DepthEnable = TRUE; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = TRUE; depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; const D3D11_DEPTH_STENCILOP_DESC stencilMarkOp = { D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_REPLACE, D3D11_COMPARISON_ALWAYS }; depthStencilDesc.FrontFace = stencilMarkOp; depthStencilDesc.BackFace = stencilMarkOp; DXThrowIfFailed( spD3DDevice1->CreateDepthStencilState(&depthStencilDesc, m_spDepthStencilState.GetAddressOf()) ); // Create NoDepthWriteLessStencilMaskState D3D11_DEPTH_STENCIL_DESC noWriteDepthStencilDesc; noWriteDepthStencilDesc.DepthEnable = TRUE; noWriteDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; noWriteDepthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; noWriteDepthStencilDesc.StencilEnable = TRUE; noWriteDepthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; noWriteDepthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; const D3D11_DEPTH_STENCILOP_DESC noSkyStencilOp = { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_EQUAL }; noWriteDepthStencilDesc.FrontFace = noSkyStencilOp; noWriteDepthStencilDesc.BackFace = noSkyStencilOp; DXThrowIfFailed( spD3DDevice1->CreateDepthStencilState(&noWriteDepthStencilDesc, m_spNoDepthWriteLessStencilMaskState.GetAddressOf()) ); // // Color and Specular Intensity // // Create the color and specular intensity render target bufferDesc.Format = m_ColorSpecularIntensityTextureFormat; bufferDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; DXThrowIfFailed( spD3DDevice1->CreateTexture2D( &bufferDesc, nullptr, &m_spColorSpecularIntensityRT ) ); // Create the color and specular intensity render target view CD3D11_RENDER_TARGET_VIEW_DESC RTVDesc( D3D11_RTV_DIMENSION_TEXTURE2D, m_ColorSpecularIntensityRTVFormat ); DXThrowIfFailed( spD3DDevice1->CreateRenderTargetView( m_spColorSpecularIntensityRT.Get(), &RTVDesc, &m_spColorSpecularIntensityRTV ) ); // Create the color and specular intensity shader resource view SRVDesc.Format = m_ColorSpecularIntensitySRVFormat; DXThrowIfFailed( spD3DDevice1->CreateShaderResourceView( m_spColorSpecularIntensityRT.Get(), &SRVDesc, &m_spColorSpecularIntensitySRV ) ); // // Normal // // Create the normal render target bufferDesc.Format = m_NormalTextureFormat; DXThrowIfFailed( spD3DDevice1->CreateTexture2D( &bufferDesc, nullptr, &m_spNormalRT ) ); // Create the normal render target view RTVDesc.Format = m_NormalRTVFormat; DXThrowIfFailed( spD3DDevice1->CreateRenderTargetView( m_spNormalRT.Get(), &RTVDesc, &m_spNormalRTV ) ); // Create the normal shader resource view SRVDesc.Format = m_NormalSRVFormat; DXThrowIfFailed( spD3DDevice1->CreateShaderResourceView( m_spNormalRT.Get(), &SRVDesc, &m_spNormalSRV ) ); // // Specular Exponent // // Create the specular exponent render target bufferDesc.Format = m_SpecularExponentTextureFormat; DXThrowIfFailed( spD3DDevice1->CreateTexture2D( &bufferDesc, nullptr, &m_spPositonRT ) ); // Create the specular exponent render target view RTVDesc.Format = m_SpecularExponentRTVFormat; DXThrowIfFailed( spD3DDevice1->CreateRenderTargetView( m_spPositonRT.Get(), &RTVDesc, &m_spPositionRTV ) ); // Create the specular exponent shader resource view SRVDesc.Format = m_SpecularExponentSRVFormat; DXThrowIfFailed( spD3DDevice1->CreateShaderResourceView( m_spPositonRT.Get(), &SRVDesc, &m_spPositionSRV ) ); }