buffer_cache: Reduce uniform buffer size from shader usage
Increases performance significantly on certain titles.
This commit is contained in:
parent
e57ee3b7fd
commit
4a2361a1e2
|
@ -560,32 +560,45 @@ void VisitUsages(Info& info, IR::Inst& inst) {
|
||||||
case IR::Opcode::GetCbufU32:
|
case IR::Opcode::GetCbufU32:
|
||||||
case IR::Opcode::GetCbufF32:
|
case IR::Opcode::GetCbufF32:
|
||||||
case IR::Opcode::GetCbufU32x2: {
|
case IR::Opcode::GetCbufU32x2: {
|
||||||
if (const IR::Value index{inst.Arg(0)}; index.IsImmediate()) {
|
const IR::Value index{inst.Arg(0)};
|
||||||
AddConstantBufferDescriptor(info, index.U32(), 1);
|
const IR::Value offset{inst.Arg(1)};
|
||||||
} else {
|
if (!index.IsImmediate()) {
|
||||||
throw NotImplementedException("Constant buffer with non-immediate index");
|
throw NotImplementedException("Constant buffer with non-immediate index");
|
||||||
}
|
}
|
||||||
|
AddConstantBufferDescriptor(info, index.U32(), 1);
|
||||||
|
u32 element_size{};
|
||||||
switch (inst.GetOpcode()) {
|
switch (inst.GetOpcode()) {
|
||||||
case IR::Opcode::GetCbufU8:
|
case IR::Opcode::GetCbufU8:
|
||||||
case IR::Opcode::GetCbufS8:
|
case IR::Opcode::GetCbufS8:
|
||||||
info.used_constant_buffer_types |= IR::Type::U8;
|
info.used_constant_buffer_types |= IR::Type::U8;
|
||||||
|
element_size = 1;
|
||||||
break;
|
break;
|
||||||
case IR::Opcode::GetCbufU16:
|
case IR::Opcode::GetCbufU16:
|
||||||
case IR::Opcode::GetCbufS16:
|
case IR::Opcode::GetCbufS16:
|
||||||
info.used_constant_buffer_types |= IR::Type::U16;
|
info.used_constant_buffer_types |= IR::Type::U16;
|
||||||
|
element_size = 2;
|
||||||
break;
|
break;
|
||||||
case IR::Opcode::GetCbufU32:
|
case IR::Opcode::GetCbufU32:
|
||||||
info.used_constant_buffer_types |= IR::Type::U32;
|
info.used_constant_buffer_types |= IR::Type::U32;
|
||||||
|
element_size = 4;
|
||||||
break;
|
break;
|
||||||
case IR::Opcode::GetCbufF32:
|
case IR::Opcode::GetCbufF32:
|
||||||
info.used_constant_buffer_types |= IR::Type::F32;
|
info.used_constant_buffer_types |= IR::Type::F32;
|
||||||
|
element_size = 4;
|
||||||
break;
|
break;
|
||||||
case IR::Opcode::GetCbufU32x2:
|
case IR::Opcode::GetCbufU32x2:
|
||||||
info.used_constant_buffer_types |= IR::Type::U32x2;
|
info.used_constant_buffer_types |= IR::Type::U32x2;
|
||||||
|
element_size = 8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
u32& size{info.constant_buffer_used_sizes[index.U32()]};
|
||||||
|
if (offset.IsImmediate()) {
|
||||||
|
size = std::max(size, offset.U32() + element_size);
|
||||||
|
} else {
|
||||||
|
size = 0x10'000;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IR::Opcode::BindlessImageSampleImplicitLod:
|
case IR::Opcode::BindlessImageSampleImplicitLod:
|
||||||
|
|
|
@ -197,6 +197,7 @@ struct Info {
|
||||||
IR::Type used_storage_buffer_types{};
|
IR::Type used_storage_buffer_types{};
|
||||||
|
|
||||||
u32 constant_buffer_mask{};
|
u32 constant_buffer_mask{};
|
||||||
|
std::array<u32, MAX_CBUFS> constant_buffer_used_sizes{};
|
||||||
u32 nvn_buffer_base{};
|
u32 nvn_buffer_base{};
|
||||||
std::bitset<16> nvn_buffer_used{};
|
std::bitset<16> nvn_buffer_used{};
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ MICROPROFILE_DECLARE(GPU_DownloadMemory);
|
||||||
using BufferId = SlotId;
|
using BufferId = SlotId;
|
||||||
|
|
||||||
using VideoCore::Surface::PixelFormat;
|
using VideoCore::Surface::PixelFormat;
|
||||||
|
using namespace Common::Literals;
|
||||||
|
|
||||||
constexpr u32 NUM_VERTEX_BUFFERS = 32;
|
constexpr u32 NUM_VERTEX_BUFFERS = 32;
|
||||||
constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4;
|
constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4;
|
||||||
|
@ -53,7 +54,8 @@ constexpr u32 NUM_STORAGE_BUFFERS = 16;
|
||||||
constexpr u32 NUM_TEXTURE_BUFFERS = 16;
|
constexpr u32 NUM_TEXTURE_BUFFERS = 16;
|
||||||
constexpr u32 NUM_STAGES = 5;
|
constexpr u32 NUM_STAGES = 5;
|
||||||
|
|
||||||
using namespace Common::Literals;
|
using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;
|
||||||
|
using ComputeUniformBufferSizes = std::array<u32, NUM_COMPUTE_UNIFORM_BUFFERS>;
|
||||||
|
|
||||||
template <typename P>
|
template <typename P>
|
||||||
class BufferCache {
|
class BufferCache {
|
||||||
|
@ -142,9 +144,10 @@ public:
|
||||||
|
|
||||||
void BindHostComputeBuffers();
|
void BindHostComputeBuffers();
|
||||||
|
|
||||||
void SetEnabledUniformBuffers(const std::array<u32, NUM_STAGES>& mask);
|
void SetUniformBuffersState(const std::array<u32, NUM_STAGES>& mask,
|
||||||
|
const UniformBufferSizes* sizes);
|
||||||
|
|
||||||
void SetEnabledComputeUniformBuffers(u32 enabled);
|
void SetComputeUniformBufferState(u32 mask, const ComputeUniformBufferSizes* sizes);
|
||||||
|
|
||||||
void UnbindGraphicsStorageBuffers(size_t stage);
|
void UnbindGraphicsStorageBuffers(size_t stage);
|
||||||
|
|
||||||
|
@ -384,8 +387,11 @@ private:
|
||||||
std::array<Binding, NUM_STORAGE_BUFFERS> compute_storage_buffers;
|
std::array<Binding, NUM_STORAGE_BUFFERS> compute_storage_buffers;
|
||||||
std::array<TextureBufferBinding, NUM_TEXTURE_BUFFERS> compute_texture_buffers;
|
std::array<TextureBufferBinding, NUM_TEXTURE_BUFFERS> compute_texture_buffers;
|
||||||
|
|
||||||
std::array<u32, NUM_STAGES> enabled_uniform_buffers{};
|
std::array<u32, NUM_STAGES> enabled_uniform_buffer_masks{};
|
||||||
u32 enabled_compute_uniform_buffers = 0;
|
u32 enabled_compute_uniform_buffer_mask = 0;
|
||||||
|
|
||||||
|
const UniformBufferSizes* uniform_buffer_sizes{};
|
||||||
|
const ComputeUniformBufferSizes* compute_uniform_buffer_sizes{};
|
||||||
|
|
||||||
std::array<u32, NUM_STAGES> enabled_storage_buffers{};
|
std::array<u32, NUM_STAGES> enabled_storage_buffers{};
|
||||||
std::array<u32, NUM_STAGES> written_storage_buffers{};
|
std::array<u32, NUM_STAGES> written_storage_buffers{};
|
||||||
|
@ -670,18 +676,22 @@ void BufferCache<P>::BindHostComputeBuffers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::SetEnabledUniformBuffers(const std::array<u32, NUM_STAGES>& mask) {
|
void BufferCache<P>::SetUniformBuffersState(const std::array<u32, NUM_STAGES>& mask,
|
||||||
|
const UniformBufferSizes* sizes) {
|
||||||
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
|
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
|
||||||
if (enabled_uniform_buffers != mask) {
|
if (enabled_uniform_buffer_masks != mask) {
|
||||||
dirty_uniform_buffers.fill(~u32{0});
|
dirty_uniform_buffers.fill(~u32{0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enabled_uniform_buffers = mask;
|
enabled_uniform_buffer_masks = mask;
|
||||||
|
uniform_buffer_sizes = sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::SetEnabledComputeUniformBuffers(u32 enabled) {
|
void BufferCache<P>::SetComputeUniformBufferState(u32 mask,
|
||||||
enabled_compute_uniform_buffers = enabled;
|
const ComputeUniformBufferSizes* sizes) {
|
||||||
|
enabled_compute_uniform_buffer_mask = mask;
|
||||||
|
compute_uniform_buffer_sizes = sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
@ -984,7 +994,7 @@ void BufferCache<P>::BindHostGraphicsUniformBuffers(size_t stage) {
|
||||||
dirty = std::exchange(dirty_uniform_buffers[stage], 0);
|
dirty = std::exchange(dirty_uniform_buffers[stage], 0);
|
||||||
}
|
}
|
||||||
u32 binding_index = 0;
|
u32 binding_index = 0;
|
||||||
ForEachEnabledBit(enabled_uniform_buffers[stage], [&](u32 index) {
|
ForEachEnabledBit(enabled_uniform_buffer_masks[stage], [&](u32 index) {
|
||||||
const bool needs_bind = ((dirty >> index) & 1) != 0;
|
const bool needs_bind = ((dirty >> index) & 1) != 0;
|
||||||
BindHostGraphicsUniformBuffer(stage, index, binding_index, needs_bind);
|
BindHostGraphicsUniformBuffer(stage, index, binding_index, needs_bind);
|
||||||
if constexpr (NEEDS_BIND_UNIFORM_INDEX) {
|
if constexpr (NEEDS_BIND_UNIFORM_INDEX) {
|
||||||
|
@ -998,7 +1008,7 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
|
||||||
bool needs_bind) {
|
bool needs_bind) {
|
||||||
const Binding& binding = uniform_buffers[stage][index];
|
const Binding& binding = uniform_buffers[stage][index];
|
||||||
const VAddr cpu_addr = binding.cpu_addr;
|
const VAddr cpu_addr = binding.cpu_addr;
|
||||||
const u32 size = binding.size;
|
const u32 size = std::min(binding.size, (*uniform_buffer_sizes)[stage][index]);
|
||||||
Buffer& buffer = slot_buffers[binding.buffer_id];
|
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||||
TouchBuffer(buffer);
|
TouchBuffer(buffer);
|
||||||
const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID &&
|
const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID &&
|
||||||
|
@ -1113,11 +1123,11 @@ void BufferCache<P>::BindHostComputeUniformBuffers() {
|
||||||
dirty_uniform_buffers.fill(~u32{0});
|
dirty_uniform_buffers.fill(~u32{0});
|
||||||
}
|
}
|
||||||
u32 binding_index = 0;
|
u32 binding_index = 0;
|
||||||
ForEachEnabledBit(enabled_compute_uniform_buffers, [&](u32 index) {
|
ForEachEnabledBit(enabled_compute_uniform_buffer_mask, [&](u32 index) {
|
||||||
const Binding& binding = compute_uniform_buffers[index];
|
const Binding& binding = compute_uniform_buffers[index];
|
||||||
Buffer& buffer = slot_buffers[binding.buffer_id];
|
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||||
TouchBuffer(buffer);
|
TouchBuffer(buffer);
|
||||||
const u32 size = binding.size;
|
const u32 size = std::min(binding.size, (*compute_uniform_buffer_sizes)[index]);
|
||||||
SynchronizeBuffer(buffer, binding.cpu_addr, size);
|
SynchronizeBuffer(buffer, binding.cpu_addr, size);
|
||||||
|
|
||||||
const u32 offset = buffer.Offset(binding.cpu_addr);
|
const u32 offset = buffer.Offset(binding.cpu_addr);
|
||||||
|
@ -1261,7 +1271,7 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) {
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::UpdateUniformBuffers(size_t stage) {
|
void BufferCache<P>::UpdateUniformBuffers(size_t stage) {
|
||||||
ForEachEnabledBit(enabled_uniform_buffers[stage], [&](u32 index) {
|
ForEachEnabledBit(enabled_uniform_buffer_masks[stage], [&](u32 index) {
|
||||||
Binding& binding = uniform_buffers[stage][index];
|
Binding& binding = uniform_buffers[stage][index];
|
||||||
if (binding.buffer_id) {
|
if (binding.buffer_id) {
|
||||||
// Already updated
|
// Already updated
|
||||||
|
@ -1334,7 +1344,7 @@ void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) {
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::UpdateComputeUniformBuffers() {
|
void BufferCache<P>::UpdateComputeUniformBuffers() {
|
||||||
ForEachEnabledBit(enabled_compute_uniform_buffers, [&](u32 index) {
|
ForEachEnabledBit(enabled_compute_uniform_buffer_mask, [&](u32 index) {
|
||||||
Binding& binding = compute_uniform_buffers[index];
|
Binding& binding = compute_uniform_buffers[index];
|
||||||
binding = NULL_BINDING;
|
binding = NULL_BINDING;
|
||||||
const auto& launch_desc = kepler_compute.launch_description;
|
const auto& launch_desc = kepler_compute.launch_description;
|
||||||
|
|
|
@ -43,6 +43,8 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
|
||||||
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
|
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
|
||||||
kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_},
|
kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_},
|
||||||
source_program{std::move(source_program_)}, assembly_program{std::move(assembly_program_)} {
|
source_program{std::move(source_program_)}, assembly_program{std::move(assembly_program_)} {
|
||||||
|
std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
|
||||||
|
uniform_buffer_sizes.begin());
|
||||||
|
|
||||||
num_texture_buffers = AccumulateCount(info.texture_buffer_descriptors);
|
num_texture_buffers = AccumulateCount(info.texture_buffer_descriptors);
|
||||||
num_image_buffers = AccumulateCount(info.image_buffer_descriptors);
|
num_image_buffers = AccumulateCount(info.image_buffer_descriptors);
|
||||||
|
@ -63,7 +65,7 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputePipeline::Configure() {
|
void ComputePipeline::Configure() {
|
||||||
buffer_cache.SetEnabledComputeUniformBuffers(info.constant_buffer_mask);
|
buffer_cache.SetComputeUniformBufferState(info.constant_buffer_mask, &uniform_buffer_sizes);
|
||||||
buffer_cache.UnbindComputeStorageBuffers();
|
buffer_cache.UnbindComputeStorageBuffers();
|
||||||
size_t ssbo_index{};
|
size_t ssbo_index{};
|
||||||
for (const auto& desc : info.storage_buffers_descriptors) {
|
for (const auto& desc : info.storage_buffers_descriptors) {
|
||||||
|
|
|
@ -72,6 +72,7 @@ private:
|
||||||
Shader::Info info;
|
Shader::Info info;
|
||||||
OGLProgram source_program;
|
OGLProgram source_program;
|
||||||
OGLAssemblyProgram assembly_program;
|
OGLAssemblyProgram assembly_program;
|
||||||
|
VideoCommon::ComputeUniformBufferSizes uniform_buffer_sizes{};
|
||||||
|
|
||||||
u32 num_texture_buffers{};
|
u32 num_texture_buffers{};
|
||||||
u32 num_image_buffers{};
|
u32 num_image_buffers{};
|
||||||
|
|
|
@ -60,6 +60,14 @@ std::pair<GLint, GLint> TransformFeedbackEnum(u8 location) {
|
||||||
UNIMPLEMENTED_MSG("index={}", index);
|
UNIMPLEMENTED_MSG("index={}", index);
|
||||||
return {GL_POSITION, 0};
|
return {GL_POSITION, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Spec {
|
||||||
|
static constexpr std::array<bool, 5> enabled_stages{true, true, true, true, true};
|
||||||
|
static constexpr bool has_storage_buffers = true;
|
||||||
|
static constexpr bool has_texture_buffers = true;
|
||||||
|
static constexpr bool has_image_buffers = true;
|
||||||
|
static constexpr bool has_images = true;
|
||||||
|
};
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
size_t GraphicsPipelineKey::Hash() const noexcept {
|
size_t GraphicsPipelineKey::Hash() const noexcept {
|
||||||
|
@ -100,7 +108,8 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
|
||||||
base_uniform_bindings[stage + 1] += AccumulateCount(info.constant_buffer_descriptors);
|
base_uniform_bindings[stage + 1] += AccumulateCount(info.constant_buffer_descriptors);
|
||||||
base_storage_bindings[stage + 1] += AccumulateCount(info.storage_buffers_descriptors);
|
base_storage_bindings[stage + 1] += AccumulateCount(info.storage_buffers_descriptors);
|
||||||
}
|
}
|
||||||
enabled_uniform_buffers[stage] = info.constant_buffer_mask;
|
enabled_uniform_buffer_masks[stage] = info.constant_buffer_mask;
|
||||||
|
std::ranges::copy(info.constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin());
|
||||||
|
|
||||||
const u32 num_tex_buffer_bindings{AccumulateCount(info.texture_buffer_descriptors)};
|
const u32 num_tex_buffer_bindings{AccumulateCount(info.texture_buffer_descriptors)};
|
||||||
num_texture_buffers[stage] += num_tex_buffer_bindings;
|
num_texture_buffers[stage] += num_tex_buffer_bindings;
|
||||||
|
@ -130,14 +139,6 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Spec {
|
|
||||||
static constexpr std::array<bool, 5> enabled_stages{true, true, true, true, true};
|
|
||||||
static constexpr bool has_storage_buffers = true;
|
|
||||||
static constexpr bool has_texture_buffers = true;
|
|
||||||
static constexpr bool has_image_buffers = true;
|
|
||||||
static constexpr bool has_images = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
void GraphicsPipeline::Configure(bool is_indexed) {
|
void GraphicsPipeline::Configure(bool is_indexed) {
|
||||||
std::array<ImageId, MAX_TEXTURES + MAX_IMAGES> image_view_ids;
|
std::array<ImageId, MAX_TEXTURES + MAX_IMAGES> image_view_ids;
|
||||||
std::array<u32, MAX_TEXTURES + MAX_IMAGES> image_view_indices;
|
std::array<u32, MAX_TEXTURES + MAX_IMAGES> image_view_indices;
|
||||||
|
@ -147,7 +148,7 @@ void GraphicsPipeline::Configure(bool is_indexed) {
|
||||||
|
|
||||||
texture_cache.SynchronizeGraphicsDescriptors();
|
texture_cache.SynchronizeGraphicsDescriptors();
|
||||||
|
|
||||||
buffer_cache.SetEnabledUniformBuffers(enabled_uniform_buffers);
|
buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes);
|
||||||
buffer_cache.runtime.SetBaseUniformBindings(base_uniform_bindings);
|
buffer_cache.runtime.SetBaseUniformBindings(base_uniform_bindings);
|
||||||
buffer_cache.runtime.SetBaseStorageBindings(base_storage_bindings);
|
buffer_cache.runtime.SetBaseStorageBindings(base_storage_bindings);
|
||||||
buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers);
|
buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers);
|
||||||
|
|
|
@ -99,7 +99,8 @@ private:
|
||||||
u32 enabled_stages_mask{};
|
u32 enabled_stages_mask{};
|
||||||
|
|
||||||
std::array<Shader::Info, 5> stage_infos{};
|
std::array<Shader::Info, 5> stage_infos{};
|
||||||
std::array<u32, 5> enabled_uniform_buffers{};
|
std::array<u32, 5> enabled_uniform_buffer_masks{};
|
||||||
|
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
||||||
std::array<u32, 5> base_uniform_bindings{};
|
std::array<u32, 5> base_uniform_bindings{};
|
||||||
std::array<u32, 5> base_storage_bindings{};
|
std::array<u32, 5> base_storage_bindings{};
|
||||||
std::array<u32, 5> num_texture_buffers{};
|
std::array<u32, 5> num_texture_buffers{};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
@ -27,6 +28,9 @@ ComputePipeline::ComputePipeline(const Device& device_, DescriptorPool& descript
|
||||||
vk::ShaderModule spv_module_)
|
vk::ShaderModule spv_module_)
|
||||||
: device{device_}, update_descriptor_queue{update_descriptor_queue_}, info{info_},
|
: device{device_}, update_descriptor_queue{update_descriptor_queue_}, info{info_},
|
||||||
spv_module(std::move(spv_module_)) {
|
spv_module(std::move(spv_module_)) {
|
||||||
|
std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
|
||||||
|
uniform_buffer_sizes.begin());
|
||||||
|
|
||||||
auto func{[this, &descriptor_pool] {
|
auto func{[this, &descriptor_pool] {
|
||||||
DescriptorLayoutBuilder builder{device.GetLogical()};
|
DescriptorLayoutBuilder builder{device.GetLogical()};
|
||||||
builder.Add(info, VK_SHADER_STAGE_COMPUTE_BIT);
|
builder.Add(info, VK_SHADER_STAGE_COMPUTE_BIT);
|
||||||
|
@ -75,7 +79,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
|
||||||
BufferCache& buffer_cache, TextureCache& texture_cache) {
|
BufferCache& buffer_cache, TextureCache& texture_cache) {
|
||||||
update_descriptor_queue.Acquire();
|
update_descriptor_queue.Acquire();
|
||||||
|
|
||||||
buffer_cache.SetEnabledComputeUniformBuffers(info.constant_buffer_mask);
|
buffer_cache.SetComputeUniformBufferState(info.constant_buffer_mask, &uniform_buffer_sizes);
|
||||||
buffer_cache.UnbindComputeStorageBuffers();
|
buffer_cache.UnbindComputeStorageBuffers();
|
||||||
size_t ssbo_index{};
|
size_t ssbo_index{};
|
||||||
for (const auto& desc : info.storage_buffers_descriptors) {
|
for (const auto& desc : info.storage_buffers_descriptors) {
|
||||||
|
|
|
@ -44,6 +44,8 @@ private:
|
||||||
VKUpdateDescriptorQueue& update_descriptor_queue;
|
VKUpdateDescriptorQueue& update_descriptor_queue;
|
||||||
Shader::Info info;
|
Shader::Info info;
|
||||||
|
|
||||||
|
VideoCommon::ComputeUniformBufferSizes uniform_buffer_sizes{};
|
||||||
|
|
||||||
vk::ShaderModule spv_module;
|
vk::ShaderModule spv_module;
|
||||||
vk::DescriptorSetLayout descriptor_set_layout;
|
vk::DescriptorSetLayout descriptor_set_layout;
|
||||||
DescriptorAllocator descriptor_allocator;
|
DescriptorAllocator descriptor_allocator;
|
||||||
|
|
|
@ -218,10 +218,14 @@ GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_,
|
||||||
update_descriptor_queue{update_descriptor_queue_}, spv_modules{std::move(stages)} {
|
update_descriptor_queue{update_descriptor_queue_}, spv_modules{std::move(stages)} {
|
||||||
std::ranges::transform(infos, stage_infos.begin(),
|
std::ranges::transform(infos, stage_infos.begin(),
|
||||||
[](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
|
[](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
|
||||||
std::ranges::transform(infos, enabled_uniform_buffers.begin(), [](const Shader::Info* info) {
|
for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
|
||||||
return info ? info->constant_buffer_mask : 0;
|
const Shader::Info* const info{infos[stage]};
|
||||||
});
|
if (!info) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
enabled_uniform_buffer_masks[stage] = info->constant_buffer_mask;
|
||||||
|
std::ranges::copy(info->constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin());
|
||||||
|
}
|
||||||
auto func{[this, &render_pass_cache, &descriptor_pool] {
|
auto func{[this, &render_pass_cache, &descriptor_pool] {
|
||||||
DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)};
|
DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)};
|
||||||
descriptor_set_layout = builder.CreateDescriptorSetLayout();
|
descriptor_set_layout = builder.CreateDescriptorSetLayout();
|
||||||
|
@ -262,7 +266,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
|
|
||||||
texture_cache.SynchronizeGraphicsDescriptors();
|
texture_cache.SynchronizeGraphicsDescriptors();
|
||||||
|
|
||||||
buffer_cache.SetEnabledUniformBuffers(enabled_uniform_buffers);
|
buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes);
|
||||||
|
|
||||||
const auto& regs{maxwell3d.regs};
|
const auto& regs{maxwell3d.regs};
|
||||||
const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
|
const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
|
||||||
|
|
|
@ -130,7 +130,8 @@ private:
|
||||||
std::array<vk::ShaderModule, NUM_STAGES> spv_modules;
|
std::array<vk::ShaderModule, NUM_STAGES> spv_modules;
|
||||||
|
|
||||||
std::array<Shader::Info, NUM_STAGES> stage_infos;
|
std::array<Shader::Info, NUM_STAGES> stage_infos;
|
||||||
std::array<u32, 5> enabled_uniform_buffers{};
|
std::array<u32, 5> enabled_uniform_buffer_masks{};
|
||||||
|
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
||||||
|
|
||||||
vk::DescriptorSetLayout descriptor_set_layout;
|
vk::DescriptorSetLayout descriptor_set_layout;
|
||||||
DescriptorAllocator descriptor_allocator;
|
DescriptorAllocator descriptor_allocator;
|
||||||
|
|
Reference in New Issue