//============================================================================== VkPipelineColorBlendStateCreateInfo* PipelineImpl::initColorState( const ColorStateInfo& c, VkPipelineColorBlendStateCreateInfo& ci) { ci.logicOpEnable = VK_FALSE; ci.attachmentCount = c.m_attachmentCount; for(U i = 0; i < ci.attachmentCount; ++i) { VkPipelineColorBlendAttachmentState& out = const_cast<VkPipelineColorBlendAttachmentState&>( ci.pAttachments[i]); const ColorAttachmentStateInfo& in = c.m_attachments[i]; out.blendEnable = !(in.m_srcBlendMethod == BlendMethod::ONE && in.m_dstBlendMethod == BlendMethod::ZERO); out.srcColorBlendFactor = convertBlendMethod(in.m_srcBlendMethod); out.dstColorBlendFactor = convertBlendMethod(in.m_dstBlendMethod); out.colorBlendOp = convertBlendFunc(in.m_blendFunction); out.srcAlphaBlendFactor = out.srcColorBlendFactor; out.dstAlphaBlendFactor = out.dstColorBlendFactor; out.alphaBlendOp = out.colorBlendOp; out.colorWriteMask = convertColorWriteMask(in.m_channelWriteMask); } return &ci; }
Pipeline* Direct3D12Backend::createPipeline(const PipelineDesc& desc) { HRESULT hr; auto* pipeline = new Direct3D12Pipeline(); // Root signature parameters CD3DX12_DESCRIPTOR_RANGE ranges[2]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, desc.numCBVs, 0); ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, desc.numSRVs, 0); std::vector<CD3DX12_ROOT_PARAMETER> parameters; if (desc.numCBVs) { CD3DX12_ROOT_PARAMETER parameter; parameter.InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL); parameters.push_back(parameter); } if (desc.numSRVs) { CD3DX12_ROOT_PARAMETER parameter; parameter.InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL); parameters.push_back(parameter); } // Samplers std::vector<D3D12_STATIC_SAMPLER_DESC> d3dSamplers(desc.samplers.size()); for (Size i = 0; i < desc.samplers.size(); i++) { const auto& sampler = desc.samplers[i]; d3dSamplers[i].Filter = convertFilter(sampler.filter); d3dSamplers[i].AddressU = convertTextureAddressMode(sampler.addressU); d3dSamplers[i].AddressV = convertTextureAddressMode(sampler.addressV); d3dSamplers[i].AddressW = convertTextureAddressMode(sampler.addressW); d3dSamplers[i].MipLODBias = 0; d3dSamplers[i].MaxAnisotropy = 0; d3dSamplers[i].ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; d3dSamplers[i].BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; d3dSamplers[i].MinLOD = 0.0f; d3dSamplers[i].MaxLOD = D3D12_FLOAT32_MAX; d3dSamplers[i].ShaderRegister = i; d3dSamplers[i].RegisterSpace = 0; d3dSamplers[i].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; } // Root signature D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = {}; rootSignatureDesc.NumParameters = parameters.size(); rootSignatureDesc.pParameters = parameters.data(); rootSignatureDesc.NumStaticSamplers = d3dSamplers.size(); rootSignatureDesc.pStaticSamplers = d3dSamplers.data(); rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS; ID3DBlob* signature; ID3DBlob* error; hr = _D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); if (FAILED(hr)) { LPVOID errorString = error->GetBufferPointer(); logger.error(LOG_GRAPHICS, "Direct3D12Backend::createPipeline: D3D12SerializeRootSignature failed (0x%X): %s", hr, errorString); return nullptr; } hr = device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&pipeline->rootSignature)); if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::createPipeline: CreateRootSignature failed (0x%X)", hr); return nullptr; } D3D12_GRAPHICS_PIPELINE_STATE_DESC d3dDesc = {}; d3dDesc.NodeMask = 1; d3dDesc.SampleMask = UINT_MAX; d3dDesc.pRootSignature = pipeline->rootSignature; d3dDesc.NumRenderTargets = 1; d3dDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; d3dDesc.DSVFormat = convertFormat(desc.formatDSV); d3dDesc.SampleDesc.Count = 1; // Shaders if (desc.vs) { auto* d3dShader = static_cast<Direct3D12Shader*>(desc.vs); d3dDesc.VS.pShaderBytecode = d3dShader->bytecodeData; d3dDesc.VS.BytecodeLength = d3dShader->bytecodeSize; } if (desc.hs) { auto* d3dShader = static_cast<Direct3D12Shader*>(desc.hs); d3dDesc.HS.pShaderBytecode = d3dShader->bytecodeData; d3dDesc.HS.BytecodeLength = d3dShader->bytecodeSize; } if (desc.ds) { auto* d3dShader = static_cast<Direct3D12Shader*>(desc.ds); d3dDesc.DS.pShaderBytecode = d3dShader->bytecodeData; d3dDesc.DS.BytecodeLength = d3dShader->bytecodeSize; } if (desc.gs) { auto* d3dShader = static_cast<Direct3D12Shader*>(desc.gs); d3dDesc.GS.pShaderBytecode = d3dShader->bytecodeData; d3dDesc.GS.BytecodeLength = d3dShader->bytecodeSize; } if (desc.ps) { auto* d3dShader = static_cast<Direct3D12Shader*>(desc.ps); d3dDesc.PS.pShaderBytecode = d3dShader->bytecodeData; d3dDesc.PS.BytecodeLength = d3dShader->bytecodeSize; } // IA state std::vector<D3D12_INPUT_ELEMENT_DESC> d3dInputElements; for (const auto& element : desc.iaState.inputLayout) { DXGI_FORMAT format = convertFormat(element.format); D3D12_INPUT_CLASSIFICATION inputClassification = convertInputClassification(element.inputClassification); d3dInputElements.emplace_back(D3D12_INPUT_ELEMENT_DESC{ "INPUT", element.semanticIndex, format, element.inputSlot, element.offset, inputClassification, element.instanceStepRate }); } d3dDesc.InputLayout.NumElements = d3dInputElements.size(); d3dDesc.InputLayout.pInputElementDescs = d3dInputElements.data(); d3dDesc.PrimitiveTopologyType = convertPrimitiveTopologyType(desc.iaState.topology); // RS state d3dDesc.RasterizerState.FillMode = convertFillMode(desc.rsState.fillMode); d3dDesc.RasterizerState.CullMode = convertCullMode(desc.rsState.cullMode); d3dDesc.RasterizerState.FrontCounterClockwise = desc.rsState.frontCounterClockwise; d3dDesc.RasterizerState.DepthClipEnable = TRUE; // TODO d3dDesc.DepthStencilState.DepthEnable = desc.rsState.depthEnable; d3dDesc.DepthStencilState.DepthWriteMask = convertDepthWriteMask(desc.rsState.depthWriteMask); d3dDesc.DepthStencilState.DepthFunc = convertComparisonFunc(desc.rsState.depthFunc); d3dDesc.DepthStencilState.StencilEnable = desc.rsState.stencilEnable; d3dDesc.DepthStencilState.StencilReadMask = desc.rsState.stencilReadMask; d3dDesc.DepthStencilState.StencilWriteMask = desc.rsState.stencilWriteMask; d3dDesc.DepthStencilState.FrontFace.StencilFailOp = convertStencilOp(desc.rsState.frontFace.stencilOpFail); d3dDesc.DepthStencilState.FrontFace.StencilDepthFailOp = convertStencilOp(desc.rsState.frontFace.stencilOpZFail); d3dDesc.DepthStencilState.FrontFace.StencilPassOp = convertStencilOp(desc.rsState.frontFace.stencilOpPass); d3dDesc.DepthStencilState.FrontFace.StencilFunc = convertComparisonFunc(desc.rsState.frontFace.stencilFunc); d3dDesc.DepthStencilState.BackFace.StencilFailOp = convertStencilOp(desc.rsState.backFace.stencilOpFail); d3dDesc.DepthStencilState.BackFace.StencilDepthFailOp = convertStencilOp(desc.rsState.backFace.stencilOpZFail); d3dDesc.DepthStencilState.BackFace.StencilPassOp = convertStencilOp(desc.rsState.backFace.stencilOpPass); d3dDesc.DepthStencilState.BackFace.StencilFunc = convertComparisonFunc(desc.rsState.backFace.stencilFunc); // CB state d3dDesc.BlendState.AlphaToCoverageEnable = desc.cbState.enableAlphaToCoverage; d3dDesc.BlendState.IndependentBlendEnable = desc.cbState.enableIndependentBlend; UINT sizeColorTargetBlendArray = d3dDesc.BlendState.IndependentBlendEnable ? 8 : 1; for (UINT i = 0; i < sizeColorTargetBlendArray; i++) { const auto& source = desc.cbState.colorTarget[i]; auto& d3dTarget = d3dDesc.BlendState.RenderTarget[i]; d3dTarget.BlendEnable = source.enableBlend; d3dTarget.LogicOpEnable = source.enableLogicOp; d3dTarget.SrcBlend = convertBlend(source.srcBlend); d3dTarget.DestBlend = convertBlend(source.destBlend); d3dTarget.BlendOp = convertBlendOp(source.blendOp); d3dTarget.SrcBlendAlpha = convertBlend(source.srcBlendAlpha); d3dTarget.DestBlendAlpha = convertBlend(source.destBlendAlpha); d3dTarget.BlendOpAlpha = convertBlendOp(source.blendOpAlpha); d3dTarget.LogicOp = convertLogicOp(source.logicOp); d3dTarget.RenderTargetWriteMask = convertColorWriteMask(source.colorWriteMask); } hr = device->CreateGraphicsPipelineState(&d3dDesc, IID_PPV_ARGS(&pipeline->state)); if (FAILED(hr)) { logger.error(LOG_GRAPHICS, "Direct3D12Backend::createPipeline: CreateGraphicsPipelineState failed (0x%X)", hr); return nullptr; } return pipeline; }