[vk] fix LM3 and TL:LTD multiple NonUniform annotations (#3997)

should fix AMD

Signed-off-by: lizzie lizzie@eden-emu.dev

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3997
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
lizzie 2026-05-29 03:28:10 +02:00 committed by crueter
parent 251a3470dc
commit 5ea24621cf
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
5 changed files with 32 additions and 46 deletions

View file

@ -462,6 +462,13 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
ctx.AddCapability(spv::Capability::ImageGatherExtended); ctx.AddCapability(spv::Capability::ImageGatherExtended);
ctx.AddCapability(spv::Capability::ImageQuery); ctx.AddCapability(spv::Capability::ImageQuery);
ctx.AddCapability(spv::Capability::SampledBuffer); ctx.AddCapability(spv::Capability::SampledBuffer);
// TODO: this usage needs to be tracked properly
if (ctx.profile.support_sampled_image_array_nonuniform_indexing) {
if (ctx.profile.supported_spirv < 0x00010400)
ctx.AddExtension("SPV_EXT_descriptor_indexing");
ctx.AddCapability(spv::Capability::ShaderNonUniform);
ctx.AddCapability(spv::Capability::SampledImageArrayNonUniformIndexing);
}
} }
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) { void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {

View file

@ -14,37 +14,10 @@
namespace Shader::Backend::SPIRV { namespace Shader::Backend::SPIRV {
namespace { namespace {
class DescriptorIndex {
public:
explicit DescriptorIndex(EmitContext& ctx, const IR::Value& index)
: id{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)},
is_non_uniform{ctx.profile.support_sampled_image_array_nonuniform_indexing &&
!index.IsImmediate()} {
if (!is_non_uniform) {
return;
}
if (ctx.profile.supported_spirv < 0x00010400) {
ctx.AddExtension("SPV_EXT_descriptor_indexing");
}
ctx.AddCapability(spv::Capability::ShaderNonUniform);
ctx.AddCapability(spv::Capability::SampledImageArrayNonUniformIndexing);
Decorate(ctx, id);
}
Id Value() const { [[nodiscard]] bool IsNonUniformDescriptor(EmitContext& ctx, const IR::Value& index) noexcept {
return id; return ctx.profile.support_sampled_image_array_nonuniform_indexing && !index.IsImmediate();
} }
void Decorate(EmitContext& ctx, Id object) const {
if (is_non_uniform) {
ctx.Decorate(object, spv::Decoration::NonUniform);
}
}
private:
Id id;
bool is_non_uniform;
};
class ImageOperands { class ImageOperands {
public: public:
@ -221,11 +194,13 @@ private:
Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR::Value& index) { Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR::Value& index) {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) { if (def.count > 1) {
const DescriptorIndex idx{ctx, index}; auto const idx = index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index);
const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())}; if (!ctx.non_uniform_ids.contains(idx.value) && IsNonUniformDescriptor(ctx, index)) {
idx.Decorate(ctx, pointer); ctx.Decorate(idx, spv::Decoration::NonUniform);
ctx.non_uniform_ids.insert(idx.value);
}
const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, idx)};
const Id object{ctx.OpLoad(def.sampled_type, pointer)}; const Id object{ctx.OpLoad(def.sampled_type, pointer)};
idx.Decorate(ctx, object);
return object; return object;
} else { } else {
return ctx.OpLoad(def.sampled_type, def.id); return ctx.OpLoad(def.sampled_type, def.id);
@ -244,13 +219,14 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
} else { } else {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) { if (def.count > 1) {
const DescriptorIndex idx{ctx, index}; auto const idx = index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index);
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())}; if (!ctx.non_uniform_ids.contains(idx.value) && IsNonUniformDescriptor(ctx, index)) {
idx.Decorate(ctx, ptr); ctx.Decorate(idx, spv::Decoration::NonUniform);
const Id object{ctx.OpLoad(def.sampled_type, ptr)}; ctx.non_uniform_ids.insert(idx.value);
idx.Decorate(ctx, object); }
const Id image{ctx.OpImage(def.image_type, object)}; const Id ptr = ctx.OpAccessChain(def.pointer_type, def.id, idx);
idx.Decorate(ctx, image); const Id object = ctx.OpLoad(def.sampled_type, ptr);
const Id image = ctx.OpImage(def.image_type, object);
return image; return image;
} }
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id)); return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));

View file

@ -9,6 +9,7 @@
#include <array> #include <array>
#include <sirit/sirit.h> #include <sirit/sirit.h>
#include <ankerl/unordered_dense.h>
#include "shader_recompiler/backend/bindings.h" #include "shader_recompiler/backend/bindings.h"
#include "shader_recompiler/frontend/ir/program.h" #include "shader_recompiler/frontend/ir/program.h"
@ -366,6 +367,9 @@ public:
Id load_const_func_u32x2{}; Id load_const_func_u32x2{};
Id load_const_func_u32x4{}; Id load_const_func_u32x4{};
// Sirit::Id doesn't play nice with *::set<>
ankerl::unordered_dense::set<u32> non_uniform_ids;
private: private:
void DefineCommonTypes(const Info& info); void DefineCommonTypes(const Info& info);
void DefineCommonConstants(); void DefineCommonConstants();

View file

@ -733,9 +733,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
break; break;
} }
u32 index; u32 index;
const u32 size_shift{cbuf.count > 1 ? DynamicDescriptorSizeShift(cbuf.dynamic_offset) u32 size_shift = cbuf.count > 1 ? DynamicDescriptorSizeShift(cbuf.dynamic_offset) : DESCRIPTOR_SIZE_SHIFT;
: DESCRIPTOR_SIZE_SHIFT}; u32 count = cbuf.count;
u32 count{cbuf.count};
switch (inst->GetOpcode()) { switch (inst->GetOpcode()) {
case IR::Opcode::ImageRead: case IR::Opcode::ImageRead:
case IR::Opcode::ImageAtomicIAdd32: case IR::Opcode::ImageAtomicIAdd32:

View file

@ -267,8 +267,8 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
}; };
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, WRITE_BARRIER);
upload_cmdbuf.End(); upload_cmdbuf.End();
cmdbuf.End(); cmdbuf.End();