diff options
| author | DrChat <arkolbed@gmail.com> | 2018-02-18 18:50:53 -0600 |
|---|---|---|
| committer | DrChat <arkolbed@gmail.com> | 2018-02-18 18:50:53 -0600 |
| commit | 4e1a55f585dd3127f753a13c91a0837a1d836e73 (patch) | |
| tree | 29a014df14c83fe9fbd6e4d4e6230508df04acd9 | |
| parent | 946373270960622603175e753bd50c382c74c817 (diff) | |
[Vulkan] Bind the vertex set to DS slot 2
| -rw-r--r-- | src/xenia/gpu/vulkan/pipeline_cache.cc | 5 | ||||
| -rw-r--r-- | src/xenia/gpu/vulkan/pipeline_cache.h | 3 | ||||
| -rw-r--r-- | src/xenia/gpu/vulkan/vulkan_command_processor.cc | 75 |
3 files changed, 13 insertions, 70 deletions
diff --git a/src/xenia/gpu/vulkan/pipeline_cache.cc b/src/xenia/gpu/vulkan/pipeline_cache.cc index e9e20b408..65292e9ce 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/pipeline_cache.cc @@ -44,7 +44,8 @@ PipelineCache::~PipelineCache() { Shutdown(); } VkResult PipelineCache::Initialize( VkDescriptorSetLayout uniform_descriptor_set_layout, - VkDescriptorSetLayout texture_descriptor_set_layout) { + VkDescriptorSetLayout texture_descriptor_set_layout, + VkDescriptorSetLayout vertex_descriptor_set_layout) { VkResult status; // Initialize the shared driver pipeline cache. @@ -70,6 +71,8 @@ VkResult PipelineCache::Initialize( uniform_descriptor_set_layout, // All texture bindings. texture_descriptor_set_layout, + // Vertex bindings. + vertex_descriptor_set_layout, }; // Push constants used for draw parameters. diff --git a/src/xenia/gpu/vulkan/pipeline_cache.h b/src/xenia/gpu/vulkan/pipeline_cache.h index ec68edda5..17b0cd1f4 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.h +++ b/src/xenia/gpu/vulkan/pipeline_cache.h @@ -43,7 +43,8 @@ class PipelineCache { ~PipelineCache(); VkResult Initialize(VkDescriptorSetLayout uniform_descriptor_set_layout, - VkDescriptorSetLayout texture_descriptor_set_layout); + VkDescriptorSetLayout texture_descriptor_set_layout, + VkDescriptorSetLayout vertex_descriptor_set_layout); void Shutdown(); // Loads a shader from the cache, possibly translating it. diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index 888c70a80..7f9503204 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -106,7 +106,8 @@ bool VulkanCommandProcessor::SetupContext() { pipeline_cache_ = std::make_unique<PipelineCache>(register_file_, device_); status = pipeline_cache_->Initialize( buffer_cache_->constant_descriptor_set_layout(), - texture_cache_->texture_descriptor_set_layout()); + texture_cache_->texture_descriptor_set_layout(), + buffer_cache_->vertex_descriptor_set_layout()); if (status != VK_SUCCESS) { XELOGE("Unable to initialize pipeline cache"); pipeline_cache_->Shutdown(); @@ -823,74 +824,12 @@ bool VulkanCommandProcessor::PopulateVertexBuffers( } assert_true(vertex_bindings.size() <= 32); - VkBuffer all_buffers[32]; - 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; - const auto group = reinterpret_cast<xe_gpu_fetch_group_t*>(®s.values[r]); - const xe_gpu_vertex_fetch_t* fetch = nullptr; - switch (vertex_binding.fetch_constant % 3) { - case 0: - fetch = &group->vertex_fetch_0; - break; - case 1: - fetch = &group->vertex_fetch_1; - break; - case 2: - fetch = &group->vertex_fetch_2; - break; - } - - if (fetch->type != 0x3) { - // TODO(DrChat): Some games use type 0x0 (with no data). - return false; - } - - // TODO(benvanik): compute based on indices or vertex count. - // THIS CAN BE MASSIVELY INCORRECT (too large). - uint32_t source_length = fetch->size * 4; - - uint32_t physical_address = fetch->address << 2; - trace_writer_.WriteMemoryRead(physical_address, source_length); - - // Upload (or get a cached copy of) the buffer. - // TODO: Make the buffer cache ... actually cache buffers. We can have - // a list of buffers that were cached, and store those in chunks in a - // multiple of the host's page size. - // So, we need to track all vertex buffers in a sorted map, and track all - // write watches in a sorted map. When a vertex buffer is uploaded, track - // all untracked pages with 1-page write watches. In the callback, - // invalidate any overlapping vertex buffers. - // - // We would keep the old transient buffer as a staging buffer, and upload - // to a GPU-only buffer that tracks all cached vertex buffers. - auto buffer_ref = buffer_cache_->UploadVertexBuffer( - current_setup_buffer_, physical_address, source_length, - static_cast<Endian>(fetch->endian), current_batch_fence_); - if (buffer_ref.second == VK_WHOLE_SIZE) { - // Failed to upload buffer. - return false; - } - - // Stash the buffer reference for our bulk bind at the end. - all_buffers[buffer_index] = buffer_ref.first; - all_buffer_offsets[buffer_index] = buffer_ref.second; - ++buffer_index; - } - - // Bind buffers. - vkCmdBindVertexBuffers(command_buffer, 0, buffer_index, all_buffers, - all_buffer_offsets); + auto descriptor_set = buffer_cache_->PrepareVertexSet( + command_buffer, current_batch_fence_, vertex_bindings); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_cache_->pipeline_layout(), 2, 1, + &descriptor_set, 0, nullptr); return true; } |
