Beispiel #1
0
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, &paramDesc);

        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);
    }
}
Beispiel #2
0
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");
}
Beispiel #3
0
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);
}
Beispiel #4
0
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 "";
}
Beispiel #5
0
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;
        }
    }
}
Beispiel #6
0
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) + "\""
        );
    }
}
Beispiel #7
0
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 {};
}
Beispiel #8
0
    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
                )
            );
    }