diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index c67a59367..d10d40bcb 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -1109,7 +1109,7 @@ VulkanCommandProcessor::GetPipelineLayout(uint32_t texture_count_pixel, pipeline_layout_key.texture_count_pixel = texture_count_pixel; pipeline_layout_key.texture_count_vertex = texture_count_vertex; { - auto it = pipeline_layouts_.find(pipeline_layout_key.key); + auto it = pipeline_layouts_.find(pipeline_layout_key); if (it != pipeline_layouts_.end()) { return &it->second; } @@ -1125,7 +1125,7 @@ VulkanCommandProcessor::GetPipelineLayout(uint32_t texture_count_pixel, texture_descriptor_set_layout_key.is_vertex = 0; texture_descriptor_set_layout_key.texture_count = texture_count_pixel; auto it = descriptor_set_layouts_textures_.find( - texture_descriptor_set_layout_key.key); + texture_descriptor_set_layout_key); if (it != descriptor_set_layouts_textures_.end()) { descriptor_set_layout_textures_pixel = it->second; } else { @@ -1154,7 +1154,7 @@ VulkanCommandProcessor::GetPipelineLayout(uint32_t texture_count_pixel, return nullptr; } descriptor_set_layouts_textures_.emplace( - texture_descriptor_set_layout_key.key, + texture_descriptor_set_layout_key, descriptor_set_layout_textures_pixel); } } else { @@ -1167,7 +1167,7 @@ VulkanCommandProcessor::GetPipelineLayout(uint32_t texture_count_pixel, texture_descriptor_set_layout_key.is_vertex = 0; texture_descriptor_set_layout_key.texture_count = texture_count_vertex; auto it = descriptor_set_layouts_textures_.find( - texture_descriptor_set_layout_key.key); + texture_descriptor_set_layout_key); if (it != descriptor_set_layouts_textures_.end()) { descriptor_set_layout_textures_vertex = it->second; } else { @@ -1196,7 +1196,7 @@ VulkanCommandProcessor::GetPipelineLayout(uint32_t texture_count_pixel, return nullptr; } descriptor_set_layouts_textures_.emplace( - texture_descriptor_set_layout_key.key, + texture_descriptor_set_layout_key, descriptor_set_layout_textures_vertex); } } else { @@ -1248,7 +1248,7 @@ VulkanCommandProcessor::GetPipelineLayout(uint32_t texture_count_pixel, return nullptr; } auto emplaced_pair = pipeline_layouts_.emplace( - std::piecewise_construct, std::forward_as_tuple(pipeline_layout_key.key), + std::piecewise_construct, std::forward_as_tuple(pipeline_layout_key), std::forward_as_tuple(pipeline_layout, descriptor_set_layout_textures_vertex, descriptor_set_layout_textures_pixel)); diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.h b/src/xenia/gpu/vulkan/vulkan_command_processor.h index c23279bcf..2f90ca614 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.h +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.h @@ -14,11 +14,14 @@ #include #include #include +#include #include #include #include #include +#include "xenia/base/assert.h" +#include "xenia/base/hash.h" #include "xenia/gpu/command_processor.h" #include "xenia/gpu/draw_util.h" #include "xenia/gpu/registers.h" @@ -167,26 +170,54 @@ class VulkanCommandProcessor : public CommandProcessor { }; union TextureDescriptorSetLayoutKey { + uint32_t key; struct { uint32_t is_vertex : 1; // For 0, use descriptor_set_layout_empty_ instead as these are owning // references. uint32_t texture_count : 31; }; - uint32_t key = 0; + + TextureDescriptorSetLayoutKey() : key(0) { + static_assert_size(*this, sizeof(key)); + } + + struct Hasher { + size_t operator()(const TextureDescriptorSetLayoutKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const TextureDescriptorSetLayoutKey& other_key) const { + return key == other_key.key; + } + bool operator!=(const TextureDescriptorSetLayoutKey& other_key) const { + return !(*this == other_key); + } }; - static_assert(sizeof(TextureDescriptorSetLayoutKey) == sizeof(uint32_t)); union PipelineLayoutKey { + uint32_t key; struct { // Pixel textures in the low bits since those are varied much more // commonly. uint32_t texture_count_pixel : 16; uint32_t texture_count_vertex : 16; }; - uint32_t key = 0; + + PipelineLayoutKey() : key(0) { static_assert_size(*this, sizeof(key)); } + + struct Hasher { + size_t operator()(const PipelineLayoutKey& key) const { + return std::hash{}(key.key); + } + }; + bool operator==(const PipelineLayoutKey& other_key) const { + return key == other_key.key; + } + bool operator!=(const PipelineLayoutKey& other_key) const { + return !(*this == other_key); + } }; - static_assert(sizeof(PipelineLayoutKey) == sizeof(uint32_t)); class PipelineLayout : public VulkanPipelineCache::PipelineLayoutProvider { public: @@ -319,13 +350,14 @@ class VulkanCommandProcessor : public CommandProcessor { VkDescriptorSetLayout descriptor_set_layout_shared_memory_and_edram_ = VK_NULL_HANDLE; - // TextureDescriptorSetLayoutKey::key -> VkDescriptorSetLayout. - // Layouts are referenced by pipeline_layouts_. - std::unordered_map + // Descriptor set layouts are referenced by pipeline_layouts_. + std::unordered_map descriptor_set_layouts_textures_; - // PipelineLayoutKey::key -> PipelineLayout. - // Layouts are referenced by VulkanPipelineCache. - std::unordered_map pipeline_layouts_; + // Pipeline layouts are referenced by VulkanPipelineCache. + std::unordered_map + pipeline_layouts_; std::unique_ptr shared_memory_;