shader: Implement tessellation shaders, polygon mode and invocation id

This commit is contained in:
ReinUsesLisp 2021-04-15 22:46:11 -03:00 committed by ameerj
parent 34519d3fc6
commit 183855e396
28 changed files with 605 additions and 91 deletions

View file

@ -70,6 +70,11 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
program.stage = env.ShaderStage();
program.local_memory_size = env.LocalMemorySize();
switch (program.stage) {
case Stage::TessellationControl: {
const ProgramHeader& sph{env.SPH()};
program.invocations = sph.common2.threads_per_input_primitive;
break;
}
case Stage::Geometry: {
const ProgramHeader& sph{env.SPH()};
program.output_topology = sph.common3.output_topology;

View file

@ -70,12 +70,6 @@ void TranslatorVisitor::ALD(u64 insn) {
BitField<47, 2, Size> size;
} const ald{insn};
if (ald.o != 0) {
throw NotImplementedException("O");
}
if (ald.patch != 0) {
throw NotImplementedException("P");
}
const u64 offset{ald.absolute_offset.Value()};
if (offset % 4 != 0) {
throw NotImplementedException("Unaligned absolute offset {}", offset);
@ -84,11 +78,19 @@ void TranslatorVisitor::ALD(u64 insn) {
const u32 num_elements{NumElements(ald.size)};
if (ald.index_reg == IR::Reg::RZ) {
for (u32 element = 0; element < num_elements; ++element) {
const IR::Attribute attr{offset / 4 + element};
F(ald.dest_reg + element, ir.GetAttribute(attr, vertex));
if (ald.patch != 0) {
const IR::Patch patch{offset / 4 + element};
F(ald.dest_reg + element, ir.GetPatch(patch));
} else {
const IR::Attribute attr{offset / 4 + element};
F(ald.dest_reg + element, ir.GetAttribute(attr, vertex));
}
}
return;
}
if (ald.patch != 0) {
throw NotImplementedException("Indirect patch read");
}
HandleIndexed(*this, ald.index_reg, num_elements, [&](u32 element, IR::U32 final_offset) {
F(ald.dest_reg + element, ir.GetAttributeIndexed(final_offset, vertex));
});
@ -106,9 +108,6 @@ void TranslatorVisitor::AST(u64 insn) {
BitField<47, 2, Size> size;
} const ast{insn};
if (ast.patch != 0) {
throw NotImplementedException("P");
}
if (ast.index_reg != IR::Reg::RZ) {
throw NotImplementedException("Indexed store");
}
@ -120,11 +119,19 @@ void TranslatorVisitor::AST(u64 insn) {
const u32 num_elements{NumElements(ast.size)};
if (ast.index_reg == IR::Reg::RZ) {
for (u32 element = 0; element < num_elements; ++element) {
const IR::Attribute attr{offset / 4 + element};
ir.SetAttribute(attr, F(ast.src_reg + element), vertex);
if (ast.patch != 0) {
const IR::Patch patch{offset / 4 + element};
ir.SetPatch(patch, F(ast.src_reg + element));
} else {
const IR::Attribute attr{offset / 4 + element};
ir.SetAttribute(attr, F(ast.src_reg + element), vertex);
}
}
return;
}
if (ast.patch != 0) {
throw NotImplementedException("Indexed tessellation patch store");
}
HandleIndexed(*this, ast.index_reg, num_elements, [&](u32 element, IR::U32 final_offset) {
ir.SetAttributeIndexed(final_offset, F(ast.src_reg + element), vertex);
});

View file

@ -113,6 +113,8 @@ enum class SpecialRegister : u64 {
[[nodiscard]] IR::U32 Read(IR::IREmitter& ir, SpecialRegister special_register) {
switch (special_register) {
case SpecialRegister::SR_INVOCATION_ID:
return ir.InvocationId();
case SpecialRegister::SR_THREAD_KILL:
return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))};
case SpecialRegister::SR_INVOCATION_INFO: