Hello,
I have a few short shaders in assembler code and I would like to understand what it really does. Or better, I know what it does but I am not able to get it work. So please, could someone help?
I need to get the alpha value of the pixels written by pixel shader. This is the pixel shader:
Microsoft (R) Direct3D Shader Compiler 9.30.9200.16384
Copyright (C) Microsoft Corporation 2002-2011. All rights reserved.
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
///
// Note: shader requires additional functionality:
// Minimum-precision data types
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION 0 xyzw 0 POS float
// TEXCOORD 0 xy 1 NONE float xy
// TEXCOORD 1 xyzw 2 NONE min2_8f xyzw
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_TARGET 0 xyzw 0 TARGET min2_8f xyzw
//
//
// Sampler/Resource to DX9 shader sampler mappings:
//
// Target Sampler Source Sampler Source Resource
// -------------- --------------- ----------------
// s0 s0 t0
//
//
// Level9 shader bytecode:
//
ps_2_0
dcl t0.xy
dcl t1 {min2_8f}
dcl_2d s0
texld r0 {min2_8f}, t0, s0
mul r0.xyz, r0 {min2_8f}, t1 {min2_8f}
mov r0.w, t1.w {min2_8f}
mov oC0 {min2_8f}, r0
// approximately 4 instruction slots used (1 texture, 3 arithmetic)
ps_4_0
dcl_globalFlags refactoringAllowed | enableMinimumPrecision
dcl_sampler s0, mode_default
dcl_resource_texture2d (float,float,float,float) t0
dcl_input_ps linear v1.xy
dcl_input_ps linear v2.xyzw {min2_8f}
dcl_output o0.xyzw {min2_8f}
dcl_temps 1
sample r0.xyzw {min2_8f}, v1.xyxx, t0.xyzw, s0
mul r0.xyz, r0.xyzx {min2_8f as def32}, v2.xyzx {min2_8f as def32}
mov r0.w, v2.w {min2_8f as def32}
mov o0.xyzw {min2_8f}, r0.xyzw {def32 as min2_8f}
ret
// Approximately 0 instruction slots used
As I understand correctly, The output alpha value is stored in o0.w which is just copied from the input (v2.w which the second input TEXCOORD.w). And there is a vertex shader which should compute the alpha and put it on its output:
Microsoft (R) Direct3D Shader Compiler 9.30.9200.16384
Copyright (C) Microsoft Corporation 2002-2011. All rights reserved.
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
///
// Note: shader requires additional functionality:
// Minimum-precision data types
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// POSITION 0 xy 0 NONE float xy
// TEXCOORD 0 xy 1 NONE int x
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION 0 xyzw 0 POS float xyzw
// TEXCOORD 0 xy 1 NONE float xy
// TEXCOORD 1 xyzw 2 NONE min2_8f xyzw
//
//
// Constant buffer to DX9 shader constant mappings:
//
// Target Reg Buffer Start Reg # of Regs Data Conversion
// ---------- ------- --------- --------- ----------------------
// c0 cb1 0 250 ( FLT, FLT, FLT, FLT)
// c251 cb0 0 1 ( FLT, FLT, FLT, FLT)
//
//
// Runtime generated constant mappings:
//
// Target Reg Constant Description
// ---------- --------------------------------------------------
// c250 Vertex Shader position offset
//
//
// Level9 shader bytecode:
//
vs_2_0
def c252, 0.5, 1, 0, 0
dcl_texcoord v0
dcl_texcoord1 v1
mova a0.x, v1.x
mul r0.xy, v0, c0[a0.x]
add r0.x, r0.y, r0.x
add oT0.x, r0.x, c0[a0.x].z
mul r0.xy, v0, c1[a0.x]
add r0.x, r0.y, r0.x
add oT0.y, r0.x, c1[a0.x].z
mov oT1 {min2_8f}, c2[a0.x]
mad r0.xy, v0, c251.xzzw, c251.ywzw
add oPos.xy, r0, c250
mov oPos.zw, c252.xyxy
// approximately 11 instruction slots used
vs_4_0
dcl_globalFlags refactoringAllowed | enableMinimumPrecision
dcl_constantbuffer cb0[1], immediateIndexed
dcl_constantbuffer cb1[250], dynamicIndexed
dcl_input v0.xy
dcl_input v1.x
dcl_output_siv o0.xyzw, position
dcl_output o1.xy
dcl_output o2.xyzw {min2_8f}
dcl_temps 1
mad o0.xy, v0.xyxx, cb0[0].xzxx, cb0[0].ywyy
mov o0.zw, l(0,0,0.500000,1.000000)
mov r0.x, v1.x
dp2 r0.y, v0.xyxx, cb1[r0.x + 0].xyxx
add o1.x, r0.y, cb1[r0.x + 0].z
iadd r0.xy, v1.xxxx, l(1, 2, 0, 0)
dp2 r0.z, v0.xyxx, cb1[r0.x + 0].xyxx
add o1.y, r0.z, cb1[r0.x + 0].z
mov o2.xyzw {min2_8f}, cb1[r0.y + 0].xyzw {def32 as min2_8f}
ret
// Approximately 0 instruction slots used
From this code, I can understand that the requested value is stored at cb1[r0.y+0].w which should be just a value in the constant buffer #2. And index to constant buffer #2 is stored at offset pointed by r0.y. But I am not able to compute this offset (which should just be value in constant buffer #1). I probably miss something, because if I read the constant buffers by
ID3D11Buffer* constantBuffers[2];
This->VSGetConstantBuffers(0, 2, constantBuffers);
the requested value is not there. The constantBuffers[0] is 16 bytes long, constantBuffers[1] is 4000 bytes long which correspond to the data written in shader disassembly.
I know I have a little bit non-standard task. But I would really appreciate any help with finding where the requested value (alpha component of pixel shader output) is stored. Thanks in advance!