spirv: Bitcast non-F32 output attributes to their type before store
This commit is contained in:
		| @@ -52,7 +52,15 @@ Id OutputAccessChain(EmitContext& ctx, Id result_type, Id base, Args&&... args) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | struct OutAttr { | ||||||
|  |     OutAttr(Id pointer_) : pointer{pointer_} {} | ||||||
|  |     OutAttr(Id pointer_, Id type_) : pointer{pointer_}, type{type_} {} | ||||||
|  |  | ||||||
|  |     Id pointer{}; | ||||||
|  |     Id type{}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||||
|     if (IR::IsGeneric(attr)) { |     if (IR::IsGeneric(attr)) { | ||||||
|         const u32 index{IR::GenericAttributeIndex(attr)}; |         const u32 index{IR::GenericAttributeIndex(attr)}; | ||||||
|         const u32 element{IR::GenericAttributeElement(attr)}; |         const u32 element{IR::GenericAttributeElement(attr)}; | ||||||
| @@ -90,20 +98,23 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | |||||||
|         return OutputAccessChain(ctx, ctx.output_f32, ctx.clip_distances, clip_num); |         return OutputAccessChain(ctx, ctx.output_f32, ctx.clip_distances, clip_num); | ||||||
|     } |     } | ||||||
|     case IR::Attribute::Layer: |     case IR::Attribute::Layer: | ||||||
|         return ctx.profile.support_viewport_index_layer_non_geometry || |         if (ctx.profile.support_viewport_index_layer_non_geometry || | ||||||
|                        ctx.stage == Shader::Stage::Geometry |             ctx.stage == Shader::Stage::Geometry) { | ||||||
|                    ? std::optional<Id>{ctx.layer} |             return OutAttr{ctx.layer, ctx.U32[1]}; | ||||||
|                    : std::nullopt; |         } | ||||||
|  |         return std::nullopt; | ||||||
|     case IR::Attribute::ViewportIndex: |     case IR::Attribute::ViewportIndex: | ||||||
|         return ctx.profile.support_viewport_index_layer_non_geometry || |         if (ctx.profile.support_viewport_index_layer_non_geometry || | ||||||
|                        ctx.stage == Shader::Stage::Geometry |             ctx.stage == Shader::Stage::Geometry) { | ||||||
|                    ? std::optional<Id>{ctx.viewport_index} |             return OutAttr{ctx.viewport_index, ctx.U32[1]}; | ||||||
|                    : std::nullopt; |         } | ||||||
|  |         return std::nullopt; | ||||||
|     case IR::Attribute::ViewportMask: |     case IR::Attribute::ViewportMask: | ||||||
|         if (!ctx.profile.support_viewport_mask) { |         if (!ctx.profile.support_viewport_mask) { | ||||||
|             return std::nullopt; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|         return ctx.OpAccessChain(ctx.output_u32, ctx.viewport_mask, ctx.u32_zero_value); |         return OutAttr{ctx.OpAccessChain(ctx.output_u32, ctx.viewport_mask, ctx.u32_zero_value), | ||||||
|  |                        ctx.U32[1]}; | ||||||
|     default: |     default: | ||||||
|         throw NotImplementedException("Read attribute {}", attr); |         throw NotImplementedException("Read attribute {}", attr); | ||||||
|     } |     } | ||||||
| @@ -262,10 +273,14 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_unused]] Id vertex) { | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_unused]] Id vertex) { | ||||||
|     const std::optional<Id> output{OutputAttrPointer(ctx, attr)}; |     const std::optional<OutAttr> output{OutputAttrPointer(ctx, attr)}; | ||||||
|     if (output) { |     if (!output) { | ||||||
|         ctx.OpStore(*output, value); |         return; | ||||||
|     } |     } | ||||||
|  |     if (Sirit::ValidId(output->type)) { | ||||||
|  |         value = ctx.OpBitcast(output->type, value); | ||||||
|  |     } | ||||||
|  |     ctx.OpStore(output->pointer, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex) { | Id EmitGetAttributeIndexed(EmitContext& ctx, Id offset, Id vertex) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user