diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | 41 |
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 | ||
| 55 | std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | 55 | struct 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 | |||
| 63 | std::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 | ||
| 264 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_unused]] Id vertex) { | 275 | void 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 | ||
| 271 | Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex) { | 286 | Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex) { |