diff options
| author | 2021-04-24 18:28:02 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:29 -0400 | |
| commit | 5ed871398b0e89cb3f2e3eb740d431f5faaa12e4 (patch) | |
| tree | c5c4272be277e04586d11b62775dd95e61101c63 /src | |
| parent | shader: Accelerate pipeline transitions and use dirty flags for shaders (diff) | |
| download | yuzu-5ed871398b0e89cb3f2e3eb740d431f5faaa12e4.tar.gz yuzu-5ed871398b0e89cb3f2e3eb740d431f5faaa12e4.tar.xz yuzu-5ed871398b0e89cb3f2e3eb740d431f5faaa12e4.zip | |
vk_graphics_pipeline: Generate specialized pipeline config functions and improve code
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 239 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.h | 22 |
2 files changed, 230 insertions, 31 deletions
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 100a5e07a..674226cb7 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -19,14 +19,24 @@ | |||
| 19 | #include "video_core/renderer_vulkan/vk_update_descriptor.h" | 19 | #include "video_core/renderer_vulkan/vk_update_descriptor.h" |
| 20 | #include "video_core/vulkan_common/vulkan_device.h" | 20 | #include "video_core/vulkan_common/vulkan_device.h" |
| 21 | 21 | ||
| 22 | #ifdef _MSC_VER | ||
| 23 | #define LAMBDA_FORCEINLINE [[msvc::forceinline]] | ||
| 24 | #else | ||
| 25 | #define LAMBDA_FORCEINLINE | ||
| 26 | #endif | ||
| 27 | |||
| 22 | namespace Vulkan { | 28 | namespace Vulkan { |
| 23 | namespace { | 29 | namespace { |
| 24 | using boost::container::small_vector; | 30 | using boost::container::small_vector; |
| 25 | using boost::container::static_vector; | 31 | using boost::container::static_vector; |
| 32 | using Shader::ImageBufferDescriptor; | ||
| 26 | using VideoCore::Surface::PixelFormat; | 33 | using VideoCore::Surface::PixelFormat; |
| 27 | using VideoCore::Surface::PixelFormatFromDepthFormat; | 34 | using VideoCore::Surface::PixelFormatFromDepthFormat; |
| 28 | using VideoCore::Surface::PixelFormatFromRenderTargetFormat; | 35 | using VideoCore::Surface::PixelFormatFromRenderTargetFormat; |
| 29 | 36 | ||
| 37 | constexpr size_t NUM_STAGES = Maxwell::MaxShaderStage; | ||
| 38 | constexpr size_t MAX_IMAGE_ELEMENTS = 64; | ||
| 39 | |||
| 30 | DescriptorLayoutBuilder MakeBuilder(const Device& device, std::span<const Shader::Info> infos) { | 40 | DescriptorLayoutBuilder MakeBuilder(const Device& device, std::span<const Shader::Info> infos) { |
| 31 | DescriptorLayoutBuilder builder{device.GetLogical()}; | 41 | DescriptorLayoutBuilder builder{device.GetLogical()}; |
| 32 | for (size_t index = 0; index < infos.size(); ++index) { | 42 | for (size_t index = 0; index < infos.size(); ++index) { |
| @@ -116,6 +126,80 @@ size_t NumAttachments(const FixedPipelineState& state) { | |||
| 116 | } | 126 | } |
| 117 | return num; | 127 | return num; |
| 118 | } | 128 | } |
| 129 | |||
| 130 | template <typename Spec> | ||
| 131 | bool Passes(const std::array<vk::ShaderModule, NUM_STAGES>& modules, | ||
| 132 | const std::array<Shader::Info, NUM_STAGES>& stage_infos) { | ||
| 133 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { | ||
| 134 | if (!Spec::enabled_stages[stage] && modules[stage]) { | ||
| 135 | return false; | ||
| 136 | } | ||
| 137 | const auto& info{stage_infos[stage]}; | ||
| 138 | if constexpr (!Spec::has_storage_buffers) { | ||
| 139 | if (!info.storage_buffers_descriptors.empty()) { | ||
| 140 | return false; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | if constexpr (!Spec::has_texture_buffers) { | ||
| 144 | if (!info.texture_buffer_descriptors.empty()) { | ||
| 145 | return false; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | if constexpr (!Spec::has_image_buffers) { | ||
| 149 | if (!info.image_buffer_descriptors.empty()) { | ||
| 150 | return false; | ||
| 151 | } | ||
| 152 | } | ||
| 153 | if constexpr (!Spec::has_images) { | ||
| 154 | if (!info.image_descriptors.empty()) { | ||
| 155 | return false; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
| 159 | return true; | ||
| 160 | } | ||
| 161 | |||
| 162 | using ConfigureFuncPtr = void (*)(GraphicsPipeline*, bool); | ||
| 163 | |||
| 164 | template <typename Spec, typename... Specs> | ||
| 165 | ConfigureFuncPtr FindSpec(const std::array<vk::ShaderModule, NUM_STAGES>& modules, | ||
| 166 | const std::array<Shader::Info, NUM_STAGES>& stage_infos) { | ||
| 167 | if constexpr (sizeof...(Specs) > 0) { | ||
| 168 | if (!Passes<Spec>(modules, stage_infos)) { | ||
| 169 | return FindSpec<Specs...>(modules, stage_infos); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | return GraphicsPipeline::MakeConfigureSpecFunc<Spec>(); | ||
| 173 | } | ||
| 174 | |||
| 175 | struct SimpleVertexFragmentSpec { | ||
| 176 | static constexpr std::array<bool, 5> enabled_stages{true, false, false, false, true}; | ||
| 177 | static constexpr bool has_storage_buffers = false; | ||
| 178 | static constexpr bool has_texture_buffers = false; | ||
| 179 | static constexpr bool has_image_buffers = false; | ||
| 180 | static constexpr bool has_images = false; | ||
| 181 | }; | ||
| 182 | |||
| 183 | struct SimpleVertexSpec { | ||
| 184 | static constexpr std::array<bool, 5> enabled_stages{true, false, false, false, false}; | ||
| 185 | static constexpr bool has_storage_buffers = false; | ||
| 186 | static constexpr bool has_texture_buffers = false; | ||
| 187 | static constexpr bool has_image_buffers = false; | ||
| 188 | static constexpr bool has_images = false; | ||
| 189 | }; | ||
| 190 | |||
| 191 | struct DefaultSpec { | ||
| 192 | static constexpr std::array<bool, 5> enabled_stages{true, true, true, true, true}; | ||
| 193 | static constexpr bool has_storage_buffers = true; | ||
| 194 | static constexpr bool has_texture_buffers = true; | ||
| 195 | static constexpr bool has_image_buffers = true; | ||
| 196 | static constexpr bool has_images = true; | ||
| 197 | }; | ||
| 198 | |||
| 199 | ConfigureFuncPtr ConfigureFunc(const std::array<vk::ShaderModule, NUM_STAGES>& modules, | ||
| 200 | const std::array<Shader::Info, NUM_STAGES>& infos) { | ||
| 201 | return FindSpec<SimpleVertexSpec, SimpleVertexFragmentSpec, DefaultSpec>(modules, infos); | ||
| 202 | } | ||
| 119 | } // Anonymous namespace | 203 | } // Anonymous namespace |
| 120 | 204 | ||
| 121 | GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_, | 205 | GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_, |
| @@ -144,6 +228,7 @@ GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_, | |||
| 144 | descriptor_update_template = builder.CreateTemplate(set_layout, *pipeline_layout); | 228 | descriptor_update_template = builder.CreateTemplate(set_layout, *pipeline_layout); |
| 145 | 229 | ||
| 146 | const VkRenderPass render_pass{render_pass_cache.Get(MakeRenderPassKey(key.state))}; | 230 | const VkRenderPass render_pass{render_pass_cache.Get(MakeRenderPassKey(key.state))}; |
| 231 | Validate(); | ||
| 147 | MakePipeline(device, render_pass); | 232 | MakePipeline(device, render_pass); |
| 148 | 233 | ||
| 149 | std::lock_guard lock{build_mutex}; | 234 | std::lock_guard lock{build_mutex}; |
| @@ -155,6 +240,7 @@ GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_, | |||
| 155 | } else { | 240 | } else { |
| 156 | func(); | 241 | func(); |
| 157 | } | 242 | } |
| 243 | configure_func = ConfigureFunc(spv_modules, stage_infos); | ||
| 158 | } | 244 | } |
| 159 | 245 | ||
| 160 | void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { | 246 | void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { |
| @@ -162,26 +248,29 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { | |||
| 162 | transitions.push_back(transition); | 248 | transitions.push_back(transition); |
| 163 | } | 249 | } |
| 164 | 250 | ||
| 165 | void GraphicsPipeline::Configure(bool is_indexed) { | 251 | template <typename Spec> |
| 166 | static constexpr size_t max_images_elements = 64; | 252 | void GraphicsPipeline::ConfigureImpl(bool is_indexed) { |
| 167 | std::array<ImageId, max_images_elements> image_view_ids; | 253 | std::array<ImageId, MAX_IMAGE_ELEMENTS> image_view_ids; |
| 168 | static_vector<u32, max_images_elements> image_view_indices; | 254 | std::array<u32, MAX_IMAGE_ELEMENTS> image_view_indices; |
| 169 | static_vector<VkSampler, max_images_elements> samplers; | 255 | std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers; |
| 256 | size_t image_index{}; | ||
| 170 | 257 | ||
| 171 | texture_cache.SynchronizeGraphicsDescriptors(); | 258 | texture_cache.SynchronizeGraphicsDescriptors(); |
| 172 | 259 | ||
| 173 | const auto& regs{maxwell3d.regs}; | 260 | const auto& regs{maxwell3d.regs}; |
| 174 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 261 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; |
| 175 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { | 262 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 176 | const Shader::Info& info{stage_infos[stage]}; | 263 | const Shader::Info& info{stage_infos[stage]}; |
| 177 | buffer_cache.SetEnabledUniformBuffers(stage, info.constant_buffer_mask); | 264 | buffer_cache.SetEnabledUniformBuffers(stage, info.constant_buffer_mask); |
| 178 | buffer_cache.UnbindGraphicsStorageBuffers(stage); | 265 | buffer_cache.UnbindGraphicsStorageBuffers(stage); |
| 179 | size_t ssbo_index{}; | 266 | if constexpr (Spec::has_storage_buffers) { |
| 180 | for (const auto& desc : info.storage_buffers_descriptors) { | 267 | size_t ssbo_index{}; |
| 181 | ASSERT(desc.count == 1); | 268 | for (const auto& desc : info.storage_buffers_descriptors) { |
| 182 | buffer_cache.BindGraphicsStorageBuffer(stage, ssbo_index, desc.cbuf_index, | 269 | ASSERT(desc.count == 1); |
| 183 | desc.cbuf_offset, desc.is_written); | 270 | buffer_cache.BindGraphicsStorageBuffer(stage, ssbo_index, desc.cbuf_index, |
| 184 | ++ssbo_index; | 271 | desc.cbuf_offset, desc.is_written); |
| 272 | ++ssbo_index; | ||
| 273 | } | ||
| 185 | } | 274 | } |
| 186 | const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; | 275 | const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; |
| 187 | const auto read_handle{[&](const auto& desc, u32 index) { | 276 | const auto read_handle{[&](const auto& desc, u32 index) { |
| @@ -207,33 +296,60 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 207 | const auto add_image{[&](const auto& desc) { | 296 | const auto add_image{[&](const auto& desc) { |
| 208 | for (u32 index = 0; index < desc.count; ++index) { | 297 | for (u32 index = 0; index < desc.count; ++index) { |
| 209 | const TextureHandle handle{read_handle(desc, index)}; | 298 | const TextureHandle handle{read_handle(desc, index)}; |
| 210 | image_view_indices.push_back(handle.image); | 299 | image_view_indices[image_index++] = handle.image; |
| 211 | } | 300 | } |
| 212 | }}; | 301 | }}; |
| 213 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | 302 | if constexpr (Spec::has_texture_buffers) { |
| 214 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | 303 | for (const auto& desc : info.texture_buffer_descriptors) { |
| 304 | add_image(desc); | ||
| 305 | } | ||
| 306 | } | ||
| 307 | if constexpr (Spec::has_image_buffers) { | ||
| 308 | for (const auto& desc : info.image_buffer_descriptors) { | ||
| 309 | add_image(desc); | ||
| 310 | } | ||
| 311 | } | ||
| 215 | for (const auto& desc : info.texture_descriptors) { | 312 | for (const auto& desc : info.texture_descriptors) { |
| 216 | for (u32 index = 0; index < desc.count; ++index) { | 313 | for (u32 index = 0; index < desc.count; ++index) { |
| 217 | const TextureHandle handle{read_handle(desc, index)}; | 314 | const TextureHandle handle{read_handle(desc, index)}; |
| 218 | image_view_indices.push_back(handle.image); | 315 | image_view_indices[image_index] = handle.image; |
| 219 | 316 | ||
| 220 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; | 317 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; |
| 221 | samplers.push_back(sampler->Handle()); | 318 | samplers[image_index] = sampler->Handle(); |
| 319 | ++image_index; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | if constexpr (Spec::has_images) { | ||
| 323 | for (const auto& desc : info.image_descriptors) { | ||
| 324 | add_image(desc); | ||
| 222 | } | 325 | } |
| 223 | } | 326 | } |
| 224 | std::ranges::for_each(info.image_descriptors, add_image); | 327 | }}; |
| 328 | if constexpr (Spec::enabled_stages[0]) { | ||
| 329 | config_stage(0); | ||
| 330 | } | ||
| 331 | if constexpr (Spec::enabled_stages[1]) { | ||
| 332 | config_stage(1); | ||
| 333 | } | ||
| 334 | if constexpr (Spec::enabled_stages[2]) { | ||
| 335 | config_stage(2); | ||
| 225 | } | 336 | } |
| 226 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 337 | if constexpr (Spec::enabled_stages[3]) { |
| 338 | config_stage(3); | ||
| 339 | } | ||
| 340 | if constexpr (Spec::enabled_stages[4]) { | ||
| 341 | config_stage(4); | ||
| 342 | } | ||
| 343 | const std::span indices_span(image_view_indices.data(), image_index); | ||
| 227 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | 344 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); |
| 228 | 345 | ||
| 229 | ImageId* texture_buffer_index{image_view_ids.data()}; | 346 | ImageId* texture_buffer_index{image_view_ids.data()}; |
| 230 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { | 347 | const auto bind_stage_info{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 231 | size_t index{}; | 348 | size_t index{}; |
| 232 | const auto add_buffer{[&](const auto& desc) { | 349 | const auto add_buffer{[&](const auto& desc) { |
| 233 | for (u32 i = 0; i < desc.count; ++i) { | 350 | for (u32 i = 0; i < desc.count; ++i) { |
| 234 | bool is_written{false}; | 351 | bool is_written{false}; |
| 235 | if constexpr (std::is_same_v<decltype(desc), | 352 | if constexpr (std::is_same_v<decltype(desc), const ImageBufferDescriptor&>) { |
| 236 | const Shader::ImageBufferDescriptor&>) { | ||
| 237 | is_written = desc.is_written; | 353 | is_written = desc.is_written; |
| 238 | } | 354 | } |
| 239 | ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)}; | 355 | ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)}; |
| @@ -245,29 +361,75 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 245 | } | 361 | } |
| 246 | }}; | 362 | }}; |
| 247 | const Shader::Info& info{stage_infos[stage]}; | 363 | const Shader::Info& info{stage_infos[stage]}; |
| 248 | buffer_cache.UnbindGraphicsTextureBuffers(stage); | 364 | if constexpr (Spec::has_texture_buffers || Spec::has_image_buffers) { |
| 249 | std::ranges::for_each(info.texture_buffer_descriptors, add_buffer); | 365 | buffer_cache.UnbindGraphicsTextureBuffers(stage); |
| 250 | std::ranges::for_each(info.image_buffer_descriptors, add_buffer); | 366 | } |
| 367 | if constexpr (Spec::has_texture_buffers) { | ||
| 368 | for (const auto& desc : info.texture_buffer_descriptors) { | ||
| 369 | add_buffer(desc); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | if constexpr (Spec::has_image_buffers) { | ||
| 373 | for (const auto& desc : info.image_buffer_descriptors) { | ||
| 374 | add_buffer(desc); | ||
| 375 | } | ||
| 376 | } | ||
| 251 | for (const auto& desc : info.texture_descriptors) { | 377 | for (const auto& desc : info.texture_descriptors) { |
| 252 | texture_buffer_index += desc.count; | 378 | texture_buffer_index += desc.count; |
| 253 | } | 379 | } |
| 254 | for (const auto& desc : info.image_descriptors) { | 380 | if constexpr (Spec::has_images) { |
| 255 | texture_buffer_index += desc.count; | 381 | for (const auto& desc : info.image_descriptors) { |
| 382 | texture_buffer_index += desc.count; | ||
| 383 | } | ||
| 256 | } | 384 | } |
| 385 | }}; | ||
| 386 | if constexpr (Spec::enabled_stages[0]) { | ||
| 387 | bind_stage_info(0); | ||
| 388 | } | ||
| 389 | if constexpr (Spec::enabled_stages[1]) { | ||
| 390 | bind_stage_info(1); | ||
| 391 | } | ||
| 392 | if constexpr (Spec::enabled_stages[2]) { | ||
| 393 | bind_stage_info(2); | ||
| 394 | } | ||
| 395 | if constexpr (Spec::enabled_stages[3]) { | ||
| 396 | bind_stage_info(3); | ||
| 397 | } | ||
| 398 | if constexpr (Spec::enabled_stages[4]) { | ||
| 399 | bind_stage_info(4); | ||
| 257 | } | 400 | } |
| 258 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | ||
| 259 | 401 | ||
| 402 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | ||
| 260 | buffer_cache.BindHostGeometryBuffers(is_indexed); | 403 | buffer_cache.BindHostGeometryBuffers(is_indexed); |
| 261 | 404 | ||
| 262 | update_descriptor_queue.Acquire(); | 405 | update_descriptor_queue.Acquire(); |
| 263 | 406 | ||
| 264 | const VkSampler* samplers_it{samplers.data()}; | 407 | const VkSampler* samplers_it{samplers.data()}; |
| 265 | const ImageId* views_it{image_view_ids.data()}; | 408 | const ImageId* views_it{image_view_ids.data()}; |
| 266 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { | 409 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 267 | buffer_cache.BindHostStageBuffers(stage); | 410 | buffer_cache.BindHostStageBuffers(stage); |
| 268 | PushImageDescriptors(stage_infos[stage], samplers_it, views_it, texture_cache, | 411 | PushImageDescriptors(stage_infos[stage], samplers_it, views_it, texture_cache, |
| 269 | update_descriptor_queue); | 412 | update_descriptor_queue); |
| 413 | }}; | ||
| 414 | if constexpr (Spec::enabled_stages[0]) { | ||
| 415 | prepare_stage(0); | ||
| 416 | } | ||
| 417 | if constexpr (Spec::enabled_stages[1]) { | ||
| 418 | prepare_stage(1); | ||
| 419 | } | ||
| 420 | if constexpr (Spec::enabled_stages[2]) { | ||
| 421 | prepare_stage(2); | ||
| 422 | } | ||
| 423 | if constexpr (Spec::enabled_stages[3]) { | ||
| 424 | prepare_stage(3); | ||
| 270 | } | 425 | } |
| 426 | if constexpr (Spec::enabled_stages[4]) { | ||
| 427 | prepare_stage(4); | ||
| 428 | } | ||
| 429 | ConfigureDraw(); | ||
| 430 | } | ||
| 431 | |||
| 432 | void GraphicsPipeline::ConfigureDraw() { | ||
| 271 | texture_cache.UpdateRenderTargets(false); | 433 | texture_cache.UpdateRenderTargets(false); |
| 272 | scheduler.RequestRenderpass(texture_cache.GetFramebuffer()); | 434 | scheduler.RequestRenderpass(texture_cache.GetFramebuffer()); |
| 273 | 435 | ||
| @@ -550,4 +712,23 @@ void GraphicsPipeline::MakePipeline(const Device& device, VkRenderPass render_pa | |||
| 550 | }); | 712 | }); |
| 551 | } | 713 | } |
| 552 | 714 | ||
| 715 | void GraphicsPipeline::Validate() { | ||
| 716 | size_t num_images{}; | ||
| 717 | for (const auto& info : stage_infos) { | ||
| 718 | for (const auto& desc : info.texture_buffer_descriptors) { | ||
| 719 | num_images += desc.count; | ||
| 720 | } | ||
| 721 | for (const auto& desc : info.image_buffer_descriptors) { | ||
| 722 | num_images += desc.count; | ||
| 723 | } | ||
| 724 | for (const auto& desc : info.texture_descriptors) { | ||
| 725 | num_images += desc.count; | ||
| 726 | } | ||
| 727 | for (const auto& desc : info.image_descriptors) { | ||
| 728 | num_images += desc.count; | ||
| 729 | } | ||
| 730 | } | ||
| 731 | ASSERT(num_images <= MAX_IMAGE_ELEMENTS); | ||
| 732 | } | ||
| 733 | |||
| 553 | } // namespace Vulkan | 734 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index fd787840b..edab5703f 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h | |||
| @@ -75,8 +75,6 @@ public: | |||
| 75 | std::array<vk::ShaderModule, NUM_STAGES> stages, | 75 | std::array<vk::ShaderModule, NUM_STAGES> stages, |
| 76 | const std::array<const Shader::Info*, NUM_STAGES>& infos); | 76 | const std::array<const Shader::Info*, NUM_STAGES>& infos); |
| 77 | 77 | ||
| 78 | void Configure(bool is_indexed); | ||
| 79 | |||
| 80 | GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete; | 78 | GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete; |
| 81 | GraphicsPipeline(GraphicsPipeline&&) noexcept = delete; | 79 | GraphicsPipeline(GraphicsPipeline&&) noexcept = delete; |
| 82 | 80 | ||
| @@ -85,6 +83,10 @@ public: | |||
| 85 | 83 | ||
| 86 | void AddTransition(GraphicsPipeline* transition); | 84 | void AddTransition(GraphicsPipeline* transition); |
| 87 | 85 | ||
| 86 | void Configure(bool is_indexed) { | ||
| 87 | configure_func(this, is_indexed); | ||
| 88 | } | ||
| 89 | |||
| 88 | GraphicsPipeline* Next(const GraphicsPipelineCacheKey& current_key) noexcept { | 90 | GraphicsPipeline* Next(const GraphicsPipelineCacheKey& current_key) noexcept { |
| 89 | if (key == current_key) { | 91 | if (key == current_key) { |
| 90 | return this; | 92 | return this; |
| @@ -94,9 +96,23 @@ public: | |||
| 94 | : nullptr; | 96 | : nullptr; |
| 95 | } | 97 | } |
| 96 | 98 | ||
| 99 | template <typename Spec> | ||
| 100 | static auto MakeConfigureSpecFunc() { | ||
| 101 | return [](GraphicsPipeline* pipeline, bool is_indexed) { | ||
| 102 | pipeline->ConfigureImpl<Spec>(is_indexed); | ||
| 103 | }; | ||
| 104 | } | ||
| 105 | |||
| 97 | private: | 106 | private: |
| 107 | template <typename Spec> | ||
| 108 | void ConfigureImpl(bool is_indexed); | ||
| 109 | |||
| 110 | void ConfigureDraw(); | ||
| 111 | |||
| 98 | void MakePipeline(const Device& device, VkRenderPass render_pass); | 112 | void MakePipeline(const Device& device, VkRenderPass render_pass); |
| 99 | 113 | ||
| 114 | void Validate(); | ||
| 115 | |||
| 100 | const GraphicsPipelineCacheKey key; | 116 | const GraphicsPipelineCacheKey key; |
| 101 | Tegra::Engines::Maxwell3D& maxwell3d; | 117 | Tegra::Engines::Maxwell3D& maxwell3d; |
| 102 | Tegra::MemoryManager& gpu_memory; | 118 | Tegra::MemoryManager& gpu_memory; |
| @@ -105,6 +121,8 @@ private: | |||
| 105 | VKScheduler& scheduler; | 121 | VKScheduler& scheduler; |
| 106 | VKUpdateDescriptorQueue& update_descriptor_queue; | 122 | VKUpdateDescriptorQueue& update_descriptor_queue; |
| 107 | 123 | ||
| 124 | void (*configure_func)(GraphicsPipeline*, bool); | ||
| 125 | |||
| 108 | std::vector<GraphicsPipelineCacheKey> transition_keys; | 126 | std::vector<GraphicsPipelineCacheKey> transition_keys; |
| 109 | std::vector<GraphicsPipeline*> transitions; | 127 | std::vector<GraphicsPipeline*> transitions; |
| 110 | 128 | ||