Try / Tempest

3d graphics engine
MIT License
83 stars 24 forks source link

Robust support for push_constant's and SPIRV_Cross_VertexInfo in DX12 #39

Closed Try closed 1 year ago

Try commented 1 year ago

Currently shader registers are set to be automatic after cross compilation:

cbuffer SPIRV_Cross_VertexInfo
{
    int SPIRV_Cross_BaseVertex;
    int SPIRV_Cross_BaseInstance;
};

Yet, there is a problem: so far no good way to guess what register is it going to be.

Attempt #1 - find minimal value across unused ones. Normally it's a same as max_bind+1. - Doesn't work, if shader has unused bindings.

Attempt #2 - use reflection api.

    ComPtr<IDxcUtils> pUtils;
    hr = DxcCreateInstance(CLSID_DxcUtils, __uuidof(IDxcUtils), reinterpret_cast<void**>(&pUtils.get()));
    if(FAILED(hr))
      return hr;

    ComPtr<IDxcBlob> pReflectionData;
    hr = result->GetOutput(DXC_OUT_REFLECTION, IID_PPV_ARGS(&pReflectionData.get()), nullptr);
    if(FAILED(hr))
      return hr;

    // Create reflection interface.
    DxcBuffer ReflectionData;
    ReflectionData.Encoding = DXC_CP_ACP;
    ReflectionData.Ptr      = pReflectionData->GetBufferPointer();
    ReflectionData.Size     = pReflectionData->GetBufferSize();

    ComPtr<ID3D12ShaderReflection> pReflection;
    hr = pUtils->CreateReflection(&ReflectionData, IID_PPV_ARGS(&pReflection.get()));
    if(FAILED(hr))
      return hr;

    D3D12_SHADER_INPUT_BIND_DESC desc = {};
    pReflection->GetResourceBindingDescByName("SPIRV_Cross_VertexInfo",&desc);
    vertexInfoBind = desc.BindPoint;