Skip to content

Commit

Permalink
SPIR-V: Rewrite basic control-flow to use a while loop paired with a …
Browse files Browse the repository at this point in the history
…switch statement
  • Loading branch information
DrChat committed Sep 5, 2016
1 parent 52c75c8 commit 300d1c5
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 75 deletions.
2 changes: 1 addition & 1 deletion src/xenia/gpu/glsl_shader_translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ void GlslShaderTranslator::ProcessLabel(uint32_t cf_index) {
}
}

void GlslShaderTranslator::ProcessControlFlowNopInstruction() {
void GlslShaderTranslator::ProcessControlFlowNopInstruction(uint32_t cf_index) {
EmitSource("// cnop\n");
}

Expand Down
3 changes: 2 additions & 1 deletion src/xenia/gpu/glsl_shader_translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class GlslShaderTranslator : public ShaderTranslator {
public:
enum class Dialect {
kGL45,
kVulkan,
};

GlslShaderTranslator(Dialect dialect);
Expand All @@ -39,7 +40,7 @@ class GlslShaderTranslator : public ShaderTranslator {
std::vector<uint8_t> CompleteTranslation() override;

void ProcessLabel(uint32_t cf_index) override;
void ProcessControlFlowNopInstruction() override;
void ProcessControlFlowNopInstruction(uint32_t cf_index) override;
void ProcessControlFlowInstructionBegin(uint32_t cf_index) override;
void ProcessControlFlowInstructionEnd(uint32_t cf_index) override;
void ProcessExecInstructionBegin(const ParsedExecInstruction& instr) override;
Expand Down
21 changes: 12 additions & 9 deletions src/xenia/gpu/shader_translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ bool ShaderTranslator::TranslateBlocks() {
// This is what freedreno does.
uint32_t max_cf_dword_index = static_cast<uint32_t>(ucode_dword_count_);
std::set<uint32_t> label_addresses;
for (uint32_t i = 0, cf_index = 0; i < max_cf_dword_index; i += 3) {
std::vector<ControlFlowInstruction> cf_instructions;
for (uint32_t i = 0; i < max_cf_dword_index; i += 3) {
ControlFlowInstruction cf_a;
ControlFlowInstruction cf_b;
UnpackControlFlowInstructions(ucode_dwords_ + i, &cf_a, &cf_b);
Expand All @@ -383,12 +384,12 @@ bool ShaderTranslator::TranslateBlocks() {
AddControlFlowTargetLabel(cf_a, &label_addresses);
AddControlFlowTargetLabel(cf_b, &label_addresses);

PreProcessControlFlowInstruction(cf_index, cf_a);
++cf_index;
PreProcessControlFlowInstruction(cf_index, cf_b);
++cf_index;
cf_instructions.push_back(cf_a);
cf_instructions.push_back(cf_b);
}

PreProcessControlFlowInstructions(cf_instructions);

// Translate all instructions.
for (uint32_t i = 0, cf_index = 0; i < max_cf_dword_index; i += 3) {
ControlFlowInstruction cf_a;
Expand Down Expand Up @@ -491,7 +492,7 @@ void ShaderTranslator::TranslateControlFlowNop(
const ControlFlowInstruction& cf) {
ucode_disasm_buffer_.Append(" cnop\n");

ProcessControlFlowNopInstruction();
ProcessControlFlowNopInstruction(cf_index_);
}

void ShaderTranslator::TranslateControlFlowExec(
Expand Down Expand Up @@ -1065,7 +1066,9 @@ void ParseAluInstructionOperand(const AluInstruction& op, int i,
uint32_t b = ((swizzle >> 0) + 0) & 0x3;
out_op->components[0] = GetSwizzleFromComponentIndex(a);
out_op->components[1] = GetSwizzleFromComponentIndex(b);
} else {
} else if (swizzle_component_count == 3) {
assert_always();
} else if (swizzle_component_count == 4) {
for (int j = 0; j < swizzle_component_count; ++j, swizzle >>= 2) {
out_op->components[j] = GetSwizzleFromComponentIndex((swizzle + j) & 0x3);
}
Expand Down Expand Up @@ -1316,8 +1319,8 @@ void ShaderTranslator::ParseAluScalarInstruction(
&i.operands[0]);
} else {
uint32_t src3_swizzle = op.src_swizzle(3);
uint32_t swiz_a = ((src3_swizzle >> 6) - 1) & 0x3;
uint32_t swiz_b = (src3_swizzle & 0x3);
uint32_t swiz_a = ((src3_swizzle >> 6) + 3) & 0x3;
uint32_t swiz_b = ((src3_swizzle >> 0) + 0) & 0x3;
uint32_t reg2 = (static_cast<int>(op.scalar_opcode()) & 1) |
(src3_swizzle & 0x3C) | (op.src_is_temp(3) << 1);
int const_slot = (op.src_is_temp(1) || op.src_is_temp(2)) ? 1 : 0;
Expand Down
6 changes: 3 additions & 3 deletions src/xenia/gpu/shader_translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ class ShaderTranslator {
}

// Pre-process a control-flow instruction before anything else.
virtual void PreProcessControlFlowInstruction(
uint32_t cf_index, const ucode::ControlFlowInstruction& instr) {}
virtual void PreProcessControlFlowInstructions(
std::vector<ucode::ControlFlowInstruction> instrs) {}

// Handles translation for control flow label addresses.
// This is triggered once for each label required (due to control flow
// operations) before any of the instructions within the target exec.
virtual void ProcessLabel(uint32_t cf_index) {}

// Handles translation for control flow nop instructions.
virtual void ProcessControlFlowNopInstruction() {}
virtual void ProcessControlFlowNopInstruction(uint32_t cf_index) {}
// Handles the start of a control flow instruction at the given address.
virtual void ProcessControlFlowInstructionBegin(uint32_t cf_index) {}
// Handles the end of a control flow instruction that began at the given
Expand Down
Loading

0 comments on commit 300d1c5

Please sign in to comment.