summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/spirv
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-03-26 22:45:38 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:24 +0200
commit17063d16a3cfe6542e74265739191e1d018fc456 (patch)
tree3dc74c85c9be19183f4c889306458c9a6307b108 /src/shader_recompiler/backend/spirv
parentshader: Refactor PTP and other minor changes (diff)
downloadyuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar
yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.gz
yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.bz2
yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.lz
yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.xz
yuzu-17063d16a3cfe6542e74265739191e1d018fc456.tar.zst
yuzu-17063d16a3cfe6542e74265739191e1d018fc456.zip
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h3
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp10
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h3
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp48
5 files changed, 64 insertions, 8 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index 50793b5bf..c2d13f97c 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -244,8 +244,9 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) {
if (desc.count != 1) {
throw NotImplementedException("Array of textures");
}
- const Id type{TypeSampledImage(ImageType(*this, desc))};
- const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, type)};
+ const Id image_type{ImageType(*this, desc)};
+ const Id sampled_type{TypeSampledImage(image_type)};
+ const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, sampled_type)};
const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)};
Decorate(id, spv::Decoration::Binding, binding);
Decorate(id, spv::Decoration::DescriptorSet, 0U);
@@ -254,7 +255,8 @@ void EmitContext::DefineTextures(const Info& info, u32& binding) {
// TODO: Pass count info
textures.push_back(TextureDefinition{
.id{id},
- .type{type},
+ .sampled_type{sampled_type},
+ .image_type{image_type},
});
}
binding += desc.count;
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index 5ed815c06..0cb411a0e 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -31,7 +31,8 @@ private:
struct TextureDefinition {
Id id;
- Id type;
+ Id sampled_type;
+ Id image_type;
};
struct UniformDefinitions {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index cee72f50d..4bed16e7b 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -126,10 +126,10 @@ Id DefineMain(EmitContext& ctx, IR::Program& program) {
return main;
}
-void DefineEntryPoint(Environment& env, EmitContext& ctx, Id main) {
+void DefineEntryPoint(Environment& env, const IR::Program& program, EmitContext& ctx, Id main) {
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
spv::ExecutionModel execution_model{};
- switch (env.ShaderStage()) {
+ switch (program.stage) {
case Shader::Stage::Compute: {
const std::array<u32, 3> workgroup_size{env.WorkgroupSize()};
execution_model = spv::ExecutionModel::GLCompute;
@@ -143,6 +143,9 @@ void DefineEntryPoint(Environment& env, EmitContext& ctx, Id main) {
case Shader::Stage::Fragment:
execution_model = spv::ExecutionModel::Fragment;
ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
+ if (program.info.stores_frag_depth) {
+ ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);
+ }
break;
default:
throw NotImplementedException("Stage {}", env.ShaderStage());
@@ -235,6 +238,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
}
// TODO: Track this usage
ctx.AddCapability(spv::Capability::ImageGatherExtended);
+ ctx.AddCapability(spv::Capability::ImageQuery);
}
Id PhiArgDef(EmitContext& ctx, IR::Inst* inst, size_t index) {
@@ -267,7 +271,7 @@ std::vector<u32> EmitSPIRV(const Profile& profile, Environment& env, IR::Program
u32& binding) {
EmitContext ctx{profile, program, binding};
const Id main{DefineMain(ctx, program)};
- DefineEntryPoint(env, ctx, main);
+ DefineEntryPoint(env, program, ctx, main);
if (profile.support_float_controls) {
ctx.AddExtension("SPV_KHR_float_controls");
SetupDenormControl(profile, program, ctx, main);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 4da1f3707..b82b16e9d 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -343,6 +343,7 @@ Id EmitBindlessImageSampleDrefExplicitLod(EmitContext&);
Id EmitBindlessImageGather(EmitContext&);
Id EmitBindlessImageGatherDref(EmitContext&);
Id EmitBindlessImageFetch(EmitContext&);
+Id EmitBindlessImageQueryDimensions(EmitContext&);
Id EmitBoundImageSampleImplicitLod(EmitContext&);
Id EmitBoundImageSampleExplicitLod(EmitContext&);
Id EmitBoundImageSampleDrefImplicitLod(EmitContext&);
@@ -350,6 +351,7 @@ Id EmitBoundImageSampleDrefExplicitLod(EmitContext&);
Id EmitBoundImageGather(EmitContext&);
Id EmitBoundImageGatherDref(EmitContext&);
Id EmitBoundImageFetch(EmitContext&);
+Id EmitBoundImageQueryDimensions(EmitContext&);
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id bias_lc, Id offset);
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
@@ -364,6 +366,7 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
const IR::Value& offset, const IR::Value& offset2, Id dref);
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
Id lod, Id ms);
+Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod);
Id EmitVoteAll(EmitContext& ctx, Id pred);
Id EmitVoteAny(EmitContext& ctx, Id pred);
Id EmitVoteEqual(EmitContext& ctx, Id pred);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index b6e9d3c0c..3ea0011aa 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -91,7 +91,15 @@ private:
Id Texture(EmitContext& ctx, const IR::Value& index) {
if (index.IsImmediate()) {
const TextureDefinition def{ctx.textures.at(index.U32())};
- return ctx.OpLoad(def.type, def.id);
+ return ctx.OpLoad(def.sampled_type, def.id);
+ }
+ throw NotImplementedException("Indirect texture sample");
+}
+
+Id TextureImage(EmitContext& ctx, const IR::Value& index) {
+ if (index.IsImmediate()) {
+ const TextureDefinition def{ctx.textures.at(index.U32())};
+ return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
}
throw NotImplementedException("Indirect texture sample");
}
@@ -149,6 +157,10 @@ Id EmitBindlessImageFetch(EmitContext&) {
throw LogicError("Unreachable instruction");
}
+Id EmitBindlessImageQueryDimensions(EmitContext&) {
+ throw LogicError("Unreachable instruction");
+}
+
Id EmitBoundImageSampleImplicitLod(EmitContext&) {
throw LogicError("Unreachable instruction");
}
@@ -177,6 +189,10 @@ Id EmitBoundImageFetch(EmitContext&) {
throw LogicError("Unreachable instruction");
}
+Id EmitBoundImageQueryDimensions(EmitContext&) {
+ throw LogicError("Unreachable instruction");
+}
+
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id bias_lc, Id offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
@@ -241,4 +257,34 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c
Texture(ctx, index), coords, operands.Mask(), operands.Span());
}
+Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod) {
+ const auto info{inst->Flags<IR::TextureInstInfo>()};
+ const Id image{TextureImage(ctx, index)};
+ const Id zero{ctx.u32_zero_value};
+ const auto mips{[&] { return ctx.OpImageQueryLevels(ctx.U32[1], image); }};
+ switch (info.type) {
+ case TextureType::Color1D:
+ case TextureType::Shadow1D:
+ return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[1], image, lod),
+ zero, zero, mips());
+ case TextureType::ColorArray1D:
+ case TextureType::Color2D:
+ case TextureType::ColorCube:
+ case TextureType::ShadowArray1D:
+ case TextureType::Shadow2D:
+ case TextureType::ShadowCube:
+ return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[2], image, lod),
+ zero, mips());
+ case TextureType::ColorArray2D:
+ case TextureType::Color3D:
+ case TextureType::ColorArrayCube:
+ case TextureType::ShadowArray2D:
+ case TextureType::Shadow3D:
+ case TextureType::ShadowArrayCube:
+ return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod),
+ mips());
+ }
+ throw LogicError("Unspecified image type {}", info.type.Value());
+}
+
} // namespace Shader::Backend::SPIRV