Browse Source

spirv: Bitcast non-F32 output attributes to their type before store

nce_cpp
ReinUsesLisp 5 years ago
committed by ameerj
parent
commit
ca85ce444f
  1. 41
      src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp

41
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)
} }
} }
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 ||
ctx.stage == Shader::Stage::Geometry
? std::optional<Id>{ctx.layer}
: std::nullopt;
if (ctx.profile.support_viewport_index_layer_non_geometry ||
ctx.stage == Shader::Stage::Geometry) {
return OutAttr{ctx.layer, ctx.U32[1]};
}
return std::nullopt;
case IR::Attribute::ViewportIndex: case IR::Attribute::ViewportIndex:
return ctx.profile.support_viewport_index_layer_non_geometry ||
ctx.stage == Shader::Stage::Geometry
? std::optional<Id>{ctx.viewport_index}
: std::nullopt;
if (ctx.profile.support_viewport_index_layer_non_geometry ||
ctx.stage == Shader::Stage::Geometry) {
return OutAttr{ctx.viewport_index, ctx.U32[1]};
}
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)};
if (output) {
ctx.OpStore(*output, value);
const std::optional<OutAttr> output{OutputAttrPointer(ctx, attr)};
if (!output) {
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) {

Loading…
Cancel
Save