如何将纹理绑定到dx12中的不同寄存器?

时间:2019-04-11 08:39:54

标签: hlsl directx-12

我有两个纹理和一个纹理数组。我试图将两个纹理绑定到t1,将纹理数组绑定到t2。 hlsl可能会喜欢

from functools import lru_cache


@lru_cache(maxsize=None)
def fib4(n):
    if n <= 1:
        return n

    if n % 2:
        m = (n + 1) // 2
        return fib4(m) ** 2 + fib4(m - 1) ** 2
    else:
        m = n // 2
        return (2 * fib4(m - 1) + fib4(m)) * fib4(m)


def binarySearch( length):
    first = 0
    last = 10**5
    found = False

    while first <= last and not found:
        midpoint = (first + last) // 2
        length_string = len(str(fib4(midpoint)))
        if length_string == length:
            return midpoint -1
        else:
            if length < length_string:
                last = midpoint - 1
            else:
                first = midpoint + 1

print(binarySearch(1000))

我创建了一个包含2个描述符的描述符范围。

Texture2D    gDiffuseMap : register(t0);
Texture2DArray gDiffuseMaps : register(t1);

但是我不知道如何将描述符绑定到寄存器。

1 个答案:

答案 0 :(得分:2)

着色器与DirectX 12的GPU之间的通信是通过根签名处理的。对于两种纹理,如何绑定它有两种选择。

在一个描述符表中有两个纹理

首先是将它们绑定在一起,但这要求目标描述符是连续的。这就是您要做的事情。

// HLSL syntax
#define DualTextureRS \
"RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
"            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
"            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
"            DENY_HULL_SHADER_ROOT_ACCESS )," \
"DescriptorTable ( SRV(t0, numDescriptors = 2), visibility = SHADER_VISIBILITY_PIXEL )," \
"DescriptorTable ( Sampler(s0, numDescriptors = 2), visibility = SHADER_VISIBILITY_PIXEL )," \
"CBV(b0)"

// C++ code built root-signature
enum RootParameterIndex
{
    TextureSRVBase,
    TextureSamplerBase,
    ConstantBuffer,
    RootParameterCount
};

{
    D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
        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;

    CD3DX12_ROOT_PARAMETER rootParameters[RootParameterIndex::RootParameterCount] = {};
    rootParameters[RootParameterIndex::ConstantBuffer].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL);

    // Textures
    CD3DX12_DESCRIPTOR_RANGE textureRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0);
    CD3DX12_DESCRIPTOR_RANGE textureSamplerRange(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 2, 0);
    rootParameters[RootParameterIndex::TextureSRVBase].InitAsDescriptorTable(1, &textureRange, D3D12_SHADER_VISIBILITY_PIXEL);
    rootParameters[RootParameterIndex::TextureSamplerBase].InitAsDescriptorTable(1, &textureSamplerRange, D3D12_SHADER_VISIBILITY_PIXEL);

    // Create the root signature
    CD3DX12_ROOT_SIGNATURE_DESC rsigDesc = {};
    rsigDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags);

    ComPtr<ID3D12RootSignature> rootSignature;
    ComPtr<ID3DBlob> pSignature;
    ComPtr<ID3DBlob> pError;
    HRESULT hr = D3D12SerializeRootSignature(&rsigDesc, D3D_ROOT_SIGNATURE_VERSION_1, pSignature.GetAddressOf(), pError.GetAddressOf());
    if (SUCCEEDED(hr))
    {
        hr = device->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(),
            IID_PPV_ARGS(&rootSignature)
            );
    }
}

然后将其绑定:

commandList->SetGraphicsRootSignature(rootSignature.Get());
commandList->SetGraphicsRootDescriptorTable(RootParameterIndex::TextureSRVBase, texture1); // Second texture will be (texture1+1)
commandList->SetGraphicsRootDescriptorTable(RootParameterIndex::TextureSamplerBase, texture1Sampler); // Second sampler will be (texture1Sampler+1)

两个描述符表

第二个方法是将它们绑定为两个不同的描述符范围,以便可以绑定两个任意纹理:

// HLSL syntax
#define DualTextureRS \
"RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
"            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
"            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
"            DENY_HULL_SHADER_ROOT_ACCESS )," \
"DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL )," \
"DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )," \
"DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL )," \
"DescriptorTable ( Sampler(s1), visibility = SHADER_VISIBILITY_PIXEL )," \
"CBV(b0)"

// C++ code built root-signature
enum RootParameterIndex
{
    Texture1SRV,
    Texture1Sampler,
    Texture2SRV,
    Texture2Sampler,
    ConstantBuffer,
    RootParameterCount
};

{
    D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
        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;

    CD3DX12_ROOT_PARAMETER rootParameters[RootParameterIndex::RootParameterCount] = {};
    rootParameters[RootParameterIndex::ConstantBuffer].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL);

    // Texture 1
    CD3DX12_DESCRIPTOR_RANGE texture1Range(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
    CD3DX12_DESCRIPTOR_RANGE texture1SamplerRange(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
    rootParameters[RootParameterIndex::Texture1SRV].InitAsDescriptorTable(1, &texture1Range, D3D12_SHADER_VISIBILITY_PIXEL);
    rootParameters[RootParameterIndex::Texture1Sampler].InitAsDescriptorTable(1, &texture1SamplerRange, D3D12_SHADER_VISIBILITY_PIXEL);

    // Texture 2
    CD3DX12_DESCRIPTOR_RANGE texture2Range(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1);
    CD3DX12_DESCRIPTOR_RANGE texture2SamplerRange(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 1);
    rootParameters[RootParameterIndex::Texture2SRV].InitAsDescriptorTable(1, &texture2Range, D3D12_SHADER_VISIBILITY_PIXEL);
    rootParameters[RootParameterIndex::Texture2Sampler].InitAsDescriptorTable(1, &texture2SamplerRange, D3D12_SHADER_VISIBILITY_PIXEL);

    // Create the root signature
    CD3DX12_ROOT_SIGNATURE_DESC rsigDesc = {};
    rsigDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags);

    ComPtr<ID3D12RootSignature> rootSignature;
    ComPtr<ID3DBlob> pSignature;
    ComPtr<ID3DBlob> pError;
    HRESULT hr = D3D12SerializeRootSignature(&rsigDesc, D3D_ROOT_SIGNATURE_VERSION_1, pSignature.GetAddressOf(), pError.GetAddressOf());
    if (SUCCEEDED(hr))
    {
        hr = device->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(),
            IID_PPV_ARGS(&rootSignature)
            );
    }
}

然后将其绑定:

commandList->SetGraphicsRootSignature(rootSignature.Get());
commandList->SetGraphicsRootDescriptorTable(RootParameterIndex::Texture1SRV, texture1);
commandList->SetGraphicsRootDescriptorTable(RootParameterIndex::Texture1Sampler, texture1Sampler);
commandList->SetGraphicsRootDescriptorTable(RootParameterIndex::Texture2SRV, texture2);
commandList->SetGraphicsRootDescriptorTable(RootParameterIndex::Texture2Sampler, texture2Sampler);

第二种形式是我在DirectX Tool Kit中使用的形式,因为它更灵活。