summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp29
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h3
-rw-r--r--src/video_core/shader/decode/texture.cpp17
4 files changed, 28 insertions, 24 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 48e23d4cd..7ddf7d3ee 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -325,9 +325,6 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
specialization.tessellation.primitive = fixed_state.tessellation.primitive;
specialization.tessellation.spacing = fixed_state.tessellation.spacing;
specialization.tessellation.clockwise = fixed_state.tessellation.clockwise;
- for (const auto& rt : key.renderpass_params.color_attachments) {
- specialization.enabled_rendertargets.set(rt.index);
- }
SPIRVProgram program;
std::vector<vk::DescriptorSetLayoutBinding> bindings;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index dd6d2ef03..b53078721 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -542,11 +542,10 @@ private:
return;
}
- for (u32 rt = 0; rt < static_cast<u32>(frag_colors.size()); ++rt) {
- if (!specialization.enabled_rendertargets[rt]) {
+ for (u32 rt = 0; rt < static_cast<u32>(std::size(frag_colors)); ++rt) {
+ if (!IsRenderTargetEnabled(rt)) {
continue;
}
-
const Id id = AddGlobalVariable(OpVariable(t_out_float4, spv::StorageClass::Output));
Name(id, fmt::format("frag_color{}", rt));
Decorate(id, spv::Decoration::Location, rt);
@@ -852,6 +851,15 @@ private:
return binding;
}
+ bool IsRenderTargetEnabled(u32 rt) const {
+ for (u32 component = 0; component < 4; ++component) {
+ if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
bool IsInputAttributeArray() const {
return stage == ShaderType::TesselationControl || stage == ShaderType::TesselationEval ||
stage == ShaderType::Geometry;
@@ -1889,19 +1897,14 @@ private:
// rendertargets/components are skipped in the register assignment.
u32 current_reg = 0;
for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) {
- if (!specialization.enabled_rendertargets[rt]) {
- // Skip rendertargets that are not enabled
- continue;
- }
// TODO(Subv): Figure out how dual-source blending is configured in the Switch.
for (u32 component = 0; component < 4; ++component) {
- const Id pointer = AccessElement(t_out_float, frag_colors.at(rt), component);
- if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
- OpStore(pointer, SafeGetRegister(current_reg));
- ++current_reg;
- } else {
- OpStore(pointer, component == 3 ? v_float_one : v_float_zero);
+ if (!header.ps.IsColorComponentOutputEnabled(rt, component)) {
+ continue;
}
+ const Id pointer = AccessElement(t_out_float, frag_colors[rt], component);
+ OpStore(pointer, SafeGetRegister(current_reg));
+ ++current_reg;
}
}
if (header.ps.omap.depth) {
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index 10794be1c..f5dc14d9e 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -102,9 +102,6 @@ struct Specialization final {
Maxwell::TessellationSpacing spacing{};
bool clockwise{};
} tessellation;
-
- // Fragment specific
- std::bitset<8> enabled_rendertargets;
};
// Old gcc versions don't consider this trivially copyable.
// static_assert(std::is_trivially_copyable_v<Specialization>);
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index cd984f763..0b567e39d 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -161,16 +161,16 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
case OpCode::Id::TXD: {
UNIMPLEMENTED_IF_MSG(instr.txd.UsesMiscMode(TextureMiscMode::AOFFI),
"AOFFI is not implemented");
- UNIMPLEMENTED_IF_MSG(instr.txd.is_array != 0, "TXD Array is not implemented");
+ const bool is_array = instr.txd.is_array != 0;
u64 base_reg = instr.gpr8.Value();
const auto derivate_reg = instr.gpr20.Value();
const auto texture_type = instr.txd.texture_type.Value();
const auto coord_count = GetCoordCount(texture_type);
- const Sampler* sampler = is_bindless
- ? GetBindlessSampler(base_reg, {{texture_type, false, false}})
- : GetSampler(instr.sampler, {{texture_type, false, false}});
+ const Sampler* sampler =
+ is_bindless ? GetBindlessSampler(base_reg, {{texture_type, is_array, false}})
+ : GetSampler(instr.sampler, {{texture_type, is_array, false}});
Node4 values;
if (sampler == nullptr) {
for (u32 element = 0; element < values.size(); ++element) {
@@ -179,6 +179,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
WriteTexInstructionFloat(bb, instr, values);
break;
}
+
if (is_bindless) {
base_reg++;
}
@@ -192,8 +193,14 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
derivates.push_back(GetRegister(derivate_reg + derivate + 1));
}
+ Node array_node = {};
+ if (is_array) {
+ const Node info_reg = GetRegister(base_reg + coord_count);
+ array_node = BitfieldExtract(info_reg, 0, 16);
+ }
+
for (u32 element = 0; element < values.size(); ++element) {
- MetaTexture meta{*sampler, {}, {}, {}, {}, derivates, {}, {}, {}, element};
+ MetaTexture meta{*sampler, array_node, {}, {}, {}, derivates, {}, {}, {}, element};
values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords);
}