summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp41
1 files changed, 28 insertions, 13 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 ca067f1c4..aaa20ab95 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
@@ -52,7 +52,15 @@ Id OutputAccessChain(EmitContext& ctx, Id result_type, Id base, Args&&... args)
52 } 52 }
53} 53}
54 54
55std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { 55struct OutAttr {
56 OutAttr(Id pointer_) : pointer{pointer_} {}
57 OutAttr(Id pointer_, Id type_) : pointer{pointer_}, type{type_} {}
58
59 Id pointer{};
60 Id type{};
61};
62
63std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
56 if (IR::IsGeneric(attr)) { 64 if (IR::IsGeneric(attr)) {
57 const u32 index{IR::GenericAttributeIndex(attr)}; 65 const u32 index{IR::GenericAttributeIndex(attr)};
58 const u32 element{IR::GenericAttributeElement(attr)}; 66 const u32 element{IR::GenericAttributeElement(attr)};
@@ -90,20 +98,23 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
90 return OutputAccessChain(ctx, ctx.output_f32, ctx.clip_distances, clip_num); 98 return OutputAccessChain(ctx, ctx.output_f32, ctx.clip_distances, clip_num);
91 } 99 }
92 case IR::Attribute::Layer: 100 case IR::Attribute::Layer:
93 return ctx.profile.support_viewport_index_layer_non_geometry || 101 if (ctx.profile.support_viewport_index_layer_non_geometry ||
94 ctx.stage == Shader::Stage::Geometry 102 ctx.stage == Shader::Stage::Geometry) {
95 ? std::optional<Id>{ctx.layer} 103 return OutAttr{ctx.layer, ctx.U32[1]};
96 : std::nullopt; 104 }
105 return std::nullopt;
97 case IR::Attribute::ViewportIndex: 106 case IR::Attribute::ViewportIndex:
98 return ctx.profile.support_viewport_index_layer_non_geometry || 107 if (ctx.profile.support_viewport_index_layer_non_geometry ||
99 ctx.stage == Shader::Stage::Geometry 108 ctx.stage == Shader::Stage::Geometry) {
100 ? std::optional<Id>{ctx.viewport_index} 109 return OutAttr{ctx.viewport_index, ctx.U32[1]};
101 : std::nullopt; 110 }
111 return std::nullopt;
102 case IR::Attribute::ViewportMask: 112 case IR::Attribute::ViewportMask:
103 if (!ctx.profile.support_viewport_mask) { 113 if (!ctx.profile.support_viewport_mask) {
104 return std::nullopt; 114 return std::nullopt;
105 } 115 }
106 return ctx.OpAccessChain(ctx.output_u32, ctx.viewport_mask, ctx.u32_zero_value); 116 return OutAttr{ctx.OpAccessChain(ctx.output_u32, ctx.viewport_mask, ctx.u32_zero_value),
117 ctx.U32[1]};
107 default: 118 default:
108 throw NotImplementedException("Read attribute {}", attr); 119 throw NotImplementedException("Read attribute {}", attr);
109 } 120 }
@@ -262,10 +273,14 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
262} 273}
263 274
264void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_unused]] Id vertex) { 275void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_unused]] Id vertex) {
265 const std::optional<Id> output{OutputAttrPointer(ctx, attr)}; 276 const std::optional<OutAttr> output{OutputAttrPointer(ctx, attr)};
266 if (output) { 277 if (!output) {
267 ctx.OpStore(*output, value); 278 return;
279 }
280 if (Sirit::ValidId(output->type)) {
281 value = ctx.OpBitcast(output->type, value);
268 } 282 }
283 ctx.OpStore(output->pointer, value);
269} 284}
270 285
271Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex) { 286Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex) {