Pass vertex buffer endianness into the BufferCache

IssueCopy: Actually issue the pipeline barrier to transition the image
This commit is contained in:
Dr. Chat 2016-06-03 20:00:28 -05:00
parent 6dab81d0cd
commit 2a924d2b05
3 changed files with 35 additions and 34 deletions

View File

@ -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<VkBuffer, VkDeviceSize> BufferCache::UploadIndexBuffer(
}
std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadVertexBuffer(
const void* source_ptr, size_t source_length,
const void* source_ptr, size_t source_length, Endian endian,
std::shared_ptr<ui::vulkan::Fence> fence) {
// TODO(benvanik): check cache.
@ -263,9 +260,12 @@ std::pair<VkBuffer, VkDeviceSize> 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};
}

View File

@ -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<VkBuffer, VkDeviceSize> UploadVertexBuffer(
const void* source_ptr, size_t source_length,
const void* source_ptr, size_t source_length, Endian endian,
std::shared_ptr<ui::vulkan::Fence> fence);
// Flushes all pending data to the GPU.

View File

@ -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<const void*>(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<Endian>(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};