[D3D12] Shader translator vertex fetch
This commit is contained in:
parent
67f88ff59c
commit
3101930526
|
@ -73,6 +73,7 @@ void HlslShaderTranslator::StartTranslation() {
|
||||||
EmitSource(
|
EmitSource(
|
||||||
"cbuffer xe_system_constants : register(b0) {\n"
|
"cbuffer xe_system_constants : register(b0) {\n"
|
||||||
" float2 xe_viewport_inv_scale;\n"
|
" float2 xe_viewport_inv_scale;\n"
|
||||||
|
" uint xe_vertex_index_endian;\n"
|
||||||
" uint xe_textures_are_3d;\n"
|
" uint xe_textures_are_3d;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -94,6 +95,7 @@ void HlslShaderTranslator::StartTranslation() {
|
||||||
// for 8-in-16, 10 for 8-in-32 (a combination of 8-in-16 and 16-in-32), and
|
// for 8-in-16, 10 for 8-in-32 (a combination of 8-in-16 and 16-in-32), and
|
||||||
// 11 for 16-in-32. This means we can check bits 0 ^ 1 to see if we need to
|
// 11 for 16-in-32. This means we can check bits 0 ^ 1 to see if we need to
|
||||||
// do a 8-in-16 swap, and bit 1 to see if a 16-in-32 swap is needed.
|
// do a 8-in-16 swap, and bit 1 to see if a 16-in-32 swap is needed.
|
||||||
|
// Vertex element is a temporary integer value for fetches.
|
||||||
EmitSource(
|
EmitSource(
|
||||||
"cbuffer xe_vertex_fetch_constants : register(b18) {\n"
|
"cbuffer xe_vertex_fetch_constants : register(b18) {\n"
|
||||||
" uint2 xe_vertex_fetch[96];\n"
|
" uint2 xe_vertex_fetch[96];\n"
|
||||||
|
@ -122,9 +124,12 @@ void HlslShaderTranslator::StartTranslation() {
|
||||||
" float4 point_size : PSIZE;\n"
|
" float4 point_size : PSIZE;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"XeVertexShaderOutput main(uint xe_vertex_id : SV_VertexID) {\n"
|
"XeVertexShaderOutput main(uint xe_vertex_index_be : SV_VertexID) {\n"
|
||||||
" float4 xe_r[%u];\n"
|
" float4 xe_r[%u];\n"
|
||||||
" xe_r[0].r = float(xe_vertex_id);\n"
|
" uint xe_vertex_index =\n"
|
||||||
|
" XeSwap(xe_vertex_index_be, xe_vertex_index_endian);\n"
|
||||||
|
" uint4 xe_vertex_element;\n"
|
||||||
|
" xe_r[0].r = float(xe_vertex_index);\n"
|
||||||
" XeVertexShaderOutput xe_output;\n",
|
" XeVertexShaderOutput xe_output;\n",
|
||||||
kMaxInterpolators, register_count());
|
kMaxInterpolators, register_count());
|
||||||
// TODO(Triang3l): Reset interpolators to zero if really needed.
|
// TODO(Triang3l): Reset interpolators to zero if really needed.
|
||||||
|
@ -660,6 +665,244 @@ void HlslShaderTranslator::EmitStoreResult(const InstructionResult& result,
|
||||||
EmitSource(";\n");
|
EmitSource(";\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HlslShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
|
const ParsedVertexFetchInstruction& instr) {
|
||||||
|
EmitSourceDepth("// ");
|
||||||
|
instr.Disassemble(&source_);
|
||||||
|
|
||||||
|
if (instr.operand_count < 2 ||
|
||||||
|
instr.operand[1].storage_source !=
|
||||||
|
InstructionStorageSource::kVertexFetchConstant) {
|
||||||
|
assert_always();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool conditional_emitted = BeginPredicatedInstruction(
|
||||||
|
instr.is_predicated, instr.predicate_condition);
|
||||||
|
|
||||||
|
// Load the element from the virtual memory as uints and swap.
|
||||||
|
EmitLoadOperand(0, instr.operands[0]);
|
||||||
|
const char* load_swizzle;
|
||||||
|
const char* load_function_suffix;
|
||||||
|
switch (instr.attributes.data_format) {
|
||||||
|
case VertexFormat::k_16_16_16_16:
|
||||||
|
case VertexFormat::k_16_16_16_16_FLOAT:
|
||||||
|
case VertexFormat::k_32_32:
|
||||||
|
case VertexFormat::k_32_32_FLOAT:
|
||||||
|
load_swizzle = ".xy";
|
||||||
|
load_function_suffix = "2";
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32_32_FLOAT:
|
||||||
|
load_swizzle = ".xyz";
|
||||||
|
load_function_suffix = "3";
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32_32_32:
|
||||||
|
case VertexFormat::k_32_32_32_32_FLOAT:
|
||||||
|
load_swizzle = "";
|
||||||
|
load_function_suffix = "4";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
load_swizzle = ".x";
|
||||||
|
load_function_suffix = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
EmitSourceDepth("xe_vertex_element%s = XeSwap(xe_virtual_memory.Load%s(\n",
|
||||||
|
load_swizzle, load_function_suffix);
|
||||||
|
EmitSourceDepth(
|
||||||
|
" (xe_vertex_fetch[%u].x & 0x1FFFFFFCu) + uint(src0.x) * %u + %u),\n",
|
||||||
|
instr.operands[1].storage_index, instr.attributes.stride * 4,
|
||||||
|
instr.attributes.offset * 4);
|
||||||
|
EmitSourceDepth(" xe_vertex_fetch[%u].y);\n",
|
||||||
|
instr.operands[1].storage_index);
|
||||||
|
|
||||||
|
// Convert to the target format.
|
||||||
|
switch (instr.attributes.data_format) {
|
||||||
|
case VertexFormat::k_8_8_8_8:
|
||||||
|
EmitSourceDepth("xe_vertex_element = (xe_vertex_element.xxxx >>\n");
|
||||||
|
EmitSourceDepth(" uint4(0u, 8u, 16u, 24u)) & 255u;\n");
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv = float4(int4(xe_vertex_element << 24u) >> 24);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv = float4(xe_vertex_element);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv = max(xe_pv * (1.0 / 127.0), (-1.0).xxxx);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv *= 1.0 / 255.0;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_2_10_10_10:
|
||||||
|
EmitSourceDepth("xe_vertex_element = (xe_vertex_element.xxxx >>\n"
|
||||||
|
EmitSourceDepth(
|
||||||
|
" uint4(0u, 10u, 20u, 30u)) & uint4((1023u).xxx, 3u);\n");
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv = float4(int4(xe_vertex_element << uint4((22u).xxx, 3u))\n");
|
||||||
|
EmitSourceDepth(" >> int4((22).xxx, 3));\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv = float4(xe_vertex_element);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv = max(xe_pv * float4((1.0 / 511.0).xxx, 1.0), "
|
||||||
|
"(-1.0).xxxx);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv *= float4((1.0 / 1023.0).xxx, 1.0 / 3.0);\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_10_11_11:
|
||||||
|
EmitSourceDepth("xe_vertex_element.xyz = (xe_vertex_element.xxx >>\n"
|
||||||
|
EmitSourceDepth(
|
||||||
|
" uint3(0u, 11u, 22u)) & uint3(2047u, 2047u, 1023u);\n");
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv.xyz = float3(int3(xe_vertex_element.xyz <<\n");
|
||||||
|
EmitSourceDepth(" uint3(21u, 21u, 22u)) >> int3(21, 21, 22));\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv.xyz = float3(xe_vertex_element.xyz);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv.xyz = max(xe_pv.xyz *\n");
|
||||||
|
EmitSourceDepth(
|
||||||
|
" float3((1.0 / 1023.0).xx, 1.0 / 511.0), (-1.0).xxx);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv.xyz *= float3((1.0 / 2047.0).xx, 1.0 / 1023.0);\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EmitSourceDepth("xe_pv.w = 1.0;\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_11_11_10:
|
||||||
|
EmitSourceDepth("xe_vertex_element.xyz = (xe_vertex_element.xxx >>\n"
|
||||||
|
EmitSourceDepth(
|
||||||
|
" uint3(0u, 10u, 21u)) & uint3(1023u, 2047u, 2047u);\n");
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv.xyz = float3(int3(xe_vertex_element.xyz <<\n");
|
||||||
|
EmitSourceDepth(" uint3(22u, 21u, 21u)) >> int3(22, 21, 21));\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv.xyz = float3(xe_vertex_element.xyz);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv.xyz = max(xe_pv.xyz *\n");
|
||||||
|
EmitSourceDepth(
|
||||||
|
" float3(1.0 / 511.0, (1.0 / 1023.0).xx), (-1.0).xxx);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv.xyz *= float3(1.0 / 1023.0, (1.0 / 2047.0).xx);\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EmitSourceDepth("xe_pv.w = 1.0;\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_16_16:
|
||||||
|
EmitSourceDepth("xe_vertex_element.xy = (xe_vertex_element.xx >>\n");
|
||||||
|
EmitSourceDepth(" uint2(0u, 16u)) & 65535u;\n");
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv.xy = float2(int2(xe_vertex_element.xy << 16u) >> 16);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv.xy = float2(xe_vertex_element.xy);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv.xy = max(xe_pv.xy * (1.0 / 32767.0), (-1.0).xx);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv.xy *= 1.0 / 65535.0;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EmitSourceDepth("xe_pv.zw = float2(0.0, 1.0);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_16_16_16_16:
|
||||||
|
EmitSourceDepth("xe_vertex_element = (xe_vertex_element.xxxx >>\n");
|
||||||
|
EmitSourceDepth(" uint4(0u, 16u, 0u, 16u)) & 65535u;\n");
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv = float4(int4(xe_vertex_element << 16u) >> 16);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv = float4(xe_vertex_element);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_pv = max(xe_pv * (1.0 / 32767.0), (-1.0).xxxx);\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv *= 1.0 / 65535.0;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_16_16_FLOAT:
|
||||||
|
EmitSourceDepth("xe_vertex_element.xy = (xe_vertex_element.xx >>\n");
|
||||||
|
EmitSourceDepth(" uint2(0u, 16u)) & 65535u;\n");
|
||||||
|
EmitSourceDepth("xe_pv.xy = f16tof32(xe_vertex_element.xy);\n");
|
||||||
|
EmitSourceDepth("xe_pv.zw = float2(0.0, 1.0);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_16_16_16_16_FLOAT:
|
||||||
|
EmitSourceDepth("xe_vertex_element = (xe_vertex_element.xxxx >>\n");
|
||||||
|
EmitSourceDepth(" uint4(0u, 16u, 0u, 16u)) & 65535u;\n");
|
||||||
|
EmitSourceDepth("xe_pv = f16tof32(xe_vertex_element);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32:
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv.x = float(int(xe_vertex_element.x));\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv.x = float(xe_vertex_element.x);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
EmitSourceDepth("xe_pv.x *= asfloat(0x%Xu);\n",
|
||||||
|
instr.attributes.is_signed ? 0x30000000 : 0x2F800000);
|
||||||
|
}
|
||||||
|
EmitSourceDepth("xe_pv.yzw = float3(0.0, 0.0, 1.0);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32:
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv.xy = float2(int2(xe_vertex_element.xy));\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv.xy = float2(xe_vertex_element.xy);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
EmitSourceDepth("xe_pv.xy *= asfloat(0x%Xu);\n",
|
||||||
|
instr.attributes.is_signed ? 0x30000000 : 0x2F800000);
|
||||||
|
}
|
||||||
|
EmitSourceDepth("xe_pv.zw = float2(0.0, 1.0);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32_32_32:
|
||||||
|
if (instr.attributes.is_signed) {
|
||||||
|
EmitSourceDepth("xe_pv = float4(int4(xe_vertex_element));\n");
|
||||||
|
} else {
|
||||||
|
EmitSourceDepth("xe_pv = float4(xe_vertex_element);\n");
|
||||||
|
}
|
||||||
|
if (!instr.attributes.is_integer) {
|
||||||
|
EmitSourceDepth("xe_pv *= asfloat(0x%Xu);\n",
|
||||||
|
instr.attributes.is_signed ? 0x30000000 : 0x2F800000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_FLOAT:
|
||||||
|
EmitSourceDepth("xe_pv.x = asfloat(xe_vertex_element.x);\n");
|
||||||
|
EmitSourceDepth("xe_pv.yzw = float3(0.0, 0.0, 1.0);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32_FLOAT:
|
||||||
|
EmitSourceDepth("xe_pv.xy = asfloat(xe_vertex_element.xy);\n");
|
||||||
|
EmitSourceDepth("xe_pv.zw = float2(0.0, 1.0);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32_32_32_FLOAT:
|
||||||
|
EmitSourceDepth("xe_pv = asfloat(xe_vertex_element);\n");
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_32_32_32_FLOAT:
|
||||||
|
EmitSourceDepth("xe_pv.xyz = asfloat(xe_vertex_element.xyz);\n");
|
||||||
|
EmitSourceDepth("xe_pv.w = 1.0;\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitStoreResult(instr.result, false);
|
||||||
|
|
||||||
|
EndPredicatedInstruction(conditional_emitted);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t HlslShaderTranslator::AddSRVBinding(SRVType type,
|
uint32_t HlslShaderTranslator::AddSRVBinding(SRVType type,
|
||||||
uint32_t fetch_constant) {
|
uint32_t fetch_constant) {
|
||||||
for (uint32_t i = 0; i < srv_bindings_.size(); ++i) {
|
for (uint32_t i = 0; i < srv_bindings_.size(); ++i) {
|
||||||
|
|
|
@ -62,6 +62,9 @@ class HlslShaderTranslator : public ShaderTranslator {
|
||||||
void ProcessJumpInstruction(const ParsedJumpInstruction& instr) override;
|
void ProcessJumpInstruction(const ParsedJumpInstruction& instr) override;
|
||||||
void ProcessAllocInstruction(const ParsedAllocInstruction& instr) override;
|
void ProcessAllocInstruction(const ParsedAllocInstruction& instr) override;
|
||||||
|
|
||||||
|
void ProcessVertexFetchInstruction(
|
||||||
|
const ParsedVertexFetchInstruction& instr) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Indent();
|
void Indent();
|
||||||
void Unindent();
|
void Unindent();
|
||||||
|
|
Loading…
Reference in New Issue