diff options
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
4 files changed, 53 insertions, 10 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 0031fa5fb..3f9698d6b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -261,7 +261,9 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { case Stage::Geometry: execution_model = spv::ExecutionModel::Geometry; ctx.AddCapability(spv::Capability::Geometry); - ctx.AddCapability(spv::Capability::GeometryStreams); + if (ctx.profile.support_geometry_streams) { + ctx.AddCapability(spv::Capability::GeometryStreams); + } switch (ctx.runtime_info.input_topology) { case InputTopology::Points: ctx.AddExecutionMode(main, spv::ExecutionMode::InputPoints); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 44281e407..945cdb42b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -60,11 +60,10 @@ public: Add(spv::ImageOperandsMask::ConstOffsets, offsets); } - explicit ImageOperands(EmitContext& ctx, const IR::Value& offset, Id lod, Id ms) { + explicit ImageOperands(Id lod, Id ms) { if (Sirit::ValidId(lod)) { Add(spv::ImageOperandsMask::Lod, lod); } - AddOffset(ctx, offset, ImageFetchOffsetAllowed); if (Sirit::ValidId(ms)) { Add(spv::ImageOperandsMask::Sample, ms); } @@ -312,6 +311,43 @@ Id ImageGatherSubpixelOffset(EmitContext& ctx, const IR::TextureInstInfo& info, return coords; } } + +void AddOffsetToCoordinates(EmitContext& ctx, const IR::TextureInstInfo& info, Id& coords, + Id offset) { + if (!Sirit::ValidId(offset)) { + return; + } + + Id result_type{}; + switch (info.type) { + case TextureType::Buffer: + case TextureType::Color1D: { + result_type = ctx.U32[1]; + break; + } + case TextureType::ColorArray1D: + offset = ctx.OpCompositeConstruct(ctx.U32[2], offset, ctx.u32_zero_value); + [[fallthrough]]; + case TextureType::Color2D: + case TextureType::Color2DRect: { + result_type = ctx.U32[2]; + break; + } + case TextureType::ColorArray2D: + offset = ctx.OpCompositeConstruct(ctx.U32[3], ctx.OpCompositeExtract(ctx.U32[1], coords, 0), + ctx.OpCompositeExtract(ctx.U32[1], coords, 1), + ctx.u32_zero_value); + [[fallthrough]]; + case TextureType::Color3D: { + result_type = ctx.U32[3]; + break; + } + case TextureType::ColorCube: + case TextureType::ColorArrayCube: + return; + } + coords = ctx.OpIAdd(result_type, coords, offset); +} } // Anonymous namespace Id EmitBindlessImageSampleImplicitLod(EmitContext&) { @@ -494,9 +530,10 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, operands.Span()); } -Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, - const IR::Value& offset, Id lod, Id ms) { +Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, + Id lod, Id ms) { const auto info{inst->Flags<IR::TextureInstInfo>()}; + AddOffsetToCoordinates(ctx, info, coords, offset); if (info.type == TextureType::Buffer) { lod = Id{}; } @@ -504,7 +541,7 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id c // This image is multisampled, lod must be implicit lod = Id{}; } - const ImageOperands operands(ctx, offset, lod, ms); + const ImageOperands operands(lod, ms); return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], TextureImage(ctx, info, index), coords, operands.MaskOptional(), operands.Span()); } diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 08fcabd58..5c01b1012 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -537,8 +537,8 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id const IR::Value& offset, const IR::Value& offset2); Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, const IR::Value& offset, const IR::Value& offset2, Id dref); -Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, - const IR::Value& offset, Id lod, Id ms); +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, const IR::Value& skip_mips); Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index 9f7b6bb4b..f60da758e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp @@ -129,7 +129,9 @@ void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { if (ctx.runtime_info.convert_depth_mode && !ctx.profile.support_native_ndc) { ConvertDepthMode(ctx); } - if (stream.IsImmediate()) { + if (!ctx.profile.support_geometry_streams) { + throw NotImplementedException("Geometry streams"); + } else if (stream.IsImmediate()) { ctx.OpEmitStreamVertex(ctx.Def(stream)); } else { LOG_WARNING(Shader_SPIRV, "Stream is not immediate"); @@ -140,7 +142,9 @@ void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { } void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { - if (stream.IsImmediate()) { + if (!ctx.profile.support_geometry_streams) { + throw NotImplementedException("Geometry streams"); + } else if (stream.IsImmediate()) { ctx.OpEndStreamPrimitive(ctx.Def(stream)); } else { LOG_WARNING(Shader_SPIRV, "Stream is not immediate"); |