summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp3
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp4
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp16
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h3
-rw-r--r--src/shader_recompiler/backend/glasm/glasm_emit_context.cpp4
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp4
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp16
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_instructions.h3
-rw-r--r--src/shader_recompiler/backend/glsl/glsl_emit_context.cpp3
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp24
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_instructions.h5
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp35
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.h5
15 files changed, 131 insertions, 2 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 01f9abc71..3b0176bf6 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -450,6 +450,9 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I
if (program.info.uses_rescaling_uniform) {
header += "PARAM scaling[1]={program.local[0..0]};";
}
+ if (program.info.uses_render_area) {
+ header += "PARAM render_area[1]={program.local[1..1]};";
+ }
header += "TEMP ";
for (size_t index = 0; index < ctx.reg_alloc.NumUsedRegisters(); ++index) {
header += fmt::format("R{},", index);
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
index 2fc2a0ac6..5bfdecc09 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
@@ -43,6 +43,10 @@ void EmitBitCastU64F64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
Alias(inst, value);
}
+void EmitBitCastS32F32(EmitContext&, IR::Inst& inst, const IR::Value& value) {
+ Alias(inst, value);
+}
+
void EmitBitCastF16U16(EmitContext&, IR::Inst& inst, const IR::Value& value) {
Alias(inst, value);
}
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
index 7e8f37563..d6562c842 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
@@ -379,6 +379,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) {
ctx.Add("MOV.S {}.x,primitive_invocation.x;", inst);
}
+void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) {
+ switch (ctx.stage) {
+ case Stage::TessellationControl:
+ case Stage::TessellationEval:
+ ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst);
+ break;
+ default:
+ LOG_WARNING(Shader, "(STUBBED) called");
+ ctx.Add("MOV.S {}.x,0x00ff0000;", inst);
+ }
+}
+
void EmitSampleId(EmitContext& ctx, IR::Inst& inst) {
ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst);
}
@@ -396,6 +408,10 @@ void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) {
ctx.Add("MOV.F {}.x,scaling[0].z;", inst);
}
+void EmitRenderArea(EmitContext& ctx, IR::Inst& inst) {
+ ctx.Add("MOV.F {},render_area[0];", inst);
+}
+
void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset) {
ctx.Add("MOV.U {},lmem[{}].x;", inst, word_offset);
}
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 8b0ac3031..eaaf9ba39 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -69,10 +69,12 @@ void EmitSetOFlag(EmitContext& ctx);
void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst);
void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst);
void EmitInvocationId(EmitContext& ctx, IR::Inst& inst);
+void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst);
void EmitSampleId(EmitContext& ctx, IR::Inst& inst);
void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst);
void EmitYDirection(EmitContext& ctx, IR::Inst& inst);
void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst);
+void EmitRenderArea(EmitContext& ctx, IR::Inst& inst);
void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset);
void EmitWriteLocal(EmitContext& ctx, ScalarU32 word_offset, ScalarU32 value);
void EmitUndefU1(EmitContext& ctx, IR::Inst& inst);
@@ -195,6 +197,7 @@ void EmitSelectF64(EmitContext& ctx, ScalarS32 cond, Register true_value, Regist
void EmitBitCastU16F16(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastU32F32(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
+void EmitBitCastS32F32(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastF16U16(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastF32U32(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastF64U64(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
diff --git a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
index 89603c1c4..333a91cc5 100644
--- a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
+++ b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
@@ -95,6 +95,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
if (info.uses_invocation_id) {
Add("ATTRIB primitive_invocation=primitive.invocation;");
}
+ if (info.uses_invocation_info &&
+ (stage == Stage::TessellationControl || stage == Stage::TessellationEval)) {
+ Add("ATTRIB primitive_vertexcount = primitive.vertexcount;");
+ }
if (info.stores_tess_level_outer) {
Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};");
}
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
index 1be4a0f59..8e5e6cf1f 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
@@ -48,6 +48,10 @@ void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value)
ctx.AddU64("{}=doubleBitsToUint64({});", inst, value);
}
+void EmitBitCastS32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) {
+ ctx.AddF32("{}=ftoi({});", inst, value);
+}
+
void EmitBitCastF16U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst) {
NotImplemented();
}
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
index fad8d1e30..c1671c37b 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
@@ -399,6 +399,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) {
ctx.AddU32("{}=uint(gl_InvocationID);", inst);
}
+void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) {
+ switch (ctx.stage) {
+ case Stage::TessellationControl:
+ case Stage::TessellationEval:
+ ctx.AddU32("{}=uint(gl_PatchVerticesIn)<<16;", inst);
+ break;
+ default:
+ LOG_WARNING(Shader, "(STUBBED) called");
+ ctx.AddU32("{}=uint(0x00ff0000);", inst);
+ }
+}
+
void EmitSampleId(EmitContext& ctx, IR::Inst& inst) {
ctx.AddU32("{}=uint(gl_SampleID);", inst);
}
@@ -416,6 +428,10 @@ void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) {
ctx.AddF32("{}=scaling.z;", inst);
}
+void EmitRenderArea(EmitContext& ctx, IR::Inst& inst) {
+ ctx.AddF32x4("{}=render_area;", inst);
+}
+
void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, std::string_view word_offset) {
ctx.AddU32("{}=lmem[{}];", inst, word_offset);
}
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
index 639691ba6..4151c89de 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
@@ -83,10 +83,12 @@ void EmitSetOFlag(EmitContext& ctx);
void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst);
void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst);
void EmitInvocationId(EmitContext& ctx, IR::Inst& inst);
+void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst);
void EmitSampleId(EmitContext& ctx, IR::Inst& inst);
void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst);
void EmitYDirection(EmitContext& ctx, IR::Inst& inst);
void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst);
+void EmitRenderArea(EmitContext& ctx, IR::Inst& inst);
void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, std::string_view word_offset);
void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_view value);
void EmitUndefU1(EmitContext& ctx, IR::Inst& inst);
@@ -229,6 +231,7 @@ void EmitSelectF64(EmitContext& ctx, IR::Inst& inst, std::string_view cond,
void EmitBitCastU16F16(EmitContext& ctx, IR::Inst& inst);
void EmitBitCastU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value);
void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value);
+void EmitBitCastS32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value);
void EmitBitCastF16U16(EmitContext& ctx, IR::Inst& inst);
void EmitBitCastF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value);
void EmitBitCastF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value);
diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
index c767a9dc3..5d01ec0cd 100644
--- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
@@ -358,6 +358,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
if (info.uses_rescaling_uniform) {
header += "layout(location=0) uniform vec4 scaling;";
}
+ if (info.uses_render_area) {
+ header += "layout(location=1) uniform vec4 render_area;";
+ }
DefineConstantBuffers(bindings);
DefineConstantBufferIndirect();
DefineStorageBuffers(bindings);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 7567b6fc9..937881484 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -23,8 +23,12 @@ struct RescalingLayout {
alignas(16) std::array<u32, NUM_IMAGE_SCALING_WORDS> rescaling_images;
u32 down_factor;
};
+struct RenderAreaLayout {
+ std::array<f32, 4> render_area;
+};
constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescaling_textures);
constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor);
+constexpr u32 RENDERAREA_LAYOUT_OFFSET = offsetof(RenderAreaLayout, render_area);
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
IR::Program& program, Bindings& bindings);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp
index c4ca28d11..50daacd95 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp
@@ -18,6 +18,10 @@ void EmitBitCastU64F64(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
}
+void EmitBitCastS32F32(EmitContext&) {
+ throw NotImplementedException("SPIR-V Instruction");
+}
+
void EmitBitCastF16U16(EmitContext&) {
throw NotImplementedException("SPIR-V Instruction");
}
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 2c68aba39..5b3b5d1f3 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
@@ -353,7 +353,6 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
case IR::Attribute::TessellationEvaluationPointV:
return ctx.OpLoad(ctx.F32[1],
ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.Const(1U)));
-
default:
throw NotImplementedException("Read attribute {}", attr);
}
@@ -513,6 +512,18 @@ Id EmitInvocationId(EmitContext& ctx) {
return ctx.OpLoad(ctx.U32[1], ctx.invocation_id);
}
+Id EmitInvocationInfo(EmitContext& ctx) {
+ switch (ctx.stage) {
+ case Stage::TessellationControl:
+ case Stage::TessellationEval:
+ return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.patch_vertices_in),
+ ctx.Const(16u));
+ default:
+ LOG_WARNING(Shader, "(STUBBED) called");
+ return ctx.Const(0x00ff0000u);
+ }
+}
+
Id EmitSampleId(EmitContext& ctx) {
return ctx.OpLoad(ctx.U32[1], ctx.sample_id);
}
@@ -537,6 +548,17 @@ Id EmitResolutionDownFactor(EmitContext& ctx) {
}
}
+Id EmitRenderArea(EmitContext& ctx) {
+ if (ctx.profile.unified_descriptor_binding) {
+ const Id pointer_type{ctx.TypePointer(spv::StorageClass::PushConstant, ctx.F32[4])};
+ const Id index{ctx.Const(ctx.render_are_member_index)};
+ const Id pointer{ctx.OpAccessChain(pointer_type, ctx.render_area_push_constant, index)};
+ return ctx.OpLoad(ctx.F32[4], pointer);
+ } else {
+ throw NotImplementedException("SPIR-V Instruction");
+ }
+}
+
Id EmitLoadLocal(EmitContext& ctx, Id word_offset) {
const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)};
return ctx.OpLoad(ctx.U32[1], pointer);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
index 984d072b4..e31cdc5e8 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
@@ -72,10 +72,12 @@ void EmitSetOFlag(EmitContext& ctx);
Id EmitWorkgroupId(EmitContext& ctx);
Id EmitLocalInvocationId(EmitContext& ctx);
Id EmitInvocationId(EmitContext& ctx);
+Id EmitInvocationInfo(EmitContext& ctx);
Id EmitSampleId(EmitContext& ctx);
Id EmitIsHelperInvocation(EmitContext& ctx);
Id EmitYDirection(EmitContext& ctx);
Id EmitResolutionDownFactor(EmitContext& ctx);
+Id EmitRenderArea(EmitContext& ctx);
Id EmitLoadLocal(EmitContext& ctx, Id word_offset);
void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value);
Id EmitUndefU1(EmitContext& ctx);
@@ -177,7 +179,8 @@ Id EmitSelectF64(EmitContext& ctx, Id cond, Id true_value, Id false_value);
void EmitBitCastU16F16(EmitContext& ctx);
Id EmitBitCastU32F32(EmitContext& ctx, Id value);
void EmitBitCastU64F64(EmitContext& ctx);
-void EmitBitCastF16U16(EmitContext& ctx);
+void EmitBitCastS32F32(EmitContext& ctx);
+void EmitBitCastF16U16(EmitContext&);
Id EmitBitCastF32U32(EmitContext& ctx, Id value);
void EmitBitCastF64U64(EmitContext& ctx);
Id EmitPackUint2x32(EmitContext& ctx, Id value);
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index aecc4c612..0bfc2dd89 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -473,6 +473,7 @@ EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_inf
DefineAttributeMemAccess(program.info);
DefineGlobalMemoryFunctions(program.info);
DefineRescalingInput(program.info);
+ DefineRenderArea(program.info);
}
EmitContext::~EmitContext() = default;
@@ -982,6 +983,36 @@ void EmitContext::DefineRescalingInputUniformConstant() {
}
}
+void EmitContext::DefineRenderArea(const Info& info) {
+ if (!info.uses_render_area) {
+ return;
+ }
+
+ if (profile.unified_descriptor_binding) {
+ boost::container::static_vector<Id, 1> members{};
+ u32 member_index{0};
+
+ members.push_back(F32[4]);
+ render_are_member_index = member_index++;
+
+ const Id push_constant_struct{TypeStruct(std::span(members.data(), members.size()))};
+ Decorate(push_constant_struct, spv::Decoration::Block);
+ Name(push_constant_struct, "RenderAreaInfo");
+
+ MemberDecorate(push_constant_struct, render_are_member_index, spv::Decoration::Offset, 0);
+ MemberName(push_constant_struct, render_are_member_index, "render_area");
+
+ const Id pointer_type{TypePointer(spv::StorageClass::PushConstant, push_constant_struct)};
+ render_area_push_constant =
+ AddGlobalVariable(pointer_type, spv::StorageClass::PushConstant);
+ Name(render_area_push_constant, "render_area_push_constants");
+
+ if (profile.supported_spirv >= 0x00010400) {
+ interfaces.push_back(render_area_push_constant);
+ }
+ }
+}
+
void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) {
if (info.constant_buffer_descriptors.empty()) {
return;
@@ -1294,6 +1325,10 @@ void EmitContext::DefineInputs(const IR::Program& program) {
if (info.uses_invocation_id) {
invocation_id = DefineInput(*this, U32[1], false, spv::BuiltIn::InvocationId);
}
+ if (info.uses_invocation_info &&
+ (stage == Shader::Stage::TessellationControl || stage == Shader::Stage::TessellationEval)) {
+ patch_vertices_in = DefineInput(*this, U32[1], false, spv::BuiltIn::PatchVertices);
+ }
if (info.uses_sample_id) {
sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId);
}
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
index bc25b8b84..dde45b4bc 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
@@ -204,6 +204,7 @@ public:
Id workgroup_id{};
Id local_invocation_id{};
Id invocation_id{};
+ Id patch_vertices_in{};
Id sample_id{};
Id is_helper_invocation{};
Id subgroup_local_invocation_id{};
@@ -243,6 +244,9 @@ public:
u32 texture_rescaling_index{};
u32 image_rescaling_index{};
+ Id render_area_push_constant{};
+ u32 render_are_member_index{};
+
Id local_memory{};
Id shared_memory_u8{};
@@ -318,6 +322,7 @@ private:
void DefineRescalingInput(const Info& info);
void DefineRescalingInputPushConstant();
void DefineRescalingInputUniformConstant();
+ void DefineRenderArea(const Info& info);
void DefineInputs(const IR::Program& program);
void DefineOutputs(const IR::Program& program);