Browse Source

[Re-introduced] Color output handling in SPIR-V emission

eds-true-adreno-fixes
CamilleLaVey 3 weeks ago
committed by Caio Oliveira
parent
commit
df088c6442
No known key found for this signature in database GPG Key ID: AAAE6C7FD4186B0C
  1. 19
      src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
  2. 14
      src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
  3. 4
      src/shader_recompiler/backend/spirv/spirv_emit_context.h
  4. 4
      src/shader_recompiler/runtime_info.h
  5. 20
      src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

19
src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp

@ -491,9 +491,24 @@ void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value) {
} }
void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, 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 Id component_id{ctx.Const(component)};
const Id pointer{ctx.OpAccessChain(ctx.output_f32, ctx.frag_color.at(index), component_id)};
ctx.OpStore(pointer, value);
const Id pointer{ctx.OpAccessChain(pointer_type, ctx.frag_color.at(index), component_id)};
ctx.OpStore(pointer, store_value);
} }
void EmitSetSampleMask(EmitContext& ctx, Id value) { void EmitSetSampleMask(EmitContext& ctx, Id value) {

14
src/shader_recompiler/backend/spirv/spirv_emit_context.cpp

@ -563,6 +563,7 @@ void EmitContext::DefineCommonTypes(const Info& info) {
output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32");
output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32"); 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) { if (info.uses_int8 && profile.support_int8) {
AddCapability(spv::Capability::Int8); AddCapability(spv::Capability::Int8);
@ -1699,7 +1700,18 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) { if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) {
continue; continue;
} }
frag_color[index] = DefineOutput(*this, F32[4], std::nullopt);
const AttributeType output_type{runtime_info.color_output_types[index]};
const Id vec_type = [&, output_type]() -> Id {
switch (output_type) {
case AttributeType::SignedInt:
return S32[4];
case AttributeType::UnsignedInt:
return U32[4];
default:
return F32[4];
}
}();
frag_color[index] = DefineOutput(*this, vec_type, std::nullopt);
Decorate(frag_color[index], spv::Decoration::Location, index); Decorate(frag_color[index], spv::Decoration::Location, index);
Name(frag_color[index], fmt::format("frag_color{}", index)); Name(frag_color[index], fmt::format("frag_color{}", index));
} }

4
src/shader_recompiler/backend/spirv/spirv_emit_context.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -246,6 +249,7 @@ public:
Id output_f32{}; Id output_f32{};
Id output_u32{}; Id output_u32{};
Id output_s32{};
Id image_buffer_type{}; Id image_buffer_type{};
Id image_u32{}; Id image_u32{};

4
src/shader_recompiler/runtime_info.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -80,6 +83,7 @@ struct TransformFeedbackVarying {
struct RuntimeInfo { struct RuntimeInfo {
std::array<AttributeType, 32> generic_input_types{}; std::array<AttributeType, 32> generic_input_types{};
std::array<AttributeType, 8> color_output_types{};
VaryingState previous_stage_stores; VaryingState previous_stage_stores;
std::map<IR::Attribute, IR::Attribute> previous_stage_legacy_stores_mapping; std::map<IR::Attribute, IR::Attribute> previous_stage_legacy_stores_mapping;

20
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@ -36,6 +36,7 @@
#include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_shader_util.h" #include "video_core/renderer_vulkan/vk_shader_util.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.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_cache.h"
#include "video_core/shader_environment.h" #include "video_core/shader_environment.h"
#include "video_core/shader_notify.h" #include "video_core/shader_notify.h"
@ -105,6 +106,21 @@ Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp compariso
return {}; 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) { VkShaderStageFlagBits StageToVkStage(Shader::Stage stage) {
switch (stage) { switch (stage) {
case Shader::Stage::VertexA: case Shader::Stage::VertexA:
@ -249,6 +265,10 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
info.alpha_test_func = MaxwellToCompareFunction( info.alpha_test_func = MaxwellToCompareFunction(
key.state.UnpackComparisonOp(key.state.alpha_test_func.Value())); key.state.UnpackComparisonOp(key.state.alpha_test_func.Value()));
info.alpha_test_reference = std::bit_cast<float>(key.state.alpha_test_ref); info.alpha_test_reference = std::bit_cast<float>(key.state.alpha_test_ref);
for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
const auto format = static_cast<Tegra::RenderTargetFormat>(key.state.color_formats[index]);
info.color_output_types[index] = RenderTargetAttributeType(format);
}
break; break;
default: default:
break; break;

Loading…
Cancel
Save