diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index d1eb9cd935..eb7d5b9241 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -64,7 +64,7 @@ void Name(EmitContext& ctx, Id object, std::string_view format_str, Args&&... ar EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_info_, const Info& info_, Bindings& binding_) : Sirit::Module(profile_.supported_spirv), info{info_}, runtime_info{runtime_info_}, - profile{profile_}, stage{info.stage}, binding{binding_}, sharp_buf(info) { + profile{profile_}, stage{info.stage}, binding{binding_} { AddCapability(spv::Capability::Shader); DefineArithmeticTypes(); DefineInterfaces(); @@ -461,7 +461,7 @@ void EmitContext::DefineBuffers() { const auto storage_class = spv::StorageClass::Uniform; const Id pointer_type = TypePointer(storage_class, data_type); const Id record_array_type{ - TypeArray(U32[1], ConstU32(static_cast(sharp_buf.num_dwords())))}; + TypeArray(U32[1], ConstU32(static_cast(info.flattened_ud_buf.num_dwords())))}; const Id struct_type{define_struct(record_array_type, false, "srt_flatbuf_ty")}; @@ -480,7 +480,7 @@ void EmitContext::DefineBuffers() { } for (const auto& desc : info.buffers) { - const auto sharp = desc.GetSharp(sharp_buf); + const auto sharp = desc.GetSharp(info); const bool is_storage = desc.IsStorage(sharp); const u32 array_size = sharp.NumDwords() != 0 ? sharp.NumDwords() : MaxUboDwords; const auto* data_types = True(desc.used_types & IR::Type::F32) ? &F32 : &U32; @@ -610,7 +610,7 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) { } Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) { - const auto image = ctx.getSharpBuf().ReadUdSharp(desc.sharp_idx); + const auto image = ctx.info.ReadUdSharp(desc.sharp_idx); const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown; const u32 sampled = desc.is_storage ? 2 : 1; switch (desc.type) { diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 89e310af3d..fb30a5dd63 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -126,10 +126,6 @@ class EmitContext final : public Sirit::Module { return ConstantComposite(type, constituents); } - const Shader::FlatSharpBuffer& getSharpBuf() const { - return sharp_buf; - } - const Info& info; const RuntimeInfo& runtime_info; const Profile& profile; @@ -265,7 +261,6 @@ class EmitContext final : public Sirit::Module { SpirvAttribute GetAttributeInfo(AmdGpu::NumberFormat fmt, Id id, u32 num_components, bool output); - Shader::FlatSharpBuffer sharp_buf; }; } // namespace Shader::Backend::SPIRV diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 40281f1b0f..f71268c8a2 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -50,7 +50,7 @@ struct BufferResource { return buffer.GetSize() > MaxUboSize || is_written || is_gds_buffer; } - constexpr AmdGpu::Buffer GetSharp(const FlatSharpBuffer& sharp_buf) const noexcept; + constexpr AmdGpu::Buffer GetSharp(const Shader::Info& info) const noexcept; }; using BufferResourceList = boost::container::small_vector; @@ -59,7 +59,7 @@ struct TextureBufferResource { AmdGpu::NumberFormat nfmt; bool is_written{}; - constexpr AmdGpu::Buffer GetSharp(const FlatSharpBuffer& sharp_buf) const noexcept; + constexpr AmdGpu::Buffer GetSharp(const Shader::Info& info) const noexcept; }; using TextureBufferResourceList = boost::container::small_vector; @@ -72,7 +72,7 @@ struct ImageResource { bool is_atomic{}; bool is_array{}; - constexpr AmdGpu::Image GetSharp(const FlatSharpBuffer& sharp_buf) const noexcept; + constexpr AmdGpu::Image GetSharp(const Shader::Info& info) const noexcept; }; using ImageResourceList = boost::container::small_vector; @@ -82,7 +82,7 @@ struct SamplerResource { u32 associated_image : 4; u32 disable_aniso : 1; - constexpr AmdGpu::Sampler GetSharp(const FlatSharpBuffer& sharp_buf) const noexcept; + constexpr AmdGpu::Sampler GetSharp(const Shader::Info& info) const noexcept; }; using SamplerResourceList = boost::container::small_vector; @@ -178,6 +178,7 @@ struct Info { SamplerResourceList samplers; PersistentSrtInfo srt_info; + FlattenedUserDataBuffer flattened_ud_buf; std::span user_data; Stage stage; @@ -208,7 +209,11 @@ struct Info { : stage{stage_}, pgm_hash{params.hash}, pgm_base{params.Base()}, user_data{params.user_data} {} - // TODO rename or remove + template + inline T ReadUdSharp(u32 sharp_idx) const noexcept { + return flattened_ud_buf.ReadUdSharp(sharp_idx); + } + template T ReadUdReg(u32 ptr_index, u32 dword_offset) const noexcept { T data; @@ -227,7 +232,6 @@ struct Info { const u32 index = std::countr_zero(mask); ASSERT(bnd.user_data < NumUserDataRegs && index < NumUserDataRegs); mask &= ~(1U << index); - // Need to understand this TODO push.ud_regs[bnd.user_data++] = user_data[index]; } } @@ -252,34 +256,32 @@ struct Info { return {vertex_offset, instance_offset}; } - void RunSrtWalker(FlatSharpBuffer& sharp_buf) const { - sharp_buf.resize(srt_info.flattened_bufsize_dw); + void RefreshFlatBuf() { + flattened_ud_buf.resize(srt_info.flattened_bufsize_dw); ASSERT(user_data.size() <= NumUserDataRegs); - std::memcpy(sharp_buf.data(), user_data.data(), user_data.size_bytes()); + std::memcpy(flattened_ud_buf.data(), user_data.data(), user_data.size_bytes()); // Run the JIT program to walk the SRT and write the leaves to a flat buffer PFN_SrtWalker pfn = srt_info.walker.getCode(); if (pfn) { - pfn(user_data.data(), sharp_buf.data()); + pfn(user_data.data(), flattened_ud_buf.data()); } } }; -constexpr AmdGpu::Buffer BufferResource::GetSharp(const FlatSharpBuffer& sharp_buf) const noexcept { - return inline_cbuf ? inline_cbuf : sharp_buf.ReadUdSharp(sharp_idx); +constexpr AmdGpu::Buffer BufferResource::GetSharp(const Shader::Info& info) const noexcept { + return inline_cbuf ? inline_cbuf : info.ReadUdSharp(sharp_idx); } -constexpr AmdGpu::Buffer TextureBufferResource::GetSharp( - const FlatSharpBuffer& sharp_buf) const noexcept { - return sharp_buf.ReadUdSharp(sharp_idx); +constexpr AmdGpu::Buffer TextureBufferResource::GetSharp(const Shader::Info& info) const noexcept { + return info.ReadUdSharp(sharp_idx); } -constexpr AmdGpu::Image ImageResource::GetSharp(const FlatSharpBuffer& sharp_buf) const noexcept { - return sharp_buf.ReadUdSharp(sharp_idx); +constexpr AmdGpu::Image ImageResource::GetSharp(const Shader::Info& info) const noexcept { + return info.ReadUdSharp(sharp_idx); } -constexpr AmdGpu::Sampler SamplerResource::GetSharp( - const FlatSharpBuffer& sharp_buf) const noexcept { - return inline_sampler ? inline_sampler : sharp_buf.ReadUdSharp(sharp_idx); +constexpr AmdGpu::Sampler SamplerResource::GetSharp(const Shader::Info& info) const noexcept { + return inline_sampler ? inline_sampler : info.ReadUdSharp(sharp_idx); } } // namespace Shader diff --git a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp index 166f3be8fc..968a651931 100644 --- a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp +++ b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include #include "common/config.h" @@ -24,7 +25,6 @@ using namespace Xbyak::util; // TODO make sure no problems with identity and Insts being used in maps -// TODO refactor, copied from signals.cpp static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t codesize) { #ifdef ARCH_X86_64 using namespace Common::FS; @@ -63,18 +63,16 @@ using namespace Shader; struct PassInfo { // map offset to inst - using PtrUserList = boost::container::map; - - // TODO use flat_* for some of these (needs ext-boost update) + using PtrUserList = boost::container::flat_map; Optimization::SrtGvnTable gvn_table; // keys are GetUserData or ReadConst instructions that are used as pointers std::unordered_map pointer_uses; // GetUserData instructions corresponding to sgpr_base of SRT roots - boost::container::map srt_roots; + boost::container::small_flat_map srt_roots; // pick a single inst for a given value number - boost::container::map vn_to_inst; + std::unordered_map vn_to_inst; // Bumped during codegen to assign offsets to readconsts u32 dst_off_dw; @@ -97,14 +95,6 @@ struct PassInfo { }; } // namespace -namespace Shader { -// Hacky. TODO refactor info RuntimeInfo or smtn -FlatSharpBuffer::FlatSharpBuffer(const Info& info) { - info.RunSrtWalker(*this); -} - -} // namespace Shader - namespace Shader::Optimization { namespace { @@ -270,6 +260,8 @@ void FlattenExtendedUserdataPass(IR::Program& program) { IR::Inst* original = pass_info.DeduplicateInstruction(readconst); readconst->SetFlags(original->Flags()); } + + info.RefreshFlatBuf(); } } // namespace Shader::Optimization \ No newline at end of file diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index afdb35987a..cbe609bd14 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -172,7 +172,6 @@ class Descriptors { if (desc.is_gds_buffer && existing.is_gds_buffer) { return true; } - // need to learn about inline_cbug TODO return desc.sharp_idx == existing.sharp_idx && desc.inline_cbuf == existing.inline_cbuf; })}; auto& buffer = buffer_resources[index]; @@ -317,22 +316,21 @@ s32 TryHandleInlineCbuf(IR::Inst& inst, Info& info, Descriptors& descriptors, cbuf = std::bit_cast(buffer); // Assign a binding to this sharp. return descriptors.Add(BufferResource{ - // TODO handle this .sharp_idx = std::numeric_limits::max(), .used_types = BufferDataType(inst, cbuf.GetNumberFmt()), .inline_cbuf = cbuf, }); } -void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors, - Shader::FlatSharpBuffer sharp_buf) { +void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info, + Descriptors& descriptors) { s32 binding{}; AmdGpu::Buffer buffer; if (binding = TryHandleInlineCbuf(inst, info, descriptors, buffer); binding == -1) { IR::Inst* handle = inst.Arg(0).InstRecursive(); IR::Inst* producer = handle->Arg(0).InstRecursive(); const auto sharp = TrackSharp(producer, info); - buffer = sharp_buf.ReadUdSharp(sharp); + buffer = info.ReadUdSharp(sharp); binding = descriptors.Add(BufferResource{ .sharp_idx = sharp, .used_types = BufferDataType(inst, buffer.GetNumberFmt()), @@ -390,11 +388,11 @@ void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descri } void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info, - Descriptors& descriptors, Shader::FlatSharpBuffer sharp_buf) { + Descriptors& descriptors) { const IR::Inst* handle = inst.Arg(0).InstRecursive(); const IR::Inst* producer = handle->Arg(0).InstRecursive(); const auto sharp = TrackSharp(producer, info); - const auto buffer = sharp_buf.ReadUdSharp(sharp); + const auto buffer = info.ReadUdSharp(sharp); const s32 binding = descriptors.Add(TextureBufferResource{ .sharp_idx = sharp, .nfmt = buffer.GetNumberFmt(), @@ -433,8 +431,7 @@ IR::Value PatchCubeCoord(IR::IREmitter& ir, const IR::Value& s, const IR::Value& } } -void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors, - Shader::FlatSharpBuffer sharp_buf) { +void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors) { const auto pred = [](const IR::Inst* inst) -> std::optional { const auto opcode = inst->GetOpcode(); if (opcode == IR::Opcode::CompositeConstructU32x2 || // IMAGE_SAMPLE (image+sampler) @@ -453,7 +450,7 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip // Read image sharp. const auto tsharp = TrackSharp(tsharp_handle, info); const auto inst_info = inst.Flags(); - auto image = sharp_buf.ReadUdSharp(tsharp); + auto image = info.ReadUdSharp(tsharp); if (!image.Valid()) { LOG_ERROR(Render_Vulkan, "Shader compiled with unbound image!"); image = AmdGpu::Image::Null(); @@ -481,7 +478,6 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip if (handle.IsImmediate()) { LOG_WARNING(Render_Vulkan, "Inline sampler detected"); return descriptors.Add(SamplerResource{ - // TODO handle this .sharp_idx = std::numeric_limits::max(), .inline_sampler = AmdGpu::Sampler{.raw0 = handle.U32()}, }); @@ -640,21 +636,20 @@ void PatchDataRingInstruction(IR::Block& block, IR::Inst& inst, Info& info, void ResourceTrackingPass(IR::Program& program) { // Iterate resource instructions and patch them after finding the sharp. auto& info = program.info; - Shader::FlatSharpBuffer sharp_buf(info); Descriptors descriptors{info}; for (IR::Block* const block : program.blocks) { for (IR::Inst& inst : block->Instructions()) { if (IsBufferInstruction(inst)) { - PatchBufferInstruction(*block, inst, info, descriptors, sharp_buf); + PatchBufferInstruction(*block, inst, info, descriptors); continue; } if (IsTextureBufferInstruction(inst)) { - PatchTextureBufferInstruction(*block, inst, info, descriptors, sharp_buf); + PatchTextureBufferInstruction(*block, inst, info, descriptors); continue; } if (IsImageInstruction(inst)) { - PatchImageInstruction(*block, inst, info, descriptors, sharp_buf); + PatchImageInstruction(*block, inst, info, descriptors); continue; } if (IsDataRingInstruction(inst)) { diff --git a/src/shader_recompiler/ir/passes/srt.h b/src/shader_recompiler/ir/passes/srt.h index fa14c0c797..0e2d5a2d74 100644 --- a/src/shader_recompiler/ir/passes/srt.h +++ b/src/shader_recompiler/ir/passes/srt.h @@ -3,7 +3,6 @@ #pragma once -#include #include #include #include @@ -12,24 +11,15 @@ #include #include -#include #include "common/alignment.h" #include "common/assert.h" #include "common/types.h" -#include "shader_recompiler/ir/reg.h" -#include "shader_recompiler/ir/value.h" #include "xbyak/xbyak.h" namespace Shader { -// Refactor FlatSharpBuffer so we only rerun walker once per draw. Stuff it in -// runtime_info? -struct Info; - -class FlatSharpBuffer { +class FlattenedUserDataBuffer { public: - FlatSharpBuffer(const Info& info); - template T ReadUdSharp(u32 sharp_idx) const noexcept { return *reinterpret_cast(&buf[sharp_idx]); @@ -47,14 +37,16 @@ class FlatSharpBuffer { return buf.data(); } + const u32* data() const { + return buf.data(); + } + void resize(size_t new_size_dw) { buf.resize(new_size_dw); } private: - // TODO aligned_alloc with ubo min alignment (dynamic) - // 256 for now to be conservative - boost::container::vector> buf; + std::vector buf; }; typedef void(__attribute__((sysv_abi)) * PFN_SrtWalker)(const u32* /*user_data*/, @@ -110,7 +102,6 @@ struct PersistentSrtInfo { PersistentSrtInfo() : flattened_bufsize_dw(/*NumUserDataRegs*/ 16) {} // Special case when fetch shader uses step rates. - // Need to reserve space for those V#s, and find them in SrtWalker function struct SrtSharpReservation { u32 sgpr_base; u32 dword_offset; diff --git a/src/shader_recompiler/specialization.h b/src/shader_recompiler/specialization.h index 1acc0315cc..c25c611e44 100644 --- a/src/shader_recompiler/specialization.h +++ b/src/shader_recompiler/specialization.h @@ -8,6 +8,7 @@ #include "common/types.h" #include "shader_recompiler/backend/bindings.h" #include "shader_recompiler/info.h" +#include "shader_recompiler/ir/passes/srt.h" namespace Shader { @@ -47,11 +48,10 @@ struct StageSpecialization { boost::container::small_vector tex_buffers; boost::container::small_vector images; Backend::Bindings start{}; - FlatSharpBuffer sharp_buf; explicit StageSpecialization(const Shader::Info& info_, RuntimeInfo runtime_info_, Backend::Bindings start_) - : info{&info_}, runtime_info{runtime_info_}, start{start_}, sharp_buf(*info) { + : info{&info_}, runtime_info{runtime_info_}, start{start_} { u32 binding{}; if (info->has_readconst) { binding++; @@ -76,7 +76,7 @@ struct StageSpecialization { void ForEachSharp(u32& binding, auto& spec_list, auto& desc_list, auto&& func) { for (const auto& desc : desc_list) { auto& spec = spec_list.emplace_back(); - const auto sharp = desc.GetSharp(sharp_buf); + const auto sharp = desc.GetSharp(*info); if (!sharp) { binding++; continue; diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 90a6a9d808..e635c142e5 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -24,8 +24,6 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler .pName = "main", }; - Shader::FlatSharpBuffer sharp_buf(*info); - u32 binding{}; boost::container::small_vector bindings; @@ -38,7 +36,7 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler }); } for (const auto& buffer : info->buffers) { - const auto sharp = buffer.GetSharp(sharp_buf); + const auto sharp = buffer.GetSharp(*info); bindings.push_back({ .binding = binding++, .descriptorType = buffer.IsStorage(sharp) ? vk::DescriptorType::eStorageBuffer @@ -133,19 +131,18 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache, image_infos.clear(); - Shader::FlatSharpBuffer sharp_buf(*info); - info->PushUd(binding, push_data); if (info->has_readconst) { // Bind the flattened user data buf as a UBO (TODO rename "sharp"_buf) - const auto [vk_buffer, offset] = buffer_cache.ObtainHostUBO( - reinterpret_cast(sharp_buf.data()), sharp_buf.size_bytes()); + const auto [vk_buffer, offset] = + buffer_cache.ObtainHostUBO(reinterpret_cast(info->flattened_ud_buf.data()), + info->flattened_ud_buf.size_bytes()); // Should already be aligned to UBO min alignment const u32 alignment = instance.UniformMinAlignment(); ASSERT(offset % alignment == 0); push_data.AddOffset(binding.buffer, 0); // not necessary I think - buffer_infos.emplace_back(vk_buffer->Handle(), offset, sharp_buf.size_bytes()); + buffer_infos.emplace_back(vk_buffer->Handle(), offset, info->flattened_ud_buf.size_bytes()); set_writes.push_back({ .dstSet = VK_NULL_HANDLE, .dstBinding = binding.unified++, @@ -162,7 +159,7 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache, auto* vk_buffer = buffer_cache.GetGdsBuffer(); buffer_infos.emplace_back(vk_buffer->Handle(), 0, vk_buffer->SizeBytes()); } else { - const auto vsharp = desc.GetSharp(sharp_buf); + const auto vsharp = desc.GetSharp(*info); is_storage = desc.IsStorage(vsharp); const VAddr address = vsharp.base_address; // Most of the time when a metadata is updated with a shader it gets cleared. It means @@ -206,7 +203,7 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache, const auto null_buffer_view = instance.IsNullDescriptorSupported() ? VK_NULL_HANDLE : buffer_cache.NullBufferView(); for (const auto& desc : info->texture_buffers) { - const auto vsharp = desc.GetSharp(sharp_buf); + const auto vsharp = desc.GetSharp(*info); vk::BufferView& buffer_view = buffer_views.emplace_back(null_buffer_view); const u32 size = vsharp.GetSize(); if (vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid && size != 0) { @@ -255,10 +252,10 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache, ++binding.buffer; } - BindTextures(texture_cache, *info, binding, set_writes, sharp_buf); + BindTextures(texture_cache, *info, binding, set_writes); for (const auto& sampler : info->samplers) { - const auto ssharp = sampler.GetSharp(sharp_buf); + const auto ssharp = sampler.GetSharp(*info); if (ssharp.force_degamma) { LOG_WARNING(Render_Vulkan, "Texture requires gamma correction"); } diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 9f7ccb1883..b68f0a976c 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -327,7 +327,6 @@ void GraphicsPipeline::BuildDescSetLayout() { if (!stage) { continue; } - Shader::FlatSharpBuffer sharp_buf(*stage); if (stage->has_readconst) { bindings.push_back({ @@ -338,7 +337,7 @@ void GraphicsPipeline::BuildDescSetLayout() { }); } for (const auto& buffer : stage->buffers) { - const auto sharp = buffer.GetSharp(sharp_buf); + const auto sharp = buffer.GetSharp(*stage); bindings.push_back({ .binding = binding++, .descriptorType = buffer.IsStorage(sharp) ? vk::DescriptorType::eStorageBuffer @@ -407,7 +406,6 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, if (!stage) { continue; } - Shader::FlatSharpBuffer sharp_buf(*stage); if (stage->uses_step_rates) { push_data.step0 = regs.vgt_instance_step_rate_0; push_data.step1 = regs.vgt_instance_step_rate_1; @@ -416,12 +414,14 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, if (stage->has_readconst) { // Bind the flattened user data buf as a UBO (TODO rename "sharp"_buf) - const auto [vk_buffer, offset] = buffer_cache.ObtainHostUBO( - reinterpret_cast(sharp_buf.data()), sharp_buf.size_bytes()); + const auto [vk_buffer, offset] = + buffer_cache.ObtainHostUBO(reinterpret_cast(stage->flattened_ud_buf.data()), + stage->flattened_ud_buf.size_bytes()); // Should already be aligned to UBO min alignment const u32 alignment = instance.UniformMinAlignment(); ASSERT(offset % alignment == 0); - buffer_infos.emplace_back(vk_buffer->Handle(), offset, sharp_buf.size_bytes()); + buffer_infos.emplace_back(vk_buffer->Handle(), offset, + stage->flattened_ud_buf.size_bytes()); set_writes.push_back({ .dstSet = VK_NULL_HANDLE, .dstBinding = binding.unified++, @@ -433,7 +433,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, ++binding.buffer; } for (const auto& buffer : stage->buffers) { - const auto vsharp = buffer.GetSharp(sharp_buf); + const auto vsharp = buffer.GetSharp(*stage); const bool is_storage = buffer.IsStorage(vsharp); if (vsharp && vsharp.GetSize() > 0) { const VAddr address = vsharp.base_address; @@ -471,7 +471,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, const auto null_buffer_view = instance.IsNullDescriptorSupported() ? VK_NULL_HANDLE : buffer_cache.NullBufferView(); for (const auto& desc : stage->texture_buffers) { - const auto vsharp = desc.GetSharp(sharp_buf); + const auto vsharp = desc.GetSharp(*stage); vk::BufferView& buffer_view = buffer_views.emplace_back(null_buffer_view); const u32 size = vsharp.GetSize(); if (vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid && size != 0) { @@ -510,15 +510,15 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, ++binding.buffer; } - BindTextures(texture_cache, *stage, binding, set_writes, sharp_buf); + BindTextures(texture_cache, *stage, binding, set_writes); for (const auto& sampler : stage->samplers) { - auto ssharp = sampler.GetSharp(sharp_buf); + auto ssharp = sampler.GetSharp(*stage); if (ssharp.force_degamma) { LOG_WARNING(Render_Vulkan, "Texture requires gamma correction"); } if (sampler.disable_aniso) { - const auto& tsharp = stage->images[sampler.associated_image].GetSharp(sharp_buf); + const auto& tsharp = stage->images[sampler.associated_image].GetSharp(*stage); if (tsharp.base_level == 0 && tsharp.last_level == 0) { ssharp.max_aniso.Assign(AmdGpu::AnisoRatio::One); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 20226e2138..ab3f9691a0 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -441,7 +441,8 @@ std::tuple PipelineCache::GetProgram } Program* program = it_pgm->second; - const auto& info = program->info; + auto& info = program->info; + info.RefreshFlatBuf(); const auto spec = Shader::StageSpecialization(info, runtime_info, binding); size_t perm_idx = program->modules.size(); vk::ShaderModule module{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_common.cpp b/src/video_core/renderer_vulkan/vk_pipeline_common.cpp index 057ec4a482..61e564150a 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_common.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_common.cpp @@ -20,14 +20,14 @@ Pipeline::Pipeline(const Instance& instance_, Scheduler& scheduler_, DescriptorH Pipeline::~Pipeline() = default; void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage, - Shader::Backend::Bindings& binding, DescriptorWrites& set_writes, - const Shader::FlatSharpBuffer& sharp_buf) const { + Shader::Backend::Bindings& binding, + DescriptorWrites& set_writes) const { using ImageBindingInfo = std::tuple; boost::container::static_vector image_bindings; for (const auto& image_desc : stage.images) { - const auto tsharp = image_desc.GetSharp(sharp_buf); + const auto tsharp = image_desc.GetSharp(stage); if (tsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) { VideoCore::ImageInfo image_info{tsharp, image_desc}; const auto image_id = texture_cache.FindImage(image_info); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_common.h b/src/video_core/renderer_vulkan/vk_pipeline_common.h index 0b68cf6241..ab99e7b33f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_common.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_common.h @@ -34,8 +34,7 @@ class Pipeline { using DescriptorWrites = boost::container::small_vector; void BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage, - Shader::Backend::Bindings& binding, DescriptorWrites& set_writes, - const Shader::FlatSharpBuffer& sharp_buf) const; + Shader::Backend::Bindings& binding, DescriptorWrites& set_writes) const; protected: const Instance& instance;