From 2a924d2b05b769e52d5fa15df6b0091702b99251 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 3 Jun 2016 20:00:28 -0500 Subject: [PATCH] Pass vertex buffer endianness into the BufferCache IssueCopy: Actually issue the pipeline barrier to transition the image --- src/xenia/gpu/vulkan/buffer_cache.cc | 14 ++--- src/xenia/gpu/vulkan/buffer_cache.h | 2 +- .../gpu/vulkan/vulkan_command_processor.cc | 53 ++++++++++--------- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/xenia/gpu/vulkan/buffer_cache.cc b/src/xenia/gpu/vulkan/buffer_cache.cc index 4ae98c864..02bd88a83 100644 --- a/src/xenia/gpu/vulkan/buffer_cache.cc +++ b/src/xenia/gpu/vulkan/buffer_cache.cc @@ -22,9 +22,6 @@ namespace vulkan { using xe::ui::vulkan::CheckResult; -// Space kept between tail and head when wrapping. -constexpr VkDeviceSize kDeadZone = 4 * 1024; - constexpr VkDeviceSize kConstantRegisterUniformRange = 512 * 4 * 4 + 8 * 4 + 32 * 4; @@ -250,7 +247,7 @@ std::pair BufferCache::UploadIndexBuffer( } std::pair BufferCache::UploadVertexBuffer( - const void* source_ptr, size_t source_length, + const void* source_ptr, size_t source_length, Endian endian, std::shared_ptr fence) { // TODO(benvanik): check cache. @@ -263,9 +260,12 @@ std::pair BufferCache::UploadVertexBuffer( // Copy data into the buffer. // TODO(benvanik): memcpy then use compute shaders to swap? - // Endian::k8in32, swap words. - xe::copy_and_swap_32_aligned(transient_buffer_->host_base() + offset, - source_ptr, source_length / 4); + assert_true(endian == Endian::k8in32); + if (endian == Endian::k8in32) { + // Endian::k8in32, swap words. + xe::copy_and_swap_32_aligned(transient_buffer_->host_base() + offset, + source_ptr, source_length / 4); + } return {transient_buffer_->gpu_buffer(), offset}; } diff --git a/src/xenia/gpu/vulkan/buffer_cache.h b/src/xenia/gpu/vulkan/buffer_cache.h index ee09585b5..8695fc36d 100644 --- a/src/xenia/gpu/vulkan/buffer_cache.h +++ b/src/xenia/gpu/vulkan/buffer_cache.h @@ -67,7 +67,7 @@ class BufferCache { // Returns a buffer and offset that can be used with vkCmdBindVertexBuffers. // Size will be VK_WHOLE_SIZE if the data could not be uploaded (OOM). std::pair UploadVertexBuffer( - const void* source_ptr, size_t source_length, + const void* source_ptr, size_t source_length, Endian endian, std::shared_ptr fence); // Flushes all pending data to the GPU. diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index 9c8e268a5..f31b28142 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -29,7 +29,7 @@ namespace vulkan { using namespace xe::gpu::xenos; using xe::ui::vulkan::CheckResult; -constexpr size_t kDefaultBufferCacheCapacity = 128 * 1024 * 1024; +constexpr size_t kDefaultBufferCacheCapacity = 256 * 1024 * 1024; VulkanCommandProcessor::VulkanCommandProcessor( VulkanGraphicsSystem* graphics_system, kernel::KernelState* kernel_state) @@ -501,9 +501,6 @@ bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type, } } - // Update the render cache's tracking state. - render_cache_->UpdateState(); - // Configure the pipeline for drawing. // This encodes all render state (blend, depth, etc), our shader stages, // and our vertex input layout. @@ -711,7 +708,6 @@ bool VulkanCommandProcessor::PopulateVertexBuffers( fetch = &group->vertex_fetch_2; break; } - assert_true(fetch->endian == 2); // TODO(benvanik): compute based on indices or vertex count. // THIS CAN BE MASSIVELY INCORRECT (too large). @@ -724,7 +720,8 @@ bool VulkanCommandProcessor::PopulateVertexBuffers( memory_->TranslatePhysical(fetch->address << 2); size_t source_length = valid_range; auto buffer_ref = buffer_cache_->UploadVertexBuffer( - source_ptr, source_length, current_batch_fence_); + source_ptr, source_length, static_cast(fetch->endian), + current_batch_fence_); if (buffer_ref.second == VK_WHOLE_SIZE) { // Failed to upload buffer. return false; @@ -939,26 +936,6 @@ bool VulkanCommandProcessor::IssueCopy() { assert_not_null(texture); texture->in_flight_fence = current_batch_fence_; - if (texture->image_layout == VK_IMAGE_LAYOUT_UNDEFINED) { - // Transition the image to a general layout. - VkImageMemoryBarrier image_barrier; - image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - image_barrier.pNext = nullptr; - image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - image_barrier.srcAccessMask = 0; - image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; - image_barrier.image = texture->image; - image_barrier.subresourceRange = {0, 0, 1, 0, 1}; - image_barrier.subresourceRange.aspectMask = - copy_src_select <= 3 - ? VK_IMAGE_ASPECT_COLOR_BIT - : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - texture->image_layout = VK_IMAGE_LAYOUT_GENERAL; - } - // For debugging purposes only (trace viewer) last_copy_base_ = texture->texture_info.guest_address; @@ -988,6 +965,30 @@ bool VulkanCommandProcessor::IssueCopy() { } auto command_buffer = current_command_buffer_; + if (texture->image_layout == VK_IMAGE_LAYOUT_UNDEFINED) { + // Transition the image to a general layout. + VkImageMemoryBarrier image_barrier; + image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_barrier.pNext = nullptr; + image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_barrier.srcAccessMask = 0; + image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + image_barrier.image = texture->image; + image_barrier.subresourceRange = {0, 0, 1, 0, 1}; + image_barrier.subresourceRange.aspectMask = + copy_src_select <= 3 + ? VK_IMAGE_ASPECT_COLOR_BIT + : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + texture->image_layout = VK_IMAGE_LAYOUT_GENERAL; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, + nullptr, 1, &image_barrier); + } + VkOffset3D resolve_offset = {dest_min_x, dest_min_y, 0}; VkExtent3D resolve_extent = {uint32_t(dest_max_x - dest_min_x), uint32_t(dest_max_y - dest_min_y), 1};