From fb53c4e135e5ef1964c21fe045ed5a70197ee5e0 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 26 Jun 2026 20:24:05 -0400 Subject: [PATCH] [shader_recompiler] unify descriptor limit policy --- .../frontend/maxwell/translate_program.cpp | 23 +++++++++------- src/shader_recompiler/host_translate_info.h | 25 ++++++++++++++++++ src/shader_recompiler/ir_opt/texture_pass.cpp | 15 ++++++----- .../renderer_opengl/gl_shader_cache.cpp | 26 +++++++++++-------- .../renderer_vulkan/vk_pipeline_cache.cpp | 1 + tools/maxwell-ir/main.cpp | 1 + tools/maxwell-spirv/spirv_recompiler_impl.cpp | 1 + 7 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 705f20850a..ebc5a825dd 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp @@ -236,8 +236,11 @@ void LowerGeometryPassthrough(const IR::Program& program, const HostTranslateInf IR::Program TranslateProgram(ObjectPool& inst_pool, ObjectPool& block_pool, Environment& env, Flow::CFG& cfg, const HostTranslateInfo& host_info) { + HostTranslateInfo normalized_host_info{host_info}; + normalized_host_info.ApplyDescriptorLimitPolicy(); + IR::Program program; - program.syntax_list = BuildASL(inst_pool, block_pool, env, cfg, host_info); + program.syntax_list = BuildASL(inst_pool, block_pool, env, cfg, normalized_host_info); program.blocks = GenerateBlocks(program.syntax_list); program.post_order_blocks = PostOrder(program.syntax_list.front()); program.stage = env.ShaderStage(); @@ -260,9 +263,9 @@ IR::Program TranslateProgram(ObjectPool& inst_pool, ObjectPool> (i % 32)) & 1) == 0; } - if (!host_info.support_geometry_shader_passthrough) { + if (!normalized_host_info.support_geometry_shader_passthrough) { program.output_vertices = GetOutputTopologyVertices(program.output_topology); - LowerGeometryPassthrough(program, host_info); + LowerGeometryPassthrough(program, normalized_host_info); } } break; @@ -277,16 +280,16 @@ IR::Program TranslateProgram(ObjectPool& inst_pool, ObjectPool& inst_pool, ObjectPool& inst_pool, ObjectPool= 31 || base_offset >= max_cbuf_bytes) return 1; auto const stride = 1U << size_shift; @@ -55,7 +56,7 @@ u32 DynamicDescriptorCount(u32 base_offset, u32 size_shift, u32 max_descriptors) if (available < DESCRIPTOR_SIZE) return 1; auto const available_count = 1U + (available - DESCRIPTOR_SIZE) / stride; - return std::min(max_descriptors, available_count); + return std::min(descriptor_limit, available_count); } u32 SaturatingSub(u32 lhs, u32 rhs) { @@ -70,8 +71,9 @@ template } u32 DynamicSampledTextureCap(const Info& info, const HostTranslateInfo& host_info, u32 dynamic_arrays) { - auto const sampled_limit = std::min(host_info.max_per_stage_descriptor_sampled_images, host_info.max_descriptor_set_sampled_images); - auto const resource_limit = host_info.max_per_stage_resources; + auto const sampled_limit = (std::max)(1U, std::min(host_info.max_per_stage_descriptor_sampled_images, + host_info.max_descriptor_set_sampled_images)); + auto const resource_limit = (std::max)(1U, host_info.max_per_stage_resources); if (dynamic_arrays > 0) { auto const sampled_static_count = StaticDescriptorCount(info.texture_buffer_descriptors) + StaticDescriptorCount(info.texture_descriptors); auto const resource_static_count = @@ -444,8 +446,9 @@ std::optional TryGetConstBuffer(const IR::Inst* inst, Environme return std::nullopt; } auto const size_shift = DynamicDescriptorSizeShift(dynamic_offset); - auto const sampled_limit = (std::min)(host_info.max_per_stage_descriptor_sampled_images, host_info.max_descriptor_set_sampled_images); - auto const resource_limit = host_info.max_per_stage_resources; + auto const sampled_limit = (std::max)(1U, (std::min)(host_info.max_per_stage_descriptor_sampled_images, + host_info.max_descriptor_set_sampled_images)); + auto const resource_limit = (std::max)(1U, host_info.max_per_stage_resources); return ConstBufferAddr{ .index = index.U32(), .offset = base_offset, diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 675760d7d1..2b38b0a8a8 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -244,19 +244,22 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .max_user_clip_distances = std::min(device.GetMaxUserClipDistances(), Maxwell::Regs::NumClipDistances), }, - // TODO: proper limits? host_info{ .min_ssbo_alignment = static_cast(device.GetShaderStorageBufferAlignment()), - .max_per_stage_descriptor_sampled_images = 1024,//device.GetMaxPerStageDescriptorSampledImages(), - .max_per_stage_resources = 1024,//device.GetMaxPerStageResources(), - .max_descriptor_set_samplers = 1024,//device.GetMaxDescriptorSetSamplers(), - .max_descriptor_set_uniform_buffers = 1024,//device.GetMaxDescriptorSetUniformBuffers(), - .max_descriptor_set_uniform_buffers_dynamic = 1024,//device.GetMaxDescriptorSetUniformBuffersDynamic(), - .max_descriptor_set_storage_buffers = 1024,//device.GetMaxDescriptorSetStorageBuffers(), - .max_descriptor_set_storage_buffers_dynamic = 1024,//device.GetMaxDescriptorSetStorageBuffersDynamic(), - .max_descriptor_set_sampled_images = 1024,//device.GetMaxDescriptorSetSampledImages(), - .max_descriptor_set_storage_images = 1024,//device.GetMaxDescriptorSetStorageImages(), - .max_descriptor_set_input_attachements = 1024,//device.GetMaxDescriptorSetInputAttachments(), + .max_per_stage_descriptor_sampled_images = + Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_per_stage_resources = Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_samplers = Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_uniform_buffers = Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_uniform_buffers_dynamic = + Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_storage_buffers = Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_storage_buffers_dynamic = + Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_sampled_images = Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_storage_images = Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, + .max_descriptor_set_input_attachements = + Shader::HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, .support_float64 = true, .support_float16 = false, .support_int64 = device.HasShaderInt64(), @@ -266,6 +269,7 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(), .support_conditional_barrier = device.SupportsConditionalBarriers(), } { + host_info.ApplyDescriptorLimitPolicy(); if (use_asynchronous_shaders) { workers = CreateWorkers(); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index cb811857e4..a21924a90d 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -465,6 +465,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), .support_conditional_barrier = device.SupportsConditionalBarriers(), }; + host_info.ApplyDescriptorLimitPolicy(); if (device.GetMaxVertexInputAttributes() < Maxwell::NumVertexAttributes) { LOG_WARNING(Render_Vulkan, "maxVertexInputAttributes is too low: {} < {}", diff --git a/tools/maxwell-ir/main.cpp b/tools/maxwell-ir/main.cpp index 66aeaeac40..645816878d 100644 --- a/tools/maxwell-ir/main.cpp +++ b/tools/maxwell-ir/main.cpp @@ -44,6 +44,7 @@ int IrShaderRecompilerImpl(int argc, char *argv[]) { host_info.support_geometry_shader_passthrough = true; host_info.support_conditional_barrier = true; host_info.min_ssbo_alignment = 0; + host_info.ApplyDescriptorLimitPolicy(); auto program = Shader::Maxwell::TranslateProgram(inst_pool, block_pool, env, cfg, host_info); auto const dumped_ir = Shader::IR::DumpProgram(program); std::printf("%s\n", dumped_ir.c_str()); diff --git a/tools/maxwell-spirv/spirv_recompiler_impl.cpp b/tools/maxwell-spirv/spirv_recompiler_impl.cpp index 55830abe39..9dae69df91 100644 --- a/tools/maxwell-spirv/spirv_recompiler_impl.cpp +++ b/tools/maxwell-spirv/spirv_recompiler_impl.cpp @@ -52,6 +52,7 @@ int SpirvShaderRecompilerImpl(int argc, char *argv[]) { host_info.support_geometry_shader_passthrough = true; host_info.support_conditional_barrier = true; host_info.min_ssbo_alignment = 0; + host_info.ApplyDescriptorLimitPolicy(); auto program = Shader::Maxwell::TranslateProgram(inst_pool, block_pool, env, cfg, host_info); // IR::Program TranslateProgram(ObjectPool& inst_pool, ObjectPool& block_pool,