Loops in shaders (no TDRs! woo!).
This commit is contained in:
parent
367ca09f1d
commit
ed0b97813a
Binary file not shown.
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 67 KiB |
|
@ -291,8 +291,11 @@ void main() {
|
||||||
EmitSource(" bool p0 = false;\n");
|
EmitSource(" bool p0 = false;\n");
|
||||||
// Address register when using absolute addressing.
|
// Address register when using absolute addressing.
|
||||||
EmitSource(" int a0 = 0;\n");
|
EmitSource(" int a0 = 0;\n");
|
||||||
// TODO(benvanik): remove when loops are implemented.
|
// Loop index stack - .x is the active loop, shifted right to yzw on push.
|
||||||
EmitSource(" int aL = 0;\n"); // Hack!
|
EmitSource(" ivec4 aL = ivec4(0);\n");
|
||||||
|
// Loop counter stack, .x is the active loop.
|
||||||
|
// Represents number of times remaining to loop.
|
||||||
|
EmitSource(" ivec4 loop_count = ivec4(0);\n");
|
||||||
// Temps for source register values.
|
// Temps for source register values.
|
||||||
EmitSource(" vec4 src0;\n");
|
EmitSource(" vec4 src0;\n");
|
||||||
EmitSource(" vec4 src1;\n");
|
EmitSource(" vec4 src1;\n");
|
||||||
|
@ -378,7 +381,32 @@ void GlslShaderTranslator::ProcessLoopStartInstruction(
|
||||||
EmitSource("// ");
|
EmitSource("// ");
|
||||||
instr.Disassemble(&source_);
|
instr.Disassemble(&source_);
|
||||||
|
|
||||||
EmitUnimplementedTranslationError();
|
// Setup counter.
|
||||||
|
EmitSourceDepth(
|
||||||
|
"loop_count = ivec4(state.loop_consts[%u].x & 0xFF, "
|
||||||
|
"loop_count.x, loop_count.y, loop_count.z);\n",
|
||||||
|
instr.loop_constant_index);
|
||||||
|
|
||||||
|
// Setup relative indexing.
|
||||||
|
if (instr.is_repeat) {
|
||||||
|
// Reuse the current loop index.
|
||||||
|
EmitSourceDepth("aL = ivec4(aL.x, aL.x, aL.y, aL.z);\n");
|
||||||
|
} else {
|
||||||
|
// Push new loop starting index.
|
||||||
|
EmitSourceDepth(
|
||||||
|
"aL = ivec4((state.loop_consts[%u] >> 8) & 0xFF, aL.x, aL.y, aL.z);\n",
|
||||||
|
instr.loop_constant_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick skip loop if zero count.
|
||||||
|
EmitSourceDepth("if (loop_count.x == 0) {\n");
|
||||||
|
EmitSourceDepth(" pc = 0x%X; // Skip loop to L%d\n",
|
||||||
|
instr.loop_skip_address, instr.loop_skip_address);
|
||||||
|
EmitSourceDepth("} else {\n");
|
||||||
|
EmitSourceDepth(" pc = 0x%X; // Fallthrough to loop body L%d\n",
|
||||||
|
instr.dword_index + 1, instr.dword_index + 1);
|
||||||
|
EmitSourceDepth("}\n");
|
||||||
|
cf_wrote_pc_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlslShaderTranslator::ProcessLoopEndInstruction(
|
void GlslShaderTranslator::ProcessLoopEndInstruction(
|
||||||
|
@ -386,7 +414,38 @@ void GlslShaderTranslator::ProcessLoopEndInstruction(
|
||||||
EmitSource("// ");
|
EmitSource("// ");
|
||||||
instr.Disassemble(&source_);
|
instr.Disassemble(&source_);
|
||||||
|
|
||||||
EmitUnimplementedTranslationError();
|
// Decrement loop counter, and if we are done break out.
|
||||||
|
EmitSourceDepth("if (--loop_count.x == 0");
|
||||||
|
if (instr.is_predicated_break) {
|
||||||
|
// If the predicate condition is met we 'break;' out of the loop.
|
||||||
|
// Need to restore stack and fall through to the next cf.
|
||||||
|
EmitSource(" || %cp0) {\n", instr.predicate_condition ? ' ' : '!');
|
||||||
|
} else {
|
||||||
|
EmitSource(") {\n");
|
||||||
|
}
|
||||||
|
Indent();
|
||||||
|
|
||||||
|
// Loop completed - pop and fall through to next cf.
|
||||||
|
EmitSourceDepth(
|
||||||
|
"loop_count = ivec4(loop_count.y, loop_count.z, loop_count.w, 0);\n");
|
||||||
|
EmitSourceDepth("aL = ivec4(aL.y, aL.z, aL.w, 0);\n");
|
||||||
|
uint32_t next_address = instr.dword_index + 1;
|
||||||
|
EmitSourceDepth("pc = 0x%X; // Exit loop to L%d\n", instr.dword_index + 1,
|
||||||
|
instr.dword_index + 1);
|
||||||
|
|
||||||
|
Unindent();
|
||||||
|
EmitSourceDepth("} else {\n");
|
||||||
|
Indent();
|
||||||
|
|
||||||
|
// Still looping. Adjust index and jump back to body.
|
||||||
|
EmitSourceDepth("aL.x += (state.loop_consts[%u] << 8) >> 24;\n",
|
||||||
|
instr.loop_constant_index);
|
||||||
|
EmitSourceDepth("pc = 0x%X; // Loop back to body L%d\n",
|
||||||
|
instr.loop_body_address, instr.loop_body_address);
|
||||||
|
|
||||||
|
Unindent();
|
||||||
|
EmitSourceDepth("}\n");
|
||||||
|
cf_wrote_pc_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlslShaderTranslator::ProcessCallInstruction(
|
void GlslShaderTranslator::ProcessCallInstruction(
|
||||||
|
@ -657,9 +716,9 @@ void GlslShaderTranslator::EmitLoadOperand(size_t i,
|
||||||
break;
|
break;
|
||||||
case InstructionStorageAddressingMode::kAddressRelative:
|
case InstructionStorageAddressingMode::kAddressRelative:
|
||||||
if (storage_index_offset) {
|
if (storage_index_offset) {
|
||||||
EmitSource("[%d+%d+aL]", storage_index_offset, op.storage_index);
|
EmitSource("[%d+%d+aL.x]", storage_index_offset, op.storage_index);
|
||||||
} else {
|
} else {
|
||||||
EmitSource("[%d+aL]", op.storage_index);
|
EmitSource("[%d+aL.x]", op.storage_index);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -736,7 +795,7 @@ void GlslShaderTranslator::EmitStoreResult(const InstructionResult& result,
|
||||||
EmitSource("[%d+a0]", result.storage_index);
|
EmitSource("[%d+a0]", result.storage_index);
|
||||||
break;
|
break;
|
||||||
case InstructionStorageAddressingMode::kAddressRelative:
|
case InstructionStorageAddressingMode::kAddressRelative:
|
||||||
EmitSource("[%d+aL]", result.storage_index);
|
EmitSource("[%d+aL.x]", result.storage_index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue