diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_compute_pipeline.cpp | 36 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | 42 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/pipeline_helper.h | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | 60 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 54 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 41 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 3 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_view_base.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_view_base.h | 4 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 47 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 30 | ||||
| -rw-r--r-- | src/video_core/texture_cache/types.h | 7 |
16 files changed, 192 insertions, 192 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index 19c8ca7b2..ab2baefbb 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp | |||
| @@ -79,8 +79,7 @@ void ComputePipeline::Configure() { | |||
| 79 | } | 79 | } |
| 80 | texture_cache.SynchronizeComputeDescriptors(); | 80 | texture_cache.SynchronizeComputeDescriptors(); |
| 81 | 81 | ||
| 82 | std::array<ImageViewId, MAX_TEXTURES + MAX_IMAGES> image_view_ids; | 82 | boost::container::static_vector<VideoCommon::ImageViewInOut, MAX_TEXTURES + MAX_IMAGES> views; |
| 83 | boost::container::static_vector<u32, MAX_TEXTURES + MAX_IMAGES> image_view_indices; | ||
| 84 | std::array<GLuint, MAX_TEXTURES> samplers; | 83 | std::array<GLuint, MAX_TEXTURES> samplers; |
| 85 | std::array<GLuint, MAX_TEXTURES> textures; | 84 | std::array<GLuint, MAX_TEXTURES> textures; |
| 86 | std::array<GLuint, MAX_IMAGES> images; | 85 | std::array<GLuint, MAX_IMAGES> images; |
| @@ -110,33 +109,39 @@ void ComputePipeline::Configure() { | |||
| 110 | } | 109 | } |
| 111 | return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); | 110 | return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); |
| 112 | }}; | 111 | }}; |
| 113 | const auto add_image{[&](const auto& desc) { | 112 | const auto add_image{[&](const auto& desc, bool blacklist) { |
| 114 | for (u32 index = 0; index < desc.count; ++index) { | 113 | for (u32 index = 0; index < desc.count; ++index) { |
| 115 | const auto handle{read_handle(desc, index)}; | 114 | const auto handle{read_handle(desc, index)}; |
| 116 | image_view_indices.push_back(handle.first); | 115 | views.push_back({ |
| 116 | .index = handle.first, | ||
| 117 | .blacklist = blacklist, | ||
| 118 | .id = {}, | ||
| 119 | }); | ||
| 117 | } | 120 | } |
| 118 | }}; | 121 | }}; |
| 119 | for (const auto& desc : info.texture_buffer_descriptors) { | 122 | for (const auto& desc : info.texture_buffer_descriptors) { |
| 120 | for (u32 index = 0; index < desc.count; ++index) { | 123 | for (u32 index = 0; index < desc.count; ++index) { |
| 121 | const auto handle{read_handle(desc, index)}; | 124 | const auto handle{read_handle(desc, index)}; |
| 122 | image_view_indices.push_back(handle.first); | 125 | views.push_back({handle.first}); |
| 123 | samplers[sampler_binding++] = 0; | 126 | samplers[sampler_binding++] = 0; |
| 124 | } | 127 | } |
| 125 | } | 128 | } |
| 126 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | 129 | for (const auto& desc : info.image_buffer_descriptors) { |
| 130 | add_image(desc, false); | ||
| 131 | } | ||
| 127 | for (const auto& desc : info.texture_descriptors) { | 132 | for (const auto& desc : info.texture_descriptors) { |
| 128 | for (u32 index = 0; index < desc.count; ++index) { | 133 | for (u32 index = 0; index < desc.count; ++index) { |
| 129 | const auto handle{read_handle(desc, index)}; | 134 | const auto handle{read_handle(desc, index)}; |
| 130 | image_view_indices.push_back(handle.first); | 135 | views.push_back({handle.first}); |
| 131 | 136 | ||
| 132 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); | 137 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); |
| 133 | samplers[sampler_binding++] = sampler->Handle(); | 138 | samplers[sampler_binding++] = sampler->Handle(); |
| 134 | } | 139 | } |
| 135 | } | 140 | } |
| 136 | std::ranges::for_each(info.image_descriptors, add_image); | 141 | for (const auto& desc : info.image_descriptors) { |
| 137 | 142 | add_image(desc, true); | |
| 138 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 143 | } |
| 139 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); | 144 | texture_cache.FillComputeImageViews(std::span(views.data(), views.size())); |
| 140 | 145 | ||
| 141 | if (assembly_program.handle != 0) { | 146 | if (assembly_program.handle != 0) { |
| 142 | program_manager.BindComputeAssemblyProgram(assembly_program.handle); | 147 | program_manager.BindComputeAssemblyProgram(assembly_program.handle); |
| @@ -152,7 +157,7 @@ void ComputePipeline::Configure() { | |||
| 152 | if constexpr (is_image) { | 157 | if constexpr (is_image) { |
| 153 | is_written = desc.is_written; | 158 | is_written = desc.is_written; |
| 154 | } | 159 | } |
| 155 | ImageView& image_view{texture_cache.GetImageView(image_view_ids[texbuf_index])}; | 160 | ImageView& image_view{texture_cache.GetImageView(views[texbuf_index].id)}; |
| 156 | buffer_cache.BindComputeTextureBuffer(texbuf_index, image_view.GpuAddr(), | 161 | buffer_cache.BindComputeTextureBuffer(texbuf_index, image_view.GpuAddr(), |
| 157 | image_view.BufferSize(), image_view.format, | 162 | image_view.BufferSize(), image_view.format, |
| 158 | is_written, is_image); | 163 | is_written, is_image); |
| @@ -168,19 +173,20 @@ void ComputePipeline::Configure() { | |||
| 168 | buffer_cache.runtime.SetImagePointers(textures.data(), images.data()); | 173 | buffer_cache.runtime.SetImagePointers(textures.data(), images.data()); |
| 169 | buffer_cache.BindHostComputeBuffers(); | 174 | buffer_cache.BindHostComputeBuffers(); |
| 170 | 175 | ||
| 171 | const ImageId* views_it{image_view_ids.data() + num_texture_buffers + num_image_buffers}; | 176 | const VideoCommon::ImageViewInOut* views_it{views.data() + num_texture_buffers + |
| 177 | num_image_buffers}; | ||
| 172 | texture_binding += num_texture_buffers; | 178 | texture_binding += num_texture_buffers; |
| 173 | image_binding += num_image_buffers; | 179 | image_binding += num_image_buffers; |
| 174 | 180 | ||
| 175 | for (const auto& desc : info.texture_descriptors) { | 181 | for (const auto& desc : info.texture_descriptors) { |
| 176 | for (u32 index = 0; index < desc.count; ++index) { | 182 | for (u32 index = 0; index < desc.count; ++index) { |
| 177 | ImageView& image_view{texture_cache.GetImageView(*(views_it++))}; | 183 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; |
| 178 | textures[texture_binding++] = image_view.Handle(desc.type); | 184 | textures[texture_binding++] = image_view.Handle(desc.type); |
| 179 | } | 185 | } |
| 180 | } | 186 | } |
| 181 | for (const auto& desc : info.image_descriptors) { | 187 | for (const auto& desc : info.image_descriptors) { |
| 182 | for (u32 index = 0; index < desc.count; ++index) { | 188 | for (u32 index = 0; index < desc.count; ++index) { |
| 183 | ImageView& image_view{texture_cache.GetImageView(*(views_it++))}; | 189 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; |
| 184 | if (desc.is_written) { | 190 | if (desc.is_written) { |
| 185 | texture_cache.MarkModification(image_view.image_id); | 191 | texture_cache.MarkModification(image_view.image_id); |
| 186 | } | 192 | } |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 43ab5c03b..0bbda7951 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include "video_core/renderer_opengl/gl_shader_util.h" | 15 | #include "video_core/renderer_opengl/gl_shader_util.h" |
| 16 | #include "video_core/renderer_opengl/gl_state_tracker.h" | 16 | #include "video_core/renderer_opengl/gl_state_tracker.h" |
| 17 | #include "video_core/shader_notify.h" | 17 | #include "video_core/shader_notify.h" |
| 18 | #include "video_core/texture_cache/texture_cache_base.h" | 18 | #include "video_core/texture_cache/texture_cache.h" |
| 19 | 19 | ||
| 20 | #if defined(_MSC_VER) && defined(NDEBUG) | 20 | #if defined(_MSC_VER) && defined(NDEBUG) |
| 21 | #define LAMBDA_FORCEINLINE [[msvc::forceinline]] | 21 | #define LAMBDA_FORCEINLINE [[msvc::forceinline]] |
| @@ -280,10 +280,9 @@ GraphicsPipeline::GraphicsPipeline( | |||
| 280 | 280 | ||
| 281 | template <typename Spec> | 281 | template <typename Spec> |
| 282 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | 282 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { |
| 283 | std::array<ImageId, MAX_TEXTURES + MAX_IMAGES> image_view_ids; | 283 | std::array<VideoCommon::ImageViewInOut, MAX_TEXTURES + MAX_IMAGES> views; |
| 284 | std::array<u32, MAX_TEXTURES + MAX_IMAGES> image_view_indices; | ||
| 285 | std::array<GLuint, MAX_TEXTURES> samplers; | 284 | std::array<GLuint, MAX_TEXTURES> samplers; |
| 286 | size_t image_view_index{}; | 285 | size_t views_index{}; |
| 287 | GLsizei sampler_binding{}; | 286 | GLsizei sampler_binding{}; |
| 288 | 287 | ||
| 289 | texture_cache.SynchronizeGraphicsDescriptors(); | 288 | texture_cache.SynchronizeGraphicsDescriptors(); |
| @@ -328,30 +327,34 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 328 | } | 327 | } |
| 329 | return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); | 328 | return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); |
| 330 | }}; | 329 | }}; |
| 331 | const auto add_image{[&](const auto& desc) { | 330 | const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE { |
| 332 | for (u32 index = 0; index < desc.count; ++index) { | 331 | for (u32 index = 0; index < desc.count; ++index) { |
| 333 | const auto handle{read_handle(desc, index)}; | 332 | const auto handle{read_handle(desc, index)}; |
| 334 | image_view_indices[image_view_index++] = handle.first; | 333 | views[views_index++] = { |
| 334 | .index = handle.first, | ||
| 335 | .blacklist = blacklist, | ||
| 336 | .id = {}, | ||
| 337 | }; | ||
| 335 | } | 338 | } |
| 336 | }}; | 339 | }}; |
| 337 | if constexpr (Spec::has_texture_buffers) { | 340 | if constexpr (Spec::has_texture_buffers) { |
| 338 | for (const auto& desc : info.texture_buffer_descriptors) { | 341 | for (const auto& desc : info.texture_buffer_descriptors) { |
| 339 | for (u32 index = 0; index < desc.count; ++index) { | 342 | for (u32 index = 0; index < desc.count; ++index) { |
| 340 | const auto handle{read_handle(desc, index)}; | 343 | const auto handle{read_handle(desc, index)}; |
| 341 | image_view_indices[image_view_index++] = handle.first; | 344 | views[views_index++] = {handle.first}; |
| 342 | samplers[sampler_binding++] = 0; | 345 | samplers[sampler_binding++] = 0; |
| 343 | } | 346 | } |
| 344 | } | 347 | } |
| 345 | } | 348 | } |
| 346 | if constexpr (Spec::has_image_buffers) { | 349 | if constexpr (Spec::has_image_buffers) { |
| 347 | for (const auto& desc : info.image_buffer_descriptors) { | 350 | for (const auto& desc : info.image_buffer_descriptors) { |
| 348 | add_image(desc); | 351 | add_image(desc, false); |
| 349 | } | 352 | } |
| 350 | } | 353 | } |
| 351 | for (const auto& desc : info.texture_descriptors) { | 354 | for (const auto& desc : info.texture_descriptors) { |
| 352 | for (u32 index = 0; index < desc.count; ++index) { | 355 | for (u32 index = 0; index < desc.count; ++index) { |
| 353 | const auto handle{read_handle(desc, index)}; | 356 | const auto handle{read_handle(desc, index)}; |
| 354 | image_view_indices[image_view_index++] = handle.first; | 357 | views[views_index++] = {handle.first}; |
| 355 | 358 | ||
| 356 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; | 359 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; |
| 357 | samplers[sampler_binding++] = sampler->Handle(); | 360 | samplers[sampler_binding++] = sampler->Handle(); |
| @@ -359,7 +362,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 359 | } | 362 | } |
| 360 | if constexpr (Spec::has_images) { | 363 | if constexpr (Spec::has_images) { |
| 361 | for (const auto& desc : info.image_descriptors) { | 364 | for (const auto& desc : info.image_descriptors) { |
| 362 | add_image(desc); | 365 | add_image(desc, true); |
| 363 | } | 366 | } |
| 364 | } | 367 | } |
| 365 | }}; | 368 | }}; |
| @@ -378,13 +381,12 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 378 | if constexpr (Spec::enabled_stages[4]) { | 381 | if constexpr (Spec::enabled_stages[4]) { |
| 379 | config_stage(4); | 382 | config_stage(4); |
| 380 | } | 383 | } |
| 381 | const std::span indices_span(image_view_indices.data(), image_view_index); | 384 | texture_cache.FillGraphicsImageViews<Spec::has_images>(std::span(views.data(), views_index)); |
| 382 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | ||
| 383 | 385 | ||
| 384 | texture_cache.UpdateRenderTargets(false); | 386 | texture_cache.UpdateRenderTargets(false); |
| 385 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); | 387 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); |
| 386 | 388 | ||
| 387 | ImageId* texture_buffer_index{image_view_ids.data()}; | 389 | VideoCommon::ImageViewInOut* texture_buffer_it{views.data()}; |
| 388 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { | 390 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 389 | size_t index{}; | 391 | size_t index{}; |
| 390 | const auto add_buffer{[&](const auto& desc) { | 392 | const auto add_buffer{[&](const auto& desc) { |
| @@ -394,12 +396,12 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 394 | if constexpr (is_image) { | 396 | if constexpr (is_image) { |
| 395 | is_written = desc.is_written; | 397 | is_written = desc.is_written; |
| 396 | } | 398 | } |
| 397 | ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)}; | 399 | ImageView& image_view{texture_cache.GetImageView(texture_buffer_it->id)}; |
| 398 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), | 400 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), |
| 399 | image_view.BufferSize(), image_view.format, | 401 | image_view.BufferSize(), image_view.format, |
| 400 | is_written, is_image); | 402 | is_written, is_image); |
| 401 | ++index; | 403 | ++index; |
| 402 | ++texture_buffer_index; | 404 | ++texture_buffer_it; |
| 403 | } | 405 | } |
| 404 | }}; | 406 | }}; |
| 405 | const Shader::Info& info{stage_infos[stage]}; | 407 | const Shader::Info& info{stage_infos[stage]}; |
| @@ -415,9 +417,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 415 | add_buffer(desc); | 417 | add_buffer(desc); |
| 416 | } | 418 | } |
| 417 | } | 419 | } |
| 418 | texture_buffer_index += Shader::NumDescriptors(info.texture_descriptors); | 420 | texture_buffer_it += Shader::NumDescriptors(info.texture_descriptors); |
| 419 | if constexpr (Spec::has_images) { | 421 | if constexpr (Spec::has_images) { |
| 420 | texture_buffer_index += Shader::NumDescriptors(info.image_descriptors); | 422 | texture_buffer_it += Shader::NumDescriptors(info.image_descriptors); |
| 421 | } | 423 | } |
| 422 | }}; | 424 | }}; |
| 423 | if constexpr (Spec::enabled_stages[0]) { | 425 | if constexpr (Spec::enabled_stages[0]) { |
| @@ -446,7 +448,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 446 | } else { | 448 | } else { |
| 447 | program_manager.BindSourcePrograms(source_programs); | 449 | program_manager.BindSourcePrograms(source_programs); |
| 448 | } | 450 | } |
| 449 | const ImageId* views_it{image_view_ids.data()}; | 451 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 450 | GLsizei texture_binding = 0; | 452 | GLsizei texture_binding = 0; |
| 451 | GLsizei image_binding = 0; | 453 | GLsizei image_binding = 0; |
| 452 | std::array<GLuint, MAX_TEXTURES> textures; | 454 | std::array<GLuint, MAX_TEXTURES> textures; |
| @@ -464,13 +466,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 464 | const auto& info{stage_infos[stage]}; | 466 | const auto& info{stage_infos[stage]}; |
| 465 | for (const auto& desc : info.texture_descriptors) { | 467 | for (const auto& desc : info.texture_descriptors) { |
| 466 | for (u32 index = 0; index < desc.count; ++index) { | 468 | for (u32 index = 0; index < desc.count; ++index) { |
| 467 | ImageView& image_view{texture_cache.GetImageView(*(views_it++))}; | 469 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; |
| 468 | textures[texture_binding++] = image_view.Handle(desc.type); | 470 | textures[texture_binding++] = image_view.Handle(desc.type); |
| 469 | } | 471 | } |
| 470 | } | 472 | } |
| 471 | for (const auto& desc : info.image_descriptors) { | 473 | for (const auto& desc : info.image_descriptors) { |
| 472 | for (u32 index = 0; index < desc.count; ++index) { | 474 | for (u32 index = 0; index < desc.count; ++index) { |
| 473 | ImageView& image_view{texture_cache.GetImageView(*(views_it++))}; | 475 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; |
| 474 | if (desc.is_written) { | 476 | if (desc.is_written) { |
| 475 | texture_cache.MarkModification(image_view.image_id); | 477 | texture_cache.MarkModification(image_view.image_id); |
| 476 | } | 478 | } |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 5e2695576..5d14bfc97 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -472,11 +472,7 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& | |||
| 472 | set_view(Shader::TextureType::ColorArray1D, null_image_1d_array.handle); | 472 | set_view(Shader::TextureType::ColorArray1D, null_image_1d_array.handle); |
| 473 | set_view(Shader::TextureType::ColorArray2D, null_image_view_2d_array.handle); | 473 | set_view(Shader::TextureType::ColorArray2D, null_image_view_2d_array.handle); |
| 474 | set_view(Shader::TextureType::ColorArrayCube, null_image_cube_array.handle); | 474 | set_view(Shader::TextureType::ColorArrayCube, null_image_cube_array.handle); |
| 475 | } | ||
| 476 | |||
| 477 | TextureCacheRuntime::~TextureCacheRuntime() = default; | ||
| 478 | 475 | ||
| 479 | void TextureCacheRuntime::Init() { | ||
| 480 | resolution = Settings::values.resolution_info; | 476 | resolution = Settings::values.resolution_info; |
| 481 | is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0; | 477 | is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0; |
| 482 | if (is_rescaling_on) { | 478 | if (is_rescaling_on) { |
| @@ -485,6 +481,8 @@ void TextureCacheRuntime::Init() { | |||
| 485 | } | 481 | } |
| 486 | } | 482 | } |
| 487 | 483 | ||
| 484 | TextureCacheRuntime::~TextureCacheRuntime() = default; | ||
| 485 | |||
| 488 | void TextureCacheRuntime::Finish() { | 486 | void TextureCacheRuntime::Finish() { |
| 489 | glFinish(); | 487 | glFinish(); |
| 490 | } | 488 | } |
| @@ -685,6 +683,8 @@ Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, | |||
| 685 | } | 683 | } |
| 686 | } | 684 | } |
| 687 | 685 | ||
| 686 | Image::Image(const VideoCommon::NullImageParams& params) : VideoCommon::ImageBase{params} {} | ||
| 687 | |||
| 688 | Image::~Image() = default; | 688 | Image::~Image() = default; |
| 689 | 689 | ||
| 690 | void Image::UploadMemory(const ImageBufferMap& map, | 690 | void Image::UploadMemory(const ImageBufferMap& map, |
| @@ -1076,7 +1076,7 @@ ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, | |||
| 1076 | const VideoCommon::ImageViewInfo& view_info) | 1076 | const VideoCommon::ImageViewInfo& view_info) |
| 1077 | : VideoCommon::ImageViewBase{info, view_info} {} | 1077 | : VideoCommon::ImageViewBase{info, view_info} {} |
| 1078 | 1078 | ||
| 1079 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageParams& params) | 1079 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params) |
| 1080 | : VideoCommon::ImageViewBase{params}, views{runtime.null_image_views} {} | 1080 | : VideoCommon::ImageViewBase{params}, views{runtime.null_image_views} {} |
| 1081 | 1081 | ||
| 1082 | GLuint ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) { | 1082 | GLuint ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) { |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 787b63e87..e76ec522a 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -73,8 +73,6 @@ public: | |||
| 73 | StateTracker& state_tracker); | 73 | StateTracker& state_tracker); |
| 74 | ~TextureCacheRuntime(); | 74 | ~TextureCacheRuntime(); |
| 75 | 75 | ||
| 76 | void Init(); | ||
| 77 | |||
| 78 | void Finish(); | 76 | void Finish(); |
| 79 | 77 | ||
| 80 | ImageBufferMap UploadStagingBuffer(size_t size); | 78 | ImageBufferMap UploadStagingBuffer(size_t size); |
| @@ -167,6 +165,7 @@ class Image : public VideoCommon::ImageBase { | |||
| 167 | public: | 165 | public: |
| 168 | explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, | 166 | explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, |
| 169 | VAddr cpu_addr); | 167 | VAddr cpu_addr); |
| 168 | explicit Image(const VideoCommon::NullImageParams&); | ||
| 170 | 169 | ||
| 171 | ~Image(); | 170 | ~Image(); |
| 172 | 171 | ||
| @@ -223,7 +222,7 @@ public: | |||
| 223 | const VideoCommon::ImageViewInfo&, GPUVAddr); | 222 | const VideoCommon::ImageViewInfo&, GPUVAddr); |
| 224 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, | 223 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, |
| 225 | const VideoCommon::ImageViewInfo& view_info); | 224 | const VideoCommon::ImageViewInfo& view_info); |
| 226 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageParams&); | 225 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&); |
| 227 | 226 | ||
| 228 | [[nodiscard]] GLuint StorageView(Shader::TextureType texture_type, | 227 | [[nodiscard]] GLuint StorageView(Shader::TextureType texture_type, |
| 229 | Shader::ImageFormat image_format); | 228 | Shader::ImageFormat image_format); |
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 7ba6078df..bf18b34d1 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h | |||
| @@ -156,28 +156,27 @@ private: | |||
| 156 | u32 texture_bit{1u}; | 156 | u32 texture_bit{1u}; |
| 157 | }; | 157 | }; |
| 158 | 158 | ||
| 159 | inline void PushImageDescriptors(const Shader::Info& info, const VkSampler*& samplers, | 159 | inline void PushImageDescriptors(TextureCache& texture_cache, |
| 160 | const ImageId*& image_view_ids, TextureCache& texture_cache, | ||
| 161 | VKUpdateDescriptorQueue& update_descriptor_queue, | 160 | VKUpdateDescriptorQueue& update_descriptor_queue, |
| 162 | RescalingPushConstant& rescaling) { | 161 | const Shader::Info& info, RescalingPushConstant& rescaling, |
| 163 | static constexpr VideoCommon::ImageViewId NULL_IMAGE_VIEW_ID{0}; | 162 | const VkSampler*& samplers, |
| 164 | image_view_ids += Shader::NumDescriptors(info.texture_buffer_descriptors); | 163 | const VideoCommon::ImageViewInOut*& views) { |
| 165 | image_view_ids += Shader::NumDescriptors(info.image_buffer_descriptors); | 164 | views += Shader::NumDescriptors(info.texture_buffer_descriptors); |
| 165 | views += Shader::NumDescriptors(info.image_buffer_descriptors); | ||
| 166 | for (const auto& desc : info.texture_descriptors) { | 166 | for (const auto& desc : info.texture_descriptors) { |
| 167 | for (u32 index = 0; index < desc.count; ++index) { | 167 | for (u32 index = 0; index < desc.count; ++index) { |
| 168 | const VideoCommon::ImageViewId image_view_id{*(image_view_ids++)}; | 168 | const VideoCommon::ImageViewId image_view_id{(views++)->id}; |
| 169 | const VkSampler sampler{*(samplers++)}; | 169 | const VkSampler sampler{*(samplers++)}; |
| 170 | ImageView& image_view{texture_cache.GetImageView(image_view_id)}; | 170 | ImageView& image_view{texture_cache.GetImageView(image_view_id)}; |
| 171 | const Image& image{texture_cache.GetImage(image_view.image_id)}; | 171 | const Image& image{texture_cache.GetImage(image_view.image_id)}; |
| 172 | const VkImageView vk_image_view{image_view.Handle(desc.type)}; | 172 | const VkImageView vk_image_view{image_view.Handle(desc.type)}; |
| 173 | update_descriptor_queue.AddSampledImage(vk_image_view, sampler); | 173 | update_descriptor_queue.AddSampledImage(vk_image_view, sampler); |
| 174 | rescaling.PushTexture(image_view_id != NULL_IMAGE_VIEW_ID && | 174 | rescaling.PushTexture(True(image.flags & VideoCommon::ImageFlagBits::Rescaled)); |
| 175 | True(image.flags & VideoCommon::ImageFlagBits::Rescaled)); | ||
| 176 | } | 175 | } |
| 177 | } | 176 | } |
| 178 | for (const auto& desc : info.image_descriptors) { | 177 | for (const auto& desc : info.image_descriptors) { |
| 179 | for (u32 index = 0; index < desc.count; ++index) { | 178 | for (u32 index = 0; index < desc.count; ++index) { |
| 180 | ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; | 179 | ImageView& image_view{texture_cache.GetImageView((views++)->id)}; |
| 181 | if (desc.is_written) { | 180 | if (desc.is_written) { |
| 182 | texture_cache.MarkModification(image_view.image_id); | 181 | texture_cache.MarkModification(image_view.image_id); |
| 183 | } | 182 | } |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 5c591e345..f89b84c6e 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -108,10 +108,8 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 108 | texture_cache.SynchronizeComputeDescriptors(); | 108 | texture_cache.SynchronizeComputeDescriptors(); |
| 109 | 109 | ||
| 110 | static constexpr size_t max_elements = 64; | 110 | static constexpr size_t max_elements = 64; |
| 111 | std::array<ImageId, max_elements> image_view_ids; | 111 | boost::container::static_vector<VideoCommon::ImageViewInOut, max_elements> views; |
| 112 | boost::container::static_vector<u32, max_elements> image_view_indices; | ||
| 113 | boost::container::static_vector<VkSampler, max_elements> samplers; | 112 | boost::container::static_vector<VkSampler, max_elements> samplers; |
| 114 | boost::container::static_vector<bool, max_elements> image_view_blacklist; | ||
| 115 | 113 | ||
| 116 | const auto& qmd{kepler_compute.launch_description}; | 114 | const auto& qmd{kepler_compute.launch_description}; |
| 117 | const auto& cbufs{qmd.const_buffer_config}; | 115 | const auto& cbufs{qmd.const_buffer_config}; |
| @@ -135,54 +133,37 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 135 | } | 133 | } |
| 136 | return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); | 134 | return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); |
| 137 | }}; | 135 | }}; |
| 138 | const auto add_image{[&](const auto& desc) { | 136 | const auto add_image{[&](const auto& desc, bool blacklist) { |
| 139 | for (u32 index = 0; index < desc.count; ++index) { | 137 | for (u32 index = 0; index < desc.count; ++index) { |
| 140 | const auto handle{read_handle(desc, index)}; | 138 | const auto handle{read_handle(desc, index)}; |
| 141 | image_view_indices.push_back(handle.first); | 139 | views.push_back({ |
| 140 | .index = handle.first, | ||
| 141 | .blacklist = blacklist, | ||
| 142 | .id = {}, | ||
| 143 | }); | ||
| 142 | } | 144 | } |
| 143 | }}; | 145 | }}; |
| 144 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | 146 | for (const auto& desc : info.texture_buffer_descriptors) { |
| 145 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | 147 | add_image(desc, false); |
| 148 | } | ||
| 149 | for (const auto& desc : info.image_buffer_descriptors) { | ||
| 150 | add_image(desc, false); | ||
| 151 | } | ||
| 146 | for (const auto& desc : info.texture_descriptors) { | 152 | for (const auto& desc : info.texture_descriptors) { |
| 147 | for (u32 index = 0; index < desc.count; ++index) { | 153 | for (u32 index = 0; index < desc.count; ++index) { |
| 148 | const auto handle{read_handle(desc, index)}; | 154 | const auto handle{read_handle(desc, index)}; |
| 149 | image_view_indices.push_back(handle.first); | 155 | views.push_back({handle.first}); |
| 150 | 156 | ||
| 151 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); | 157 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.second); |
| 152 | samplers.push_back(sampler->Handle()); | 158 | samplers.push_back(sampler->Handle()); |
| 153 | } | 159 | } |
| 154 | } | 160 | } |
| 155 | const u32 black_list_base = image_view_indices.size(); | ||
| 156 | bool atleast_one_blacklisted = false; | ||
| 157 | for (const auto& desc : info.image_descriptors) { | 161 | for (const auto& desc : info.image_descriptors) { |
| 158 | const bool is_black_listed = | 162 | add_image(desc, true); |
| 159 | desc.is_written && (desc.type == Shader::TextureType::Color2D || | ||
| 160 | desc.type == Shader::TextureType::ColorArray2D); | ||
| 161 | for (u32 index = 0; index < desc.count; ++index) { | ||
| 162 | image_view_blacklist.push_back(is_black_listed); | ||
| 163 | } | ||
| 164 | atleast_one_blacklisted |= is_black_listed; | ||
| 165 | add_image(desc); | ||
| 166 | } | 163 | } |
| 167 | 164 | texture_cache.FillComputeImageViews(std::span(views.data(), views.size())); | |
| 168 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | ||
| 169 | bool has_listed_stuffs; | ||
| 170 | do { | ||
| 171 | has_listed_stuffs = false; | ||
| 172 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); | ||
| 173 | if (atleast_one_blacklisted) { | ||
| 174 | for (u32 index = 0; index < image_view_blacklist.size(); index++) { | ||
| 175 | if (image_view_blacklist[index]) { | ||
| 176 | ImageView& image_view{ | ||
| 177 | texture_cache.GetImageView(image_view_ids[index + black_list_base])}; | ||
| 178 | has_listed_stuffs |= texture_cache.BlackListImage(image_view.image_id); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } while (has_listed_stuffs); | ||
| 183 | 165 | ||
| 184 | buffer_cache.UnbindComputeTextureBuffers(); | 166 | buffer_cache.UnbindComputeTextureBuffers(); |
| 185 | ImageId* texture_buffer_ids{image_view_ids.data()}; | ||
| 186 | size_t index{}; | 167 | size_t index{}; |
| 187 | const auto add_buffer{[&](const auto& desc) { | 168 | const auto add_buffer{[&](const auto& desc) { |
| 188 | constexpr bool is_image = std::is_same_v<decltype(desc), const ImageBufferDescriptor&>; | 169 | constexpr bool is_image = std::is_same_v<decltype(desc), const ImageBufferDescriptor&>; |
| @@ -191,11 +172,10 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 191 | if constexpr (is_image) { | 172 | if constexpr (is_image) { |
| 192 | is_written = desc.is_written; | 173 | is_written = desc.is_written; |
| 193 | } | 174 | } |
| 194 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_ids); | 175 | ImageView& image_view = texture_cache.GetImageView(views[index].id); |
| 195 | buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(), | 176 | buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(), |
| 196 | image_view.BufferSize(), image_view.format, | 177 | image_view.BufferSize(), image_view.format, |
| 197 | is_written, is_image); | 178 | is_written, is_image); |
| 198 | ++texture_buffer_ids; | ||
| 199 | ++index; | 179 | ++index; |
| 200 | } | 180 | } |
| 201 | }}; | 181 | }}; |
| @@ -207,9 +187,9 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 207 | 187 | ||
| 208 | RescalingPushConstant rescaling(num_textures); | 188 | RescalingPushConstant rescaling(num_textures); |
| 209 | const VkSampler* samplers_it{samplers.data()}; | 189 | const VkSampler* samplers_it{samplers.data()}; |
| 210 | const ImageId* views_it{image_view_ids.data()}; | 190 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 211 | PushImageDescriptors(info, samplers_it, views_it, texture_cache, update_descriptor_queue, | 191 | PushImageDescriptors(texture_cache, update_descriptor_queue, info, rescaling, samplers_it, |
| 212 | rescaling); | 192 | views_it); |
| 213 | 193 | ||
| 214 | if (!is_built.load(std::memory_order::relaxed)) { | 194 | if (!is_built.load(std::memory_order::relaxed)) { |
| 215 | // Wait for the pipeline to be built | 195 | // Wait for the pipeline to be built |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4d966ee4b..4efb5d735 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -278,12 +278,10 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { | |||
| 278 | 278 | ||
| 279 | template <typename Spec> | 279 | template <typename Spec> |
| 280 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | 280 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { |
| 281 | std::array<ImageId, MAX_IMAGE_ELEMENTS> image_view_ids; | 281 | std::array<VideoCommon::ImageViewInOut, MAX_IMAGE_ELEMENTS> views; |
| 282 | std::array<u32, MAX_IMAGE_ELEMENTS> image_view_indices; | ||
| 283 | std::array<bool, MAX_IMAGE_ELEMENTS> image_view_blacklist; | ||
| 284 | std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers; | 282 | std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers; |
| 285 | size_t sampler_index{}; | 283 | size_t sampler_index{}; |
| 286 | size_t image_index{}; | 284 | size_t view_index{}; |
| 287 | 285 | ||
| 288 | texture_cache.SynchronizeGraphicsDescriptors(); | 286 | texture_cache.SynchronizeGraphicsDescriptors(); |
| 289 | 287 | ||
| @@ -291,8 +289,6 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 291 | 289 | ||
| 292 | const auto& regs{maxwell3d.regs}; | 290 | const auto& regs{maxwell3d.regs}; |
| 293 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 291 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; |
| 294 | u32 start_black_list = std::numeric_limits<u32>::max(); | ||
| 295 | u32 end_black_list = 0; | ||
| 296 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 292 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 297 | const Shader::Info& info{stage_infos[stage]}; | 293 | const Shader::Info& info{stage_infos[stage]}; |
| 298 | buffer_cache.UnbindGraphicsStorageBuffers(stage); | 294 | buffer_cache.UnbindGraphicsStorageBuffers(stage); |
| @@ -329,7 +325,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 329 | const auto add_image{[&](const auto& desc) { | 325 | const auto add_image{[&](const auto& desc) { |
| 330 | for (u32 index = 0; index < desc.count; ++index) { | 326 | for (u32 index = 0; index < desc.count; ++index) { |
| 331 | const auto handle{read_handle(desc, index)}; | 327 | const auto handle{read_handle(desc, index)}; |
| 332 | image_view_indices[image_index++] = handle.first; | 328 | views[view_index++] = {handle.first}; |
| 333 | } | 329 | } |
| 334 | }}; | 330 | }}; |
| 335 | if constexpr (Spec::has_texture_buffers) { | 331 | if constexpr (Spec::has_texture_buffers) { |
| @@ -345,7 +341,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 345 | for (const auto& desc : info.texture_descriptors) { | 341 | for (const auto& desc : info.texture_descriptors) { |
| 346 | for (u32 index = 0; index < desc.count; ++index) { | 342 | for (u32 index = 0; index < desc.count; ++index) { |
| 347 | const auto handle{read_handle(desc, index)}; | 343 | const auto handle{read_handle(desc, index)}; |
| 348 | image_view_indices[image_index++] = handle.first; | 344 | views[view_index++] = {handle.first}; |
| 349 | 345 | ||
| 350 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; | 346 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)}; |
| 351 | samplers[sampler_index++] = sampler->Handle(); | 347 | samplers[sampler_index++] = sampler->Handle(); |
| @@ -353,15 +349,6 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 353 | } | 349 | } |
| 354 | if constexpr (Spec::has_images) { | 350 | if constexpr (Spec::has_images) { |
| 355 | for (const auto& desc : info.image_descriptors) { | 351 | for (const auto& desc : info.image_descriptors) { |
| 356 | if (desc.is_written && (desc.type == Shader::TextureType::Color2D || | ||
| 357 | desc.type == Shader::TextureType::ColorArray2D)) { | ||
| 358 | auto index_copy = image_index; | ||
| 359 | for (u32 index = 0; index < desc.count; ++index) { | ||
| 360 | start_black_list = std::min<u32>(start_black_list, index_copy); | ||
| 361 | image_view_blacklist[index_copy++] = true; | ||
| 362 | end_black_list = std::max<u32>(end_black_list, index_copy); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | add_image(desc); | 352 | add_image(desc); |
| 366 | } | 353 | } |
| 367 | } | 354 | } |
| @@ -381,24 +368,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 381 | if constexpr (Spec::enabled_stages[4]) { | 368 | if constexpr (Spec::enabled_stages[4]) { |
| 382 | config_stage(4); | 369 | config_stage(4); |
| 383 | } | 370 | } |
| 384 | const std::span indices_span(image_view_indices.data(), image_index); | 371 | texture_cache.FillGraphicsImageViews<Spec::has_images>(std::span(views.data(), view_index)); |
| 385 | bool has_listed_stuffs; | ||
| 386 | do { | ||
| 387 | has_listed_stuffs = false; | ||
| 388 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | ||
| 389 | if constexpr (Spec::has_images) { | ||
| 390 | if (start_black_list < end_black_list) { | ||
| 391 | for (u32 index = start_black_list; index < end_black_list; index++) { | ||
| 392 | if (image_view_blacklist[index]) { | ||
| 393 | ImageView& image_view{texture_cache.GetImageView(image_view_ids[index])}; | ||
| 394 | has_listed_stuffs |= texture_cache.BlackListImage(image_view.image_id); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | } while (has_listed_stuffs); | ||
| 400 | 372 | ||
| 401 | ImageId* texture_buffer_index{image_view_ids.data()}; | 373 | VideoCommon::ImageViewInOut* texture_buffer_it{views.data()}; |
| 402 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { | 374 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 403 | size_t index{}; | 375 | size_t index{}; |
| 404 | const auto add_buffer{[&](const auto& desc) { | 376 | const auto add_buffer{[&](const auto& desc) { |
| @@ -408,12 +380,12 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 408 | if constexpr (is_image) { | 380 | if constexpr (is_image) { |
| 409 | is_written = desc.is_written; | 381 | is_written = desc.is_written; |
| 410 | } | 382 | } |
| 411 | ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)}; | 383 | ImageView& image_view{texture_cache.GetImageView(texture_buffer_it->id)}; |
| 412 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), | 384 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), |
| 413 | image_view.BufferSize(), image_view.format, | 385 | image_view.BufferSize(), image_view.format, |
| 414 | is_written, is_image); | 386 | is_written, is_image); |
| 415 | ++index; | 387 | ++index; |
| 416 | ++texture_buffer_index; | 388 | ++texture_buffer_it; |
| 417 | } | 389 | } |
| 418 | }}; | 390 | }}; |
| 419 | buffer_cache.UnbindGraphicsTextureBuffers(stage); | 391 | buffer_cache.UnbindGraphicsTextureBuffers(stage); |
| @@ -429,9 +401,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 429 | add_buffer(desc); | 401 | add_buffer(desc); |
| 430 | } | 402 | } |
| 431 | } | 403 | } |
| 432 | texture_buffer_index += Shader::NumDescriptors(info.texture_descriptors); | 404 | texture_buffer_it += Shader::NumDescriptors(info.texture_descriptors); |
| 433 | if constexpr (Spec::has_images) { | 405 | if constexpr (Spec::has_images) { |
| 434 | texture_buffer_index += Shader::NumDescriptors(info.image_descriptors); | 406 | texture_buffer_it += Shader::NumDescriptors(info.image_descriptors); |
| 435 | } | 407 | } |
| 436 | }}; | 408 | }}; |
| 437 | if constexpr (Spec::enabled_stages[0]) { | 409 | if constexpr (Spec::enabled_stages[0]) { |
| @@ -457,11 +429,11 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 457 | 429 | ||
| 458 | RescalingPushConstant rescaling(num_textures); | 430 | RescalingPushConstant rescaling(num_textures); |
| 459 | const VkSampler* samplers_it{samplers.data()}; | 431 | const VkSampler* samplers_it{samplers.data()}; |
| 460 | const ImageId* views_it{image_view_ids.data()}; | 432 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 461 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 433 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 462 | buffer_cache.BindHostStageBuffers(stage); | 434 | buffer_cache.BindHostStageBuffers(stage); |
| 463 | PushImageDescriptors(stage_infos[stage], samplers_it, views_it, texture_cache, | 435 | PushImageDescriptors(texture_cache, update_descriptor_queue, stage_infos[stage], rescaling, |
| 464 | update_descriptor_queue, rescaling); | 436 | samplers_it, views_it); |
| 465 | }}; | 437 | }}; |
| 466 | if constexpr (Spec::enabled_stages[0]) { | 438 | if constexpr (Spec::enabled_stages[0]) { |
| 467 | prepare_stage(0); | 439 | prepare_stage(0); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index b21992fce..3400066a6 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -730,10 +730,17 @@ void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, con | |||
| 730 | } | 730 | } |
| 731 | } // Anonymous namespace | 731 | } // Anonymous namespace |
| 732 | 732 | ||
| 733 | void TextureCacheRuntime::Init() { | 733 | TextureCacheRuntime::TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_, |
| 734 | resolution = Settings::values.resolution_info; | 734 | MemoryAllocator& memory_allocator_, |
| 735 | is_rescaling_on = resolution.up_scale != 1 || resolution.down_shift != 0; | 735 | StagingBufferPool& staging_buffer_pool_, |
| 736 | } | 736 | BlitImageHelper& blit_image_helper_, |
| 737 | ASTCDecoderPass& astc_decoder_pass_, | ||
| 738 | RenderPassCache& render_pass_cache_) | ||
| 739 | : device{device_}, scheduler{scheduler_}, memory_allocator{memory_allocator_}, | ||
| 740 | staging_buffer_pool{staging_buffer_pool_}, blit_image_helper{blit_image_helper_}, | ||
| 741 | astc_decoder_pass{astc_decoder_pass_}, render_pass_cache{render_pass_cache_}, | ||
| 742 | resolution{Settings::values.resolution_info}, | ||
| 743 | is_rescaling_on(resolution.up_scale != 1 || resolution.down_shift != 0) {} | ||
| 737 | 744 | ||
| 738 | void TextureCacheRuntime::Finish() { | 745 | void TextureCacheRuntime::Finish() { |
| 739 | scheduler.Finish(); | 746 | scheduler.Finish(); |
| @@ -1040,6 +1047,8 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu | |||
| 1040 | } | 1047 | } |
| 1041 | } | 1048 | } |
| 1042 | 1049 | ||
| 1050 | Image::Image(const VideoCommon::NullImageParams& params) : VideoCommon::ImageBase{params} {} | ||
| 1051 | |||
| 1043 | Image::~Image() = default; | 1052 | Image::~Image() = default; |
| 1044 | 1053 | ||
| 1045 | void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { | 1054 | void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { |
| @@ -1187,8 +1196,7 @@ bool Image::ScaleDown(bool save_as_backup) { | |||
| 1187 | }*/ | 1196 | }*/ |
| 1188 | 1197 | ||
| 1189 | const auto& resolution = runtime->resolution; | 1198 | const auto& resolution = runtime->resolution; |
| 1190 | vk::Image downscaled_image = | 1199 | vk::Image downscaled_image = MakeImage(runtime->device, info); |
| 1191 | MakeImage(runtime->device, info); | ||
| 1192 | MemoryCommit new_commit( | 1200 | MemoryCommit new_commit( |
| 1193 | runtime->memory_allocator.Commit(downscaled_image, MemoryUsage::DeviceLocal)); | 1201 | runtime->memory_allocator.Commit(downscaled_image, MemoryUsage::DeviceLocal)); |
| 1194 | 1202 | ||
| @@ -1301,7 +1309,7 @@ ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, | |||
| 1301 | : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, | 1309 | : VideoCommon::ImageViewBase{info, view_info}, gpu_addr{gpu_addr_}, |
| 1302 | buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {} | 1310 | buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {} |
| 1303 | 1311 | ||
| 1304 | ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::NullImageParams& params) | 1312 | ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams& params) |
| 1305 | : VideoCommon::ImageViewBase{params} {} | 1313 | : VideoCommon::ImageViewBase{params} {} |
| 1306 | 1314 | ||
| 1307 | VkImageView ImageView::DepthView() { | 1315 | VkImageView ImageView::DepthView() { |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 958a64651..9c39a6d99 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -34,21 +34,16 @@ class RenderPassCache; | |||
| 34 | class StagingBufferPool; | 34 | class StagingBufferPool; |
| 35 | class VKScheduler; | 35 | class VKScheduler; |
| 36 | 36 | ||
| 37 | struct TextureCacheRuntime { | 37 | class TextureCacheRuntime { |
| 38 | const Device& device; | 38 | public: |
| 39 | VKScheduler& scheduler; | ||
| 40 | MemoryAllocator& memory_allocator; | ||
| 41 | StagingBufferPool& staging_buffer_pool; | ||
| 42 | BlitImageHelper& blit_image_helper; | ||
| 43 | ASTCDecoderPass& astc_decoder_pass; | ||
| 44 | RenderPassCache& render_pass_cache; | ||
| 45 | static constexpr size_t TICKS_TO_DESTROY = 6; | 39 | static constexpr size_t TICKS_TO_DESTROY = 6; |
| 46 | DelayedDestructionRing<vk::Image, TICKS_TO_DESTROY> prescaled_images; | ||
| 47 | DelayedDestructionRing<MemoryCommit, TICKS_TO_DESTROY> prescaled_commits; | ||
| 48 | Settings::ResolutionScalingInfo resolution; | ||
| 49 | bool is_rescaling_on{}; | ||
| 50 | 40 | ||
| 51 | void Init(); | 41 | explicit TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_, |
| 42 | MemoryAllocator& memory_allocator_, | ||
| 43 | StagingBufferPool& staging_buffer_pool_, | ||
| 44 | BlitImageHelper& blit_image_helper_, | ||
| 45 | ASTCDecoderPass& astc_decoder_pass_, | ||
| 46 | RenderPassCache& render_pass_cache_); | ||
| 52 | 47 | ||
| 53 | void Finish(); | 48 | void Finish(); |
| 54 | 49 | ||
| @@ -56,6 +51,10 @@ struct TextureCacheRuntime { | |||
| 56 | 51 | ||
| 57 | StagingBufferRef DownloadStagingBuffer(size_t size); | 52 | StagingBufferRef DownloadStagingBuffer(size_t size); |
| 58 | 53 | ||
| 54 | void TickFrame(); | ||
| 55 | |||
| 56 | u64 GetDeviceLocalMemory() const; | ||
| 57 | |||
| 59 | void BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src, | 58 | void BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src, |
| 60 | const Region2D& dst_region, const Region2D& src_region, | 59 | const Region2D& dst_region, const Region2D& src_region, |
| 61 | Tegra::Engines::Fermi2D::Filter filter, | 60 | Tegra::Engines::Fermi2D::Filter filter, |
| @@ -84,15 +83,25 @@ struct TextureCacheRuntime { | |||
| 84 | return true; | 83 | return true; |
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | void TickFrame(); | 86 | const Device& device; |
| 87 | VKScheduler& scheduler; | ||
| 88 | MemoryAllocator& memory_allocator; | ||
| 89 | StagingBufferPool& staging_buffer_pool; | ||
| 90 | BlitImageHelper& blit_image_helper; | ||
| 91 | ASTCDecoderPass& astc_decoder_pass; | ||
| 92 | RenderPassCache& render_pass_cache; | ||
| 88 | 93 | ||
| 89 | u64 GetDeviceLocalMemory() const; | 94 | DelayedDestructionRing<vk::Image, TICKS_TO_DESTROY> prescaled_images; |
| 95 | DelayedDestructionRing<MemoryCommit, TICKS_TO_DESTROY> prescaled_commits; | ||
| 96 | Settings::ResolutionScalingInfo resolution; | ||
| 97 | bool is_rescaling_on{}; | ||
| 90 | }; | 98 | }; |
| 91 | 99 | ||
| 92 | class Image : public VideoCommon::ImageBase { | 100 | class Image : public VideoCommon::ImageBase { |
| 93 | public: | 101 | public: |
| 94 | explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, | 102 | explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, |
| 95 | VAddr cpu_addr); | 103 | VAddr cpu_addr); |
| 104 | explicit Image(const VideoCommon::NullImageParams&); | ||
| 96 | 105 | ||
| 97 | ~Image(); | 106 | ~Image(); |
| 98 | 107 | ||
| @@ -151,7 +160,7 @@ public: | |||
| 151 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); | 160 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&); |
| 152 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, | 161 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&, |
| 153 | const VideoCommon::ImageViewInfo&, GPUVAddr); | 162 | const VideoCommon::ImageViewInfo&, GPUVAddr); |
| 154 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageParams&); | 163 | explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&); |
| 155 | 164 | ||
| 156 | [[nodiscard]] VkImageView DepthView(); | 165 | [[nodiscard]] VkImageView DepthView(); |
| 157 | 166 | ||
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp index e9e725edf..25a211df8 100644 --- a/src/video_core/texture_cache/image_base.cpp +++ b/src/video_core/texture_cache/image_base.cpp | |||
| @@ -69,6 +69,8 @@ ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_ | |||
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | ImageBase::ImageBase(const NullImageParams&) {} | ||
| 73 | |||
| 72 | ImageMapView::ImageMapView(GPUVAddr gpu_addr_, VAddr cpu_addr_, size_t size_, ImageId image_id_) | 74 | ImageMapView::ImageMapView(GPUVAddr gpu_addr_, VAddr cpu_addr_, size_t size_, ImageId image_id_) |
| 73 | : gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_}, size{size_}, image_id{image_id_} {} | 75 | : gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_}, size{size_}, image_id{image_id_} {} |
| 74 | 76 | ||
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 97f107b4d..9c34687e0 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h | |||
| @@ -48,8 +48,11 @@ struct AliasedImage { | |||
| 48 | ImageId id; | 48 | ImageId id; |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | struct NullImageParams {}; | ||
| 52 | |||
| 51 | struct ImageBase { | 53 | struct ImageBase { |
| 52 | explicit ImageBase(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr); | 54 | explicit ImageBase(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr); |
| 55 | explicit ImageBase(const NullImageParams&); | ||
| 53 | 56 | ||
| 54 | [[nodiscard]] std::optional<SubresourceBase> TryFindBase(GPUVAddr other_addr) const noexcept; | 57 | [[nodiscard]] std::optional<SubresourceBase> TryFindBase(GPUVAddr other_addr) const noexcept; |
| 55 | 58 | ||
diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp index 450becbeb..e66dc9320 100644 --- a/src/video_core/texture_cache/image_view_base.cpp +++ b/src/video_core/texture_cache/image_view_base.cpp | |||
| @@ -45,6 +45,6 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in | |||
| 45 | ASSERT_MSG(view_info.type == ImageViewType::Buffer, "Expected texture buffer"); | 45 | ASSERT_MSG(view_info.type == ImageViewType::Buffer, "Expected texture buffer"); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | ImageViewBase::ImageViewBase(const NullImageParams&) {} | 48 | ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {} |
| 49 | 49 | ||
| 50 | } // namespace VideoCommon | 50 | } // namespace VideoCommon |
diff --git a/src/video_core/texture_cache/image_view_base.h b/src/video_core/texture_cache/image_view_base.h index 903f715c5..9c24c5359 100644 --- a/src/video_core/texture_cache/image_view_base.h +++ b/src/video_core/texture_cache/image_view_base.h | |||
| @@ -15,7 +15,7 @@ using VideoCore::Surface::PixelFormat; | |||
| 15 | struct ImageViewInfo; | 15 | struct ImageViewInfo; |
| 16 | struct ImageInfo; | 16 | struct ImageInfo; |
| 17 | 17 | ||
| 18 | struct NullImageParams {}; | 18 | struct NullImageViewParams {}; |
| 19 | 19 | ||
| 20 | enum class ImageViewFlagBits : u16 { | 20 | enum class ImageViewFlagBits : u16 { |
| 21 | PreemtiveDownload = 1 << 0, | 21 | PreemtiveDownload = 1 << 0, |
| @@ -28,7 +28,7 @@ struct ImageViewBase { | |||
| 28 | explicit ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_info, | 28 | explicit ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_info, |
| 29 | ImageId image_id); | 29 | ImageId image_id); |
| 30 | explicit ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info); | 30 | explicit ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info); |
| 31 | explicit ImageViewBase(const NullImageParams&); | 31 | explicit ImageViewBase(const NullImageViewParams&); |
| 32 | 32 | ||
| 33 | [[nodiscard]] bool IsBuffer() const noexcept { | 33 | [[nodiscard]] bool IsBuffer() const noexcept { |
| 34 | return type == ImageViewType::Buffer; | 34 | return type == ImageViewType::Buffer; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index be40f6b88..4e97a9e6a 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -36,7 +36,6 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& | |||
| 36 | Tegra::MemoryManager& gpu_memory_) | 36 | Tegra::MemoryManager& gpu_memory_) |
| 37 | : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, | 37 | : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, |
| 38 | kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_} { | 38 | kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_} { |
| 39 | runtime.Init(); | ||
| 40 | // Configure null sampler | 39 | // Configure null sampler |
| 41 | TSCEntry sampler_descriptor{}; | 40 | TSCEntry sampler_descriptor{}; |
| 42 | sampler_descriptor.min_filter.Assign(Tegra::Texture::TextureFilter::Linear); | 41 | sampler_descriptor.min_filter.Assign(Tegra::Texture::TextureFilter::Linear); |
| @@ -46,7 +45,8 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& | |||
| 46 | 45 | ||
| 47 | // Make sure the first index is reserved for the null resources | 46 | // Make sure the first index is reserved for the null resources |
| 48 | // This way the null resource becomes a compile time constant | 47 | // This way the null resource becomes a compile time constant |
| 49 | void(slot_image_views.insert(runtime, NullImageParams{})); | 48 | void(slot_images.insert(NullImageParams{})); |
| 49 | void(slot_image_views.insert(runtime, NullImageViewParams{})); | ||
| 50 | void(slot_samplers.insert(runtime, sampler_descriptor)); | 50 | void(slot_samplers.insert(runtime, sampler_descriptor)); |
| 51 | 51 | ||
| 52 | if constexpr (HAS_DEVICE_MEMORY_INFO) { | 52 | if constexpr (HAS_DEVICE_MEMORY_INFO) { |
| @@ -57,7 +57,7 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& | |||
| 57 | critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY); | 57 | critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY); |
| 58 | minimum_memory = 0; | 58 | minimum_memory = 0; |
| 59 | } else { | 59 | } else { |
| 60 | // on OGL we can be more conservatives as the driver takes care. | 60 | // On OpenGL we can be more conservatives as the driver takes care. |
| 61 | expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; | 61 | expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; |
| 62 | critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; | 62 | critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; |
| 63 | minimum_memory = expected_memory; | 63 | minimum_memory = expected_memory; |
| @@ -135,15 +135,14 @@ void TextureCache<P>::MarkModification(ImageId id) noexcept { | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | template <class P> | 137 | template <class P> |
| 138 | void TextureCache<P>::FillGraphicsImageViews(std::span<const u32> indices, | 138 | template <bool has_blacklists> |
| 139 | std::span<ImageViewId> image_view_ids) { | 139 | void TextureCache<P>::FillGraphicsImageViews(std::span<ImageViewInOut> views) { |
| 140 | FillImageViews(graphics_image_table, graphics_image_view_ids, indices, image_view_ids); | 140 | FillImageViews<has_blacklists>(graphics_image_table, graphics_image_view_ids, views); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | template <class P> | 143 | template <class P> |
| 144 | void TextureCache<P>::FillComputeImageViews(std::span<const u32> indices, | 144 | void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) { |
| 145 | std::span<ImageViewId> image_view_ids) { | 145 | FillImageViews<false>(compute_image_table, compute_image_view_ids, views); |
| 146 | FillImageViews(compute_image_table, compute_image_view_ids, indices, image_view_ids); | ||
| 147 | } | 146 | } |
| 148 | 147 | ||
| 149 | template <class P> | 148 | template <class P> |
| @@ -346,17 +345,26 @@ typename P::Framebuffer* TextureCache<P>::GetFramebuffer() { | |||
| 346 | } | 345 | } |
| 347 | 346 | ||
| 348 | template <class P> | 347 | template <class P> |
| 348 | template <bool has_blacklists> | ||
| 349 | void TextureCache<P>::FillImageViews(DescriptorTable<TICEntry>& table, | 349 | void TextureCache<P>::FillImageViews(DescriptorTable<TICEntry>& table, |
| 350 | std::span<ImageViewId> cached_image_view_ids, | 350 | std::span<ImageViewId> cached_image_view_ids, |
| 351 | std::span<const u32> indices, | 351 | std::span<ImageViewInOut> views) { |
| 352 | std::span<ImageViewId> image_view_ids) { | 352 | bool has_blacklisted; |
| 353 | ASSERT(indices.size() <= image_view_ids.size()); | ||
| 354 | do { | 353 | do { |
| 355 | has_deleted_images = false; | 354 | has_deleted_images = false; |
| 356 | std::ranges::transform(indices, image_view_ids.begin(), [&](u32 index) { | 355 | if constexpr (has_blacklists) { |
| 357 | return VisitImageView(table, cached_image_view_ids, index); | 356 | has_blacklisted = false; |
| 358 | }); | 357 | } |
| 359 | } while (has_deleted_images); | 358 | for (ImageViewInOut& view : views) { |
| 359 | view.id = VisitImageView(table, cached_image_view_ids, view.index); | ||
| 360 | if constexpr (has_blacklists) { | ||
| 361 | if (view.blacklist && view.id != NULL_IMAGE_VIEW_ID) { | ||
| 362 | const ImageViewBase& image_view{slot_image_views[view.id]}; | ||
| 363 | has_blacklisted |= BlackListImage(image_view.image_id); | ||
| 364 | } | ||
| 365 | } | ||
| 366 | } | ||
| 367 | } while (has_deleted_images || (has_blacklists && has_blacklisted)); | ||
| 360 | } | 368 | } |
| 361 | 369 | ||
| 362 | template <class P> | 370 | template <class P> |
| @@ -622,7 +630,7 @@ void TextureCache<P>::PopAsyncFlushes() { | |||
| 622 | } | 630 | } |
| 623 | 631 | ||
| 624 | template <class P> | 632 | template <class P> |
| 625 | bool TextureCache<P>::IsRescaling() { | 633 | bool TextureCache<P>::IsRescaling() const noexcept { |
| 626 | return is_rescaling; | 634 | return is_rescaling; |
| 627 | } | 635 | } |
| 628 | 636 | ||
| @@ -775,12 +783,11 @@ bool TextureCache<P>::BlackListImage(ImageId image_id) { | |||
| 775 | } | 783 | } |
| 776 | 784 | ||
| 777 | template <class P> | 785 | template <class P> |
| 778 | bool TextureCache<P>::ImageCanRescale(Image& image) { | 786 | bool TextureCache<P>::ImageCanRescale(ImageBase& image) { |
| 779 | if (True(image.flags & ImageFlagBits::Blacklisted)) { | 787 | if (True(image.flags & ImageFlagBits::Blacklisted)) { |
| 780 | return false; | 788 | return false; |
| 781 | } | 789 | } |
| 782 | if (True(image.flags & ImageFlagBits::Rescaled) || | 790 | if (True(image.flags & (ImageFlagBits::Rescaled | ImageFlagBits::RescaleChecked))) { |
| 783 | True(image.flags & ImageFlagBits::RescaleChecked)) { | ||
| 784 | return true; | 791 | return true; |
| 785 | } | 792 | } |
| 786 | if (!image.info.rescaleable) { | 793 | if (!image.info.rescaleable) { |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 35a29cd9b..b6cc09682 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -39,6 +39,16 @@ using VideoCore::Surface::PixelFormatFromDepthFormat; | |||
| 39 | using VideoCore::Surface::PixelFormatFromRenderTargetFormat; | 39 | using VideoCore::Surface::PixelFormatFromRenderTargetFormat; |
| 40 | using namespace Common::Literals; | 40 | using namespace Common::Literals; |
| 41 | 41 | ||
| 42 | struct ImageViewInOut { | ||
| 43 | u32 index; | ||
| 44 | bool blacklist; | ||
| 45 | union { | ||
| 46 | struct Empty { | ||
| 47 | } empty{}; | ||
| 48 | ImageViewId id; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 42 | template <class P> | 52 | template <class P> |
| 43 | class TextureCache { | 53 | class TextureCache { |
| 44 | /// Address shift for caching images into a hash table | 54 | /// Address shift for caching images into a hash table |
| @@ -53,11 +63,6 @@ class TextureCache { | |||
| 53 | /// True when the API can provide info about the memory of the device. | 63 | /// True when the API can provide info about the memory of the device. |
| 54 | static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO; | 64 | static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO; |
| 55 | 65 | ||
| 56 | /// Image view ID for null descriptors | ||
| 57 | static constexpr ImageViewId NULL_IMAGE_VIEW_ID{0}; | ||
| 58 | /// Sampler ID for bugged sampler ids | ||
| 59 | static constexpr SamplerId NULL_SAMPLER_ID{0}; | ||
| 60 | |||
| 61 | static constexpr u64 DEFAULT_EXPECTED_MEMORY = 1_GiB; | 66 | static constexpr u64 DEFAULT_EXPECTED_MEMORY = 1_GiB; |
| 62 | static constexpr u64 DEFAULT_CRITICAL_MEMORY = 2_GiB; | 67 | static constexpr u64 DEFAULT_CRITICAL_MEMORY = 2_GiB; |
| 63 | 68 | ||
| @@ -105,11 +110,11 @@ public: | |||
| 105 | void MarkModification(ImageId id) noexcept; | 110 | void MarkModification(ImageId id) noexcept; |
| 106 | 111 | ||
| 107 | /// Fill image_view_ids with the graphics images in indices | 112 | /// Fill image_view_ids with the graphics images in indices |
| 108 | void FillGraphicsImageViews(std::span<const u32> indices, | 113 | template <bool has_blacklists> |
| 109 | std::span<ImageViewId> image_view_ids); | 114 | void FillGraphicsImageViews(std::span<ImageViewInOut> views); |
| 110 | 115 | ||
| 111 | /// Fill image_view_ids with the compute images in indices | 116 | /// Fill image_view_ids with the compute images in indices |
| 112 | void FillComputeImageViews(std::span<const u32> indices, std::span<ImageViewId> image_view_ids); | 117 | void FillComputeImageViews(std::span<ImageViewInOut> views); |
| 113 | 118 | ||
| 114 | /// Get the sampler from the graphics descriptor table in the specified index | 119 | /// Get the sampler from the graphics descriptor table in the specified index |
| 115 | Sampler* GetGraphicsSampler(u32 index); | 120 | Sampler* GetGraphicsSampler(u32 index); |
| @@ -174,7 +179,7 @@ public: | |||
| 174 | /// Return true when a CPU region is modified from the GPU | 179 | /// Return true when a CPU region is modified from the GPU |
| 175 | [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); | 180 | [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); |
| 176 | 181 | ||
| 177 | [[nodiscard]] bool IsRescaling(); | 182 | [[nodiscard]] bool IsRescaling() const noexcept; |
| 178 | 183 | ||
| 179 | [[nodiscard]] bool BlackListImage(ImageId image_id); | 184 | [[nodiscard]] bool BlackListImage(ImageId image_id); |
| 180 | 185 | ||
| @@ -216,9 +221,10 @@ private: | |||
| 216 | void RunGarbageCollector(); | 221 | void RunGarbageCollector(); |
| 217 | 222 | ||
| 218 | /// Fills image_view_ids in the image views in indices | 223 | /// Fills image_view_ids in the image views in indices |
| 224 | template <bool has_blacklists> | ||
| 219 | void FillImageViews(DescriptorTable<TICEntry>& table, | 225 | void FillImageViews(DescriptorTable<TICEntry>& table, |
| 220 | std::span<ImageViewId> cached_image_view_ids, std::span<const u32> indices, | 226 | std::span<ImageViewId> cached_image_view_ids, |
| 221 | std::span<ImageViewId> image_view_ids); | 227 | std::span<ImageViewInOut> views); |
| 222 | 228 | ||
| 223 | /// Find or create an image view in the guest descriptor table | 229 | /// Find or create an image view in the guest descriptor table |
| 224 | ImageViewId VisitImageView(DescriptorTable<TICEntry>& table, | 230 | ImageViewId VisitImageView(DescriptorTable<TICEntry>& table, |
| @@ -336,7 +342,7 @@ private: | |||
| 336 | /// Returns true if the current clear parameters clear the whole image of a given image view | 342 | /// Returns true if the current clear parameters clear the whole image of a given image view |
| 337 | [[nodiscard]] bool IsFullClear(ImageViewId id); | 343 | [[nodiscard]] bool IsFullClear(ImageViewId id); |
| 338 | 344 | ||
| 339 | bool ImageCanRescale(Image& image); | 345 | bool ImageCanRescale(ImageBase& image); |
| 340 | void InvalidateScale(Image& image); | 346 | void InvalidateScale(Image& image); |
| 341 | bool ScaleUp(Image& image); | 347 | bool ScaleUp(Image& image); |
| 342 | bool ScaleDown(Image& image); | 348 | bool ScaleDown(Image& image); |
diff --git a/src/video_core/texture_cache/types.h b/src/video_core/texture_cache/types.h index 47a11cb2f..5c274abdf 100644 --- a/src/video_core/texture_cache/types.h +++ b/src/video_core/texture_cache/types.h | |||
| @@ -22,6 +22,13 @@ using ImageAllocId = SlotId; | |||
| 22 | using SamplerId = SlotId; | 22 | using SamplerId = SlotId; |
| 23 | using FramebufferId = SlotId; | 23 | using FramebufferId = SlotId; |
| 24 | 24 | ||
| 25 | /// Fake image ID for null image views | ||
| 26 | constexpr ImageId NULL_IMAGE_ID{0}; | ||
| 27 | /// Image view ID for null descriptors | ||
| 28 | constexpr ImageViewId NULL_IMAGE_VIEW_ID{0}; | ||
| 29 | /// Sampler ID for bugged sampler ids | ||
| 30 | constexpr SamplerId NULL_SAMPLER_ID{0}; | ||
| 31 | |||
| 25 | enum class ImageType : u32 { | 32 | enum class ImageType : u32 { |
| 26 | e1D, | 33 | e1D, |
| 27 | e2D, | 34 | e2D, |