summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv
diff options
context:
space:
mode:
authorameerj <52414509+ameerj@users.noreply.github.com>2021-12-24 20:00:28 -0500
committerameerj <52414509+ameerj@users.noreply.github.com>2021-12-29 19:03:49 -0500
commit14ac0c2923c41df9c6fc4833d2a8e46a6efe5b59 (patch)
tree6d9cb0ebd7d8d7b75d88a0d598c659b06d45004c /src/shader_recompiler/backend/spirv
parent640fc1418b08449f2ba729588aef5e06bc5df636 (diff)
shader: Add integer attribute get optimization pass
Works around an nvidia driver bug, where casting the integer attributes to float and back to an integer always returned 0.
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp25
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_instructions.h1
2 files changed, 26 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index 14f470812..8ea730c80 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -355,6 +355,31 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
}
}
+Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, Id) {
+ switch (attr) {
+ case IR::Attribute::PrimitiveId:
+ return ctx.OpLoad(ctx.U32[1], ctx.primitive_id);
+ case IR::Attribute::InstanceId:
+ if (ctx.profile.support_vertex_instance_id) {
+ return ctx.OpLoad(ctx.U32[1], ctx.instance_id);
+ } else {
+ const Id index{ctx.OpLoad(ctx.U32[1], ctx.instance_index)};
+ const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_instance)};
+ return ctx.OpISub(ctx.U32[1], index, base);
+ }
+ case IR::Attribute::VertexId:
+ if (ctx.profile.support_vertex_instance_id) {
+ return ctx.OpLoad(ctx.U32[1], ctx.vertex_id);
+ } else {
+ const Id index{ctx.OpLoad(ctx.U32[1], ctx.vertex_index)};
+ const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)};
+ return ctx.OpISub(ctx.U32[1], index, base);
+ }
+ default:
+ throw NotImplementedException("Read U32 attribute {}", attr);
+ }
+}
+
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_unused]] Id vertex) {
const std::optional<OutAttr> output{OutputAttrPointer(ctx, attr)};
if (!output) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
index 6cd22dd3e..887112deb 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
@@ -53,6 +53,7 @@ Id EmitGetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& o
Id EmitGetCbufF32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset);
Id EmitGetCbufU32x2(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset);
Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex);
+Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, Id vertex);
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, Id vertex);
Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex);
void EmitSetAttributeIndexed(EmitContext& ctx, Id offset, Id value, Id vertex);