directxhlsldirectx-12

Can texture arrays be a root descriptor in an hlsl root signature


So I am declaring my root descriptors in my shaders and I am coming across a scenario where I want to put a texture array as a root descriptor but HLSL is giving me this error: error X4614: RootSignature verification failed: A Shader is declaring a resource object as a texture using a register mapped to a root descriptor SRV (ShaderRegister=0, RegisterSpace=0). SRV or UAV root descriptors can only be Raw or Structured buffers. are texture arrays flat out not allowed as a root descriptor or if i wanted to do so I would have to have a single texture that I atlas myself?. Here is shader below that I am working on with this issue:

#define PI_F 3.14159265358979323846264338327950288419716939f

Texture2DArray screenTexArrays : register(t0);
SamplerState screenTexSampler : register(s0);

struct PixelInput
{
    float4 pos : SV_Position;
    float4 uvds : TEXCOORD0;    
};

cbuffer uniformsCB : register(b1)
{
    uint4 dwNumPlayers;
};

[RootSignature(
"RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT  |"\
"            DENY_HULL_SHADER_ROOT_ACCESS |"\
"            DENY_DOMAIN_SHADER_ROOT_ACCESS |"\
"            DENY_GEOMETRY_SHADER_ROOT_ACCESS ),"\
"            SRV( t0, space = 0, visibility=SHADER_VISIBILITY_PIXEL ),"\
"            RootConstants( num32BitConstants=4,"\
"                           b1,"\
"                           space = 0,"\
"                           visibility=SHADER_VISIBILITY_PIXEL ),"\
"            StaticSampler( s0,"\
"                           filter=FILTER_MIN_MAG_MIP_POINT,"\
"                           addressU = TEXTURE_ADDRESS_CLAMP,"\
"                           addressV = TEXTURE_ADDRESS_CLAMP,"\
"                           addressW = TEXTURE_ADDRESS_CLAMP,"\
"                           visibility = SHADER_VISIBILITY_PIXEL )"
)]

float4 main( PixelInput inPixel ) : SV_Target
{
    float fPlayerPerTheta = dwNumPlayers.x/(2.0f*PI_F);
    float2 vPixVecFromMiddle = normalize(inPixel.uvds.xy - float2(0.5f, 0.5f));
    float fCosThetaFromXAxis = dot(float2(1.f,0.f),vPixVecFromMiddle);
    float fPlayer = floor(acos(fCosThetaFromXAxis) * fPlayerPerTheta);

    return screenTexArrays.Sample(screenTexSampler,float3(inPixel.uvds.xy,fPlayer));
}

using this script to make a header file

@echo off
if not defined DevEnvDir (
    call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
)
if not defined DevEnvDir (
    call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
)

if "%Platform%" neq "x64" (
    echo ERROR: Platform is not "x64" - previous bat call failed.
    exit /b 1
)

set SHADERFLAGS=/WX /D__SHADER_TARGET_MAJOR=5 /D__SHADER_TARGET_MINOR=0

set POSTPROCESSPIXELSHADER=PostProcessAndCompositePixelShader.hlsl

fxc /nologo /T ps_5_0 /O3 %SHADERFLAGS% /Qstrip_reflect /Qstrip_debug /Qstrip_priv %POSTPROCESSPIXELSHADER% /Fh postProcessCompositeShader.h /Vn postProcessCompositeShaderBlob

I was going the root descriptor to avoid the 1 level of indirection that a descriptor table would add.


Solution

  • No, textures cant be put directly in the root signature. You have to create texture array descriptors in descriptor heaps, and have a descriptor table that points at it. (i.e. a root signature is an array of descriptor tables but sometimes the table can be replaced by the descriptor itself to avoid the indirection).

    These are the only types of descriptors supported in the root signature.

    • Shader resource views (SRVs) / unordered access views (UAVs) of buffer resources where format conversion is not required (untyped buffers). Some examples of untyped buffers that can be bound with root descriptors include StructuredBuffer<type>, RWStructuredBuffer<type>, ByteAddressBuffer and RWByteAddressBuffer. Typed buffers such as Buffer<uint> and Buffer<float2> can't.

    https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-descriptors-directly-in-the-root-signature