AMD Radeon™ GPU Analyzer
Radeon GPU Analyzer 是一款用于 DirectX®、Vulkan®、SPIR-V™、OpenGL® 和 OpenCL™ 的离线编译器和性能分析工具。
DirectX®12 需要完整的管线状态定义才能编译管线。这包括定位管线中的所有着色器、定义根签名,以及(对于图形管线)定义图形管线状态的一个子集。由于需要在早期准备完整的图形或计算管线元素,DirectX12 着色器的离线编译过程有些繁琐。这种方法可能会很麻烦,尤其是在用户希望单独编译单个着色器的情况下。
RGA v2.9.1 通过允许您编译单个 D3D12 着色器,简化了着色器编译体验。当提供不完整的 DirectX®12 管线时,RGA v2.9.1 会为您自动生成管线中缺失的元素。这些元素可以是根签名、图形管线状态子集,甚至是管线中的着色器。此功能基本上使您要编译的单个着色器以外的任何输入都成为可选的。
考虑以下像素着色器
struct VsOutput{ float4 pos : SV_Position; float2 tex_coord : TEXCOORD0;};
Texture2D<float4> texture0 : register(t0);SamplerState sampler0 : register(s0);
float4 PsMain(VsOutput i) : SV_Target{ return texture0.Sample(sampler0, i.tex_coord);}正常情况下,要编译此像素着色器,您需要定义完整的图形管线状态:附带的顶点着色器、根签名和图形管线状态的子集。
使用 RGA v2.9.1,您可以单独编译该像素着色器。在命令行调用方面,RGA 的使用方式没有改变。您将像以前一样使用相同的 RGA DirectX®12 命令,同时省略 D3D12 图形管线中缺失的部分。在下面的示例中,该像素着色器正在为 AMD Radeon RX 7000 系列(RDNA 3 架构)GPU 编译
rga.exe -s dx12 -c gfx1100 --ps "dxc\single_shaders\classic_ps.hlsl" --ps-entry "PsMain" --all-model 6_0 --autogen-dir "C:\RGA-2.9.1\Generated" --isa "C:\RGA-2.9.1\Isa\Out.isa"这将产生以下输出
Building for gfx1100...Auto-generating root signature using reflection into C:\RGA-2.9.1\Generated\rga_autogen_20240415_174858_.rootsig ... success.Auto-generating graphics pipeline state using reflection into C:\RGA-2.9.1\Generated\rga_autogen_20240415_174858_.gpso ... success.Auto-generating vertex shader using reflection into C:\RGA-2.9.1\Generated\rga_autogen_20240415_174858_vs.hlsl ... success.Performing front-end compilation of vertex shader through DXC...Front-end compilation success.Performing front-end compilation of pixel shader through DXC...Front-end compilation success.Performing front-end compilation of root signature through DXC...Front-end compilation success.Compiling graphics pipeline...Extracting vertex shader disassembly...vertex shader disassembly extracted successfully.Extracting pixel shader disassembly...pixel shader disassembly extracted successfully.succeeded.RGA 将检测到缺失的图形管线部分并通过反射自动生成它们。
引入了一个专用的命令行参数 `--autogen-dir <folder>`,允许您指定一个用于存储自动生成文件的文件夹。默认情况下,这些文件会在编译后删除,除非另有说明。
在我们的示例中,RGA 将自动生成一个顶点着色器、根签名的文本表示以及一个包含图形管线状态子集的 .gpso 文件。根签名的文本表示使您可以调查编译问题。它还允许您轻松地修改自动生成的文件并重新编译。
RGA 使用反射来确保它自动生成的所有文件在顶点属性(例如,顶点格式、要插值的顶点属性、渲染目标)和资源绑定(着色器使用的缓冲区和纹理)方面都与输入的像素着色器匹配。
自动生成的 HLSL 顶点着色器
// Auto-generated with Radeon GPU Analyzer (RGA).
struct VsInput{ float4 attribute0: POSITION0;};
struct VsOutput{ float4 attribute0: SV_POSITION; float2 attribute1: TEXCOORD0;};
void main(VsInput input, out VsOutput output){ float4 result = float4(0.0, 0.0, 0.0, 0.0); result += float4(input.attribute0.xyzw); output.attribute0 = float4(result.xyzw); output.attribute1 = float2(result.xy);}自动生成的基于文本的根签名
// Auto-generated with Radeon GPU Analyzer (RGA).
#define RGA_ROOT_SIGNATURE \ "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | DENY_HULL_SHADER_ROOT_ACCESS " \ "| DENY_DOMAIN_SHADER_ROOT_ACCESS | DENY_GEOMETRY_SHADER_ROOT_ACCESS ), " \ "DescriptorTable(Sampler(s0), visibility=SHADER_VISIBILITY_PIXEL), " \ "DescriptorTable(SRV(t0), visibility=SHADER_VISIBILITY_PIXEL)"包含图形管线状态对象的 .gpso 文件
# Auto-generated with Radeon GPU Analyzer (RGA).
# schemaVersion1.0
# InputLayoutNumElements (the number of D3D12_INPUT_ELEMENT_DESC elements in the D3D12_INPUT_LAYOUT_DESC structure - must match the following "InputLayout" section)1
# InputLayout ( {SemanticName, SemanticIndex, Format, InputSlot, AlignedByteOffset, InputSlotClass, InstanceDataStepRate } ) { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
# PrimitiveTopologyType (the D3D12_PRIMITIVE_TOPOLOGY_TYPE value to be used when creating the PSO)D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE
# NumRenderTargets (the number of formats in the upcoming RTVFormats section)1
# RTVFormats (an array of DXGI_FORMAT-typed values for the render target formats - the number of items in the array should match the above NumRenderTargets section){ DXGI_FORMAT_R8G8B8A8_UNORM }一旦 D3D12 图形管线中缺失的部分被自动生成,RGA 就会调用 AMD Shader 编译器,并将像素着色器以及这些文件一起传递以编译整个管线。

成功编译后,您将获得相应的像素着色器反汇编
; D3D12 Shader Hash 0x30d77570b6e44f6c49553fb9ca32e72d; API PSO Hash 0xd5b60f61c55df988; Driver Internal Pipeline Hash 0xf9f385166a76e0d7; -------- Disassembly --------------------shader main asic(GFX11) type(PS) sgpr_count(14) vgpr_count(8) wave_size(64) // s_ps_state in s0
s_version UC_VERSION_GFX11 | UC_VERSION_W64_BIT // 000000000000: B0802006 s_set_inst_prefetch_distance 0x0003 // 000000000004: BF840003 s_mov_b32 m0, s4 // 000000000008: BEFD0004 s_mov_b64 s[12:13], exec // 00000000000C: BE8C017E s_wqm_b64 exec, exec // 000000000010: BEFE1D7E s_getpc_b64 s[0:1] // 000000000014: BE804780 s_waitcnt_depctr depctr_vm_vsrc(0) & depctr_va_vdst(0) // 000000000018: BF880F83 lds_param_load v2, attr0.x wait_vdst:0 // 00000000001C: CE000002 lds_param_load v3, attr0.y wait_vdst:0 // 000000000020: CE000103 s_mov_b32 s4, s3 // 000000000024: BE840003 s_mov_b32 s5, s1 // 000000000028: BE850001 s_mov_b32 s0, s2 // 00000000002C: BE800002 s_load_b256 s[4:11], s[4:5], null // 000000000030: F40C0102 F8000000 s_load_b128 s[0:3], s[0:1], null // 000000000038: F4080000 F8000000 v_interp_p10_f32 v4, v2, v0, v2 wait_exp:1 // 000000000040: CD000104 040A0102 v_interp_p10_f32 v0, v3, v0, v3 wait_exp:0 // 000000000048: CD000000 040E0103 s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2) // 000000000050: BF870112 v_interp_p2_f32 v2, v2, v1, v4 wait_exp:7 // 000000000054: CD010702 04120302 v_interp_p2_f32 v0, v3, v1, v0 wait_exp:7 // 00000000005C: CD010700 04020303 s_and_b64 exec, exec, s[12:13] // 000000000064: 8BFE0C7E s_waitcnt lgkmcnt(0) // 000000000068: BF89FC07 image_sample v[0:3], [v2,v0], s[4:11], s[0:3] dmask:0xf dim:SQ_RSRC_IMG_2D // 00000000006C: F06C0F05 00010002 00000000 s_waitcnt vmcnt(0) // 000000000078: BF8903F7 v_cvt_pk_rtz_f16_f32 v0, v0, v1 // 00000000007C: 5E000300 v_cvt_pk_rtz_f16_f32 v2, v2, v3 // 000000000080: 5E040702 s_mov_b64 exec, s[12:13] // 000000000084: BEFE010C exp mrt0, v0, v2, off, off done // 000000000088: F8000803 00000200 s_endpgm // 000000000090: BFB00000 s_code_end // 000000000094: BF9F0000 s_code_end // 000000000098: BF9F0000 s_code_end // 00000000009C: BF9F0000 s_code_end // 0000000000A0: BF9F0000end总而言之,RGA v2.9.1 简化了 DirectX®12 的离线着色器编译和分析,并使用户能够更轻松地快速检查单个着色器。
您可以在 GitHub 上找到有关 RGA 的更多信息,包括发布二进制文件的链接,并在我们的 产品页面 上查看完整的发行说明列表。
您的反馈对我们来说非常宝贵,并有助于推动 RGA 的路线图。对于功能请求或反馈,请 在 GitHub 上联系我们!