summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrChat <arkolbed@gmail.com>2018-02-18 18:50:53 -0600
committerDrChat <arkolbed@gmail.com>2018-02-18 18:50:53 -0600
commit4e1a55f585dd3127f753a13c91a0837a1d836e73 (patch)
tree29a014df14c83fe9fbd6e4d4e6230508df04acd9
parent946373270960622603175e753bd50c382c74c817 (diff)
[Vulkan] Bind the vertex set to DS slot 2
-rw-r--r--src/xenia/gpu/vulkan/pipeline_cache.cc5
-rw-r--r--src/xenia/gpu/vulkan/pipeline_cache.h3
-rw-r--r--src/xenia/gpu/vulkan/vulkan_command_processor.cc75
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*>(&regs.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;
}