mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[D3D12] Shader translator scalar ALU
This commit is contained in:
parent
40806c1b67
commit
60706077a3
|
|
@ -71,6 +71,8 @@ void HlslShaderTranslator::Unindent() {
|
||||||
void HlslShaderTranslator::StartTranslation() {
|
void HlslShaderTranslator::StartTranslation() {
|
||||||
// Common things.
|
// Common things.
|
||||||
EmitSource(
|
EmitSource(
|
||||||
|
"#define XE_FLT_MAX 3.402823466e+38\n"
|
||||||
|
"\n"
|
||||||
"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_vertex_index_endian;\n"
|
||||||
|
|
@ -1058,5 +1060,216 @@ void HlslShaderTranslator::ProcessVectorAluInstruction(
|
||||||
EndPredicatedInstruction(conditional_emitted);
|
EndPredicatedInstruction(conditional_emitted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HlslShaderTranslator::ProcessScalarAluInstruction(
|
||||||
|
const ParsedAluInstruction& instr) {
|
||||||
|
bool conditional_emitted = BeginPredicatedInstruction(
|
||||||
|
instr.is_predicated, instr.predicate_condition);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < instr.operand_count; ++i) {
|
||||||
|
EmitLoadOperand(i, instr.operands[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (instr.scalar_opcode) {
|
||||||
|
case AluScalarOpcode::kAdds:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x + xe_src0.y;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kAddsPrev:
|
||||||
|
EmitSourceDepth("xe_ps += xe_src0.x;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMuls:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x * xe_src0.y;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMulsPrev:
|
||||||
|
EmitSourceDepth("xe_ps *= xe_src0.x;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMulsPrev2:
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_ps = (xe_ps == -XE_FLT_MAX || (isinf(xe_ps) && xe_ps < 0.0)\n");
|
||||||
|
EmitSourceDepth(
|
||||||
|
" || isnan(xe_ps) || xe_src0.y <= 0.0 || isnan(xe_src0.y)) ?\n");
|
||||||
|
EmitSourceDepth(" -XE_FLT_MAX : xe_src0.x * xe_ps;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMaxs:
|
||||||
|
EmitSourceDepth("xe_ps = max(xe_src0.x, xe_src0.y);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMins:
|
||||||
|
EmitSourceDepth("xe_ps = max(xe_src0.x, xe_src0.y);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSeqs:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x == 0.0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSgts:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x > 0.0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSges:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x >= 0.0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSnes:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x != 0.0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kFrcs:
|
||||||
|
EmitSourceDepth("xe_ps = frac(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kTruncs:
|
||||||
|
EmitSourceDepth("xe_ps = trunc(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kFloors:
|
||||||
|
EmitSourceDepth("xe_ps = floor(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kExp:
|
||||||
|
EmitSourceDepth("xe_ps = exp2(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kLogc:
|
||||||
|
EmitSourceDepth("xe_ps = log2(xe_src0.x);\n");
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_ps = (isinf(xe_ps) && xe_ps < 0.0) ? -XE_FLT_MAX : ps;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kLog:
|
||||||
|
EmitSourceDepth("xe_ps = log2(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRcpc:
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_ps = clamp(rcp(xe_src0.x), -XE_FLT_MAX, XE_FLT_MAX);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRcpf:
|
||||||
|
EmitSourceDepth("xe_ps = rcp(xe_src0.x);\n");
|
||||||
|
EmitSourceDepth("xe_ps *= float(!isinf(xe_ps));\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRcp:
|
||||||
|
EmitSourceDepth("xe_ps = rcp(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRsqc:
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_ps = clamp(rsqrt(xe_src0.x), -XE_FLT_MAX, XE_FLT_MAX);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRsqf:
|
||||||
|
EmitSourceDepth("xe_ps = rsqrt(xe_src0.x);\n");
|
||||||
|
EmitSourceDepth("xe_ps *= float(!isinf(xe_ps));\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRsq:
|
||||||
|
EmitSourceDepth("xe_ps = rsqrt(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMaxAs:
|
||||||
|
EmitSourceDepth("xe_a0 = clamp(int(round(xe_src0.x)), -256, 255);\n");
|
||||||
|
EmitSourceDepth("xe_ps = max(xe_src0.x, xe_src0.y);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMaxAf:
|
||||||
|
EmitSourceDepth("xe_a0 = clamp(int(floor(xe_src0.x)), -256, 255);\n");
|
||||||
|
EmitSourceDepth("xe_ps = max(xe_src0.x, xe_src0.y);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSubs:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x - xe_src0.y;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSubsPrev:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x - xe_ps;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpEq:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_p0 = xe_src0.x == 0.0;\n");
|
||||||
|
EmitSourceDepth("xe_ps = float(!xe_p0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpNe:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_p0 = xe_src0.x != 0.0;\n");
|
||||||
|
EmitSourceDepth("xe_ps = float(!xe_p0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpGt:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_p0 = xe_src0.x > 0.0;\n");
|
||||||
|
EmitSourceDepth("xe_ps = float(!xe_p0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpGe:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_p0 = xe_src0.x >= 0.0;\n");
|
||||||
|
EmitSourceDepth("xe_ps = float(!xe_p0);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpInv:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_p0 = xe_src0.x == 1.0;\n");
|
||||||
|
EmitSourceDepth(
|
||||||
|
"xe_ps = float(!xe_p0) * (xe_src0.x == 0.0 ? 1.0 : xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpPop:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_ps = max(xe_src0.x - 1.0, 0.0);\n");
|
||||||
|
EmitSourceDepth("xe_p0 = xe_ps == 0.0;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpClr:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_ps = false;\n");
|
||||||
|
EmitSourceDepth("xe_p0 = XE_FLT_MAX;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSetpRstr:
|
||||||
|
cf_exec_pred_ = false;
|
||||||
|
EmitSourceDepth("xe_p0 = src0.x == 0.0;\n");
|
||||||
|
EmitSourceDepth("xe_ps = src0.x;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kKillsEq:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x == 0.0);\n");
|
||||||
|
EmitSourceDepth("clip(-xe_ps);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kKillsGt:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x > 0.0);\n");
|
||||||
|
EmitSourceDepth("clip(-xe_ps);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kKillsGe:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x >= 0.0);\n");
|
||||||
|
EmitSourceDepth("clip(-xe_ps);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kKillsNe:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x != 0.0);\n");
|
||||||
|
EmitSourceDepth("clip(-xe_ps);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kKillsOne:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x == 1.0);\n");
|
||||||
|
EmitSourceDepth("clip(-xe_ps);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSqrt:
|
||||||
|
EmitSourceDepth("xe_ps = float(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kMulsc0:
|
||||||
|
case AluScalarOpcode::kMulsc1:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x * xe_src1.x;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kAddsc0:
|
||||||
|
case AluScalarOpcode::kAddsc1:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x + xe_src1.x;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSubsc0:
|
||||||
|
case AluScalarOpcode::kSubsc1:
|
||||||
|
EmitSourceDepth("xe_ps = xe_src0.x - xe_src1.x;\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kSin:
|
||||||
|
EmitSourceDepth("xe_ps = sin(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kCos:
|
||||||
|
EmitSourceDepth("xe_ps = cos(xe_src0.x);\n");
|
||||||
|
break;
|
||||||
|
case AluScalarOpcode::kRetainPrev:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitStoreResult(instr.result, true);
|
||||||
|
|
||||||
|
EndPredicatedInstruction(conditional_emitted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HlslShaderTranslator::ProcessAluInstruction(
|
||||||
|
const ParsedAluInstruction& instr) {
|
||||||
|
EmitSourceDepth("// ");
|
||||||
|
instr.Disassemble(&source_);
|
||||||
|
|
||||||
|
switch (instr.type) {
|
||||||
|
case ParsedAluInstruction::Type::kNop:
|
||||||
|
break;
|
||||||
|
case ParsedAluInstruction::Type::kVector:
|
||||||
|
ProcessVectorAluInstruction(instr);
|
||||||
|
break;
|
||||||
|
case ParsedAluInstruction::Type::kScalar:
|
||||||
|
ProcessScalarAluInstruction(instr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue