mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 03:18:55 +02:00
[vulkan] Fix Vulkan graphics pipeline crash when image descriptor count exceeds 64 (#3785)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3785 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev> Co-authored-by: wildcard <wildcard@eden-emu.dev> Co-committed-by: wildcard <wildcard@eden-emu.dev>
This commit is contained in:
parent
7a8176f63f
commit
0b179517b3
2 changed files with 21 additions and 13 deletions
|
|
@ -49,7 +49,7 @@ using VideoCore::Surface::PixelFormatFromDepthFormat;
|
||||||
using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
|
using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
|
||||||
|
|
||||||
constexpr size_t NUM_STAGES = Maxwell::MaxShaderStage;
|
constexpr size_t NUM_STAGES = Maxwell::MaxShaderStage;
|
||||||
constexpr size_t MAX_IMAGE_ELEMENTS = 64;
|
constexpr size_t INLINE_IMAGE_ELEMENTS = 64;
|
||||||
|
|
||||||
DescriptorLayoutBuilder MakeBuilder(const Device& device, std::span<const Shader::Info> infos) {
|
DescriptorLayoutBuilder MakeBuilder(const Device& device, std::span<const Shader::Info> infos) {
|
||||||
DescriptorLayoutBuilder builder{device};
|
DescriptorLayoutBuilder builder{device};
|
||||||
|
|
@ -264,7 +264,11 @@ GraphicsPipeline::GraphicsPipeline(
|
||||||
stage_infos[stage] = *info;
|
stage_infos[stage] = *info;
|
||||||
enabled_uniform_buffer_masks[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());
|
std::ranges::copy(info->constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin());
|
||||||
|
num_image_elements += Shader::NumDescriptors(info->texture_buffer_descriptors);
|
||||||
|
num_image_elements += Shader::NumDescriptors(info->image_buffer_descriptors);
|
||||||
num_textures += Shader::NumDescriptors(info->texture_descriptors);
|
num_textures += Shader::NumDescriptors(info->texture_descriptors);
|
||||||
|
num_image_elements += Shader::NumDescriptors(info->texture_descriptors);
|
||||||
|
num_image_elements += Shader::NumDescriptors(info->image_descriptors);
|
||||||
}
|
}
|
||||||
fragment_has_color0_output = stage_infos[NUM_STAGES - 1].stores_frag_color[0];
|
fragment_has_color0_output = stage_infos[NUM_STAGES - 1].stores_frag_color[0];
|
||||||
auto func{[this, shader_notify, &render_pass_cache, &descriptor_pool, pipeline_statistics] {
|
auto func{[this, shader_notify, &render_pass_cache, &descriptor_pool, pipeline_statistics] {
|
||||||
|
|
@ -310,10 +314,10 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) {
|
||||||
|
|
||||||
template <typename Spec>
|
template <typename Spec>
|
||||||
bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
std::array<VideoCommon::ImageViewInOut, MAX_IMAGE_ELEMENTS> views;
|
small_vector<VideoCommon::ImageViewInOut, INLINE_IMAGE_ELEMENTS> views;
|
||||||
std::array<VideoCommon::SamplerId, MAX_IMAGE_ELEMENTS> samplers;
|
small_vector<VideoCommon::SamplerId, INLINE_IMAGE_ELEMENTS> samplers;
|
||||||
size_t sampler_index{};
|
views.reserve(num_image_elements);
|
||||||
size_t view_index{};
|
samplers.reserve(num_textures);
|
||||||
|
|
||||||
texture_cache.SynchronizeGraphicsDescriptors();
|
texture_cache.SynchronizeGraphicsDescriptors();
|
||||||
|
|
||||||
|
|
@ -358,11 +362,11 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE {
|
const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE {
|
||||||
for (u32 index = 0; index < desc.count; ++index) {
|
for (u32 index = 0; index < desc.count; ++index) {
|
||||||
const auto handle{read_handle(desc, index)};
|
const auto handle{read_handle(desc, index)};
|
||||||
views[view_index++] = {
|
views.push_back({
|
||||||
.index = handle.first,
|
.index = handle.first,
|
||||||
.blacklist = blacklist,
|
.blacklist = blacklist,
|
||||||
.id = {}
|
.id = {}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
if constexpr (Spec::has_texture_buffers) {
|
if constexpr (Spec::has_texture_buffers) {
|
||||||
|
|
@ -378,10 +382,10 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
for (const auto& desc : info.texture_descriptors) {
|
for (const auto& desc : info.texture_descriptors) {
|
||||||
for (u32 index = 0; index < desc.count; ++index) {
|
for (u32 index = 0; index < desc.count; ++index) {
|
||||||
const auto handle{read_handle(desc, index)};
|
const auto handle{read_handle(desc, index)};
|
||||||
views[view_index++] = {handle.first};
|
views.push_back({handle.first});
|
||||||
|
|
||||||
VideoCommon::SamplerId sampler{texture_cache.GetGraphicsSamplerId(handle.second)};
|
VideoCommon::SamplerId sampler{texture_cache.GetGraphicsSamplerId(handle.second)};
|
||||||
samplers[sampler_index++] = sampler;
|
samplers.push_back(sampler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constexpr (Spec::has_images) {
|
if constexpr (Spec::has_images) {
|
||||||
|
|
@ -407,7 +411,9 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
if constexpr (Spec::enabled_stages[4]) {
|
if constexpr (Spec::enabled_stages[4]) {
|
||||||
config_stage(4);
|
config_stage(4);
|
||||||
}
|
}
|
||||||
texture_cache.FillGraphicsImageViews<Spec::has_images>(std::span(views.data(), view_index));
|
ASSERT(views.size() == num_image_elements);
|
||||||
|
ASSERT(samplers.size() == num_textures);
|
||||||
|
texture_cache.FillGraphicsImageViews<Spec::has_images>(std::span(views.data(), views.size()));
|
||||||
|
|
||||||
VideoCommon::ImageViewInOut* texture_buffer_it{views.data()};
|
VideoCommon::ImageViewInOut* texture_buffer_it{views.data()};
|
||||||
const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE {
|
const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE {
|
||||||
|
|
@ -501,7 +507,8 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
buffer_cache.any_buffer_uploaded = false;
|
buffer_cache.any_buffer_uploaded = false;
|
||||||
}
|
}
|
||||||
texture_cache.UpdateRenderTargets(false);
|
texture_cache.UpdateRenderTargets(false);
|
||||||
texture_cache.CheckFeedbackLoop(views);
|
texture_cache.CheckFeedbackLoop(std::span<const VideoCommon::ImageViewInOut>{views.data(),
|
||||||
|
views.size()});
|
||||||
ConfigureDraw(rescaling, render_area);
|
ConfigureDraw(rescaling, render_area);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -987,7 +994,7 @@ void GraphicsPipeline::Validate() {
|
||||||
num_images += Shader::NumDescriptors(info.texture_descriptors);
|
num_images += Shader::NumDescriptors(info.texture_descriptors);
|
||||||
num_images += Shader::NumDescriptors(info.image_descriptors);
|
num_images += Shader::NumDescriptors(info.image_descriptors);
|
||||||
}
|
}
|
||||||
ASSERT(num_images <= MAX_IMAGE_ELEMENTS);
|
ASSERT(num_images == num_image_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
|
|
@ -159,6 +159,7 @@ private:
|
||||||
std::array<Shader::Info, NUM_STAGES> stage_infos;
|
std::array<Shader::Info, NUM_STAGES> stage_infos;
|
||||||
std::array<u32, 5> enabled_uniform_buffer_masks{};
|
std::array<u32, 5> enabled_uniform_buffer_masks{};
|
||||||
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
VideoCommon::UniformBufferSizes uniform_buffer_sizes{};
|
||||||
|
size_t num_image_elements{};
|
||||||
u32 num_textures{};
|
u32 num_textures{};
|
||||||
bool fragment_has_color0_output{};
|
bool fragment_has_color0_output{};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue