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 fb9d3dbbb2..4eb0c57421 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 @@ -483,6 +483,21 @@ void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value) { } void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value) { + const AttributeType output_type{ctx.runtime_info.color_output_types[index]}; + Id pointer_type{ctx.output_f32}; + Id store_value{value}; + switch (output_type) { + case AttributeType::SignedInt: + pointer_type = ctx.output_s32; + store_value = ctx.OpBitcast(ctx.S32[1], value); + break; + case AttributeType::UnsignedInt: + pointer_type = ctx.output_u32; + store_value = ctx.OpBitcast(ctx.U32[1], value); + break; + default: + break; + } const Id component_id{ctx.Const(component)}; const AttributeType type{ctx.runtime_info.color_output_types[index]}; if (type == AttributeType::Float) { diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index b5976857d9..4beb24e5ea 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -549,6 +549,7 @@ void EmitContext::DefineCommonTypes(const Info& info) { output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32"); + output_s32 = Name(TypePointer(spv::StorageClass::Output, S32[1]), "output_s32"); if (info.uses_int8 && profile.support_int8) { AddCapability(spv::Capability::Int8); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index de56809a98..606c60ee87 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -249,6 +249,7 @@ public: Id output_f32{}; Id output_u32{}; + Id output_s32{}; Id image_buffer_type{}; Id image_u32{}; diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index e6e1284762..6b6d9efe65 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h @@ -84,6 +84,7 @@ struct TransformFeedbackVarying { struct RuntimeInfo { std::array generic_input_types{}; + std::array color_output_types{}; VaryingState previous_stage_stores; std::map previous_stage_legacy_stores_mapping; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 1d0bbc8b23..a7769ce1ed 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -37,6 +37,7 @@ #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_shader_util.h" #include "video_core/renderer_vulkan/vk_update_descriptor.h" +#include "video_core/surface.h" #include "video_core/shader_cache.h" #include "video_core/shader_environment.h" #include "video_core/shader_notify.h" @@ -108,6 +109,21 @@ Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp compariso return {}; } +Shader::AttributeType RenderTargetAttributeType(Tegra::RenderTargetFormat format) { + if (format == Tegra::RenderTargetFormat::NONE) { + return Shader::AttributeType::Float; + } + const auto pixel_format{ + VideoCore::Surface::PixelFormatFromRenderTargetFormat(format)}; + if (!VideoCore::Surface::IsPixelFormatInteger(pixel_format)) { + return Shader::AttributeType::Float; + } + if (VideoCore::Surface::IsPixelFormatSignedInteger(pixel_format)) { + return Shader::AttributeType::SignedInt; + } + return Shader::AttributeType::UnsignedInt; +} + VkShaderStageFlagBits StageToVkStage(Shader::Stage stage) { switch (stage) { case Shader::Stage::VertexA: