From 3e157972cc02eed4de6af050ac2aaf091b7af5c0 Mon Sep 17 00:00:00 2001 From: DrChat Date: Wed, 3 Jan 2018 16:40:31 -0600 Subject: [PATCH] [Vulkan] Add a few size checks on vertex bindings (max across all cards is 32) --- src/xenia/gpu/vulkan/pipeline_cache.cc | 10 ++++++++++ src/xenia/gpu/vulkan/pipeline_cache.h | 4 ++-- src/xenia/gpu/vulkan/vulkan_command_processor.cc | 6 ++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/xenia/gpu/vulkan/pipeline_cache.cc b/src/xenia/gpu/vulkan/pipeline_cache.cc index 1214fe0e0..4601274f8 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/pipeline_cache.cc @@ -1002,6 +1002,16 @@ PipelineCache::UpdateStatus PipelineCache::UpdateVertexInputState( auto& vertex_attrib_descrs = update_vertex_input_state_attrib_descrs_; uint32_t vertex_binding_count = 0; uint32_t vertex_attrib_count = 0; + + // Check and make sure we don't overflow. + if (vertex_shader->vertex_bindings().size() >= + xe::countof(vertex_binding_descrs)) { + XELOGE("UpdateVertexInputState failed: too many bindings! (%zd >= %zd)", + vertex_shader->vertex_bindings().size(), + xe::countof(vertex_binding_descrs)); + return UpdateStatus::kError; + } + for (const auto& vertex_binding : vertex_shader->vertex_bindings()) { assert_true(vertex_binding_count < xe::countof(vertex_binding_descrs)); auto& vertex_binding_descr = vertex_binding_descrs[vertex_binding_count++]; diff --git a/src/xenia/gpu/vulkan/pipeline_cache.h b/src/xenia/gpu/vulkan/pipeline_cache.h index 914f8ac4c..ec68edda5 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.h +++ b/src/xenia/gpu/vulkan/pipeline_cache.h @@ -184,9 +184,9 @@ class PipelineCache { void Reset() { std::memset(this, 0, sizeof(*this)); } } update_vertex_input_state_regs_; VkPipelineVertexInputStateCreateInfo update_vertex_input_state_info_; - VkVertexInputBindingDescription update_vertex_input_state_binding_descrs_[64]; + VkVertexInputBindingDescription update_vertex_input_state_binding_descrs_[32]; VkVertexInputAttributeDescription - update_vertex_input_state_attrib_descrs_[64]; + update_vertex_input_state_attrib_descrs_[96]; struct UpdateInputAssemblyStateRegisters { PrimitiveType primitive_type; diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index 9bab7fda5..d83a423b3 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -827,6 +827,12 @@ bool VulkanCommandProcessor::PopulateVertexBuffers( VkDeviceSize all_buffer_offsets[32]; uint32_t buffer_index = 0; + if (vertex_bindings.size() >= xe::countof(all_buffers)) { + XELOGE("PopulateVertexBuffers failed: Too many bindings! (%zd >= %zd)", + vertex_bindings.size(), xe::countof(all_buffers)); + return false; + } + for (const auto& vertex_binding : vertex_bindings) { int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + (vertex_binding.fetch_constant / 3) * 6;