Vulkan CP: Code refactoring
This commit is contained in:
@@ -251,6 +251,69 @@ void VulkanCommandProcessor::DestroySwapImage() {
|
|||||||
fb_memory_ = nullptr;
|
fb_memory_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanCommandProcessor::BeginFrame() {
|
||||||
|
assert_false(frame_open_);
|
||||||
|
|
||||||
|
// TODO(benvanik): bigger batches.
|
||||||
|
// TODO(DrChat): Decouple setup buffer from current batch.
|
||||||
|
// Begin a new batch, and allocate and begin a command buffer and setup buffer.
|
||||||
|
current_batch_fence_ = command_buffer_pool_->BeginBatch();
|
||||||
|
current_command_buffer_ = command_buffer_pool_->AcquireEntry();
|
||||||
|
current_setup_buffer_ = command_buffer_pool_->AcquireEntry();
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo command_buffer_begin_info;
|
||||||
|
command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
command_buffer_begin_info.pNext = nullptr;
|
||||||
|
command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
command_buffer_begin_info.pInheritanceInfo = nullptr;
|
||||||
|
auto status =
|
||||||
|
vkBeginCommandBuffer(current_command_buffer_, &command_buffer_begin_info);
|
||||||
|
CheckResult(status, "vkBeginCommandBuffer");
|
||||||
|
|
||||||
|
status =
|
||||||
|
vkBeginCommandBuffer(current_setup_buffer_, &command_buffer_begin_info);
|
||||||
|
CheckResult(status, "vkBeginCommandBuffer");
|
||||||
|
|
||||||
|
// Flag renderdoc down to start a capture if requested.
|
||||||
|
// The capture will end when these commands are submitted to the queue.
|
||||||
|
static uint32_t frame = 0;
|
||||||
|
if (device_->is_renderdoc_attached() && !capturing_ &&
|
||||||
|
(FLAGS_vulkan_renderdoc_capture_all || trace_requested_)) {
|
||||||
|
if (queue_mutex_) {
|
||||||
|
queue_mutex_->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
capturing_ = true;
|
||||||
|
trace_requested_ = false;
|
||||||
|
device_->BeginRenderDocFrameCapture();
|
||||||
|
|
||||||
|
if (queue_mutex_) {
|
||||||
|
queue_mutex_->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_open_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanCommandProcessor::EndFrame() {
|
||||||
|
if (current_render_state_) {
|
||||||
|
render_cache_->EndRenderPass();
|
||||||
|
current_render_state_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult status = VK_SUCCESS;
|
||||||
|
status = vkEndCommandBuffer(current_setup_buffer_);
|
||||||
|
CheckResult(status, "vkEndCommandBuffer");
|
||||||
|
status = vkEndCommandBuffer(current_command_buffer_);
|
||||||
|
CheckResult(status, "vkEndCommandBuffer");
|
||||||
|
|
||||||
|
current_command_buffer_ = nullptr;
|
||||||
|
current_setup_buffer_ = nullptr;
|
||||||
|
command_buffer_pool_->EndBatch();
|
||||||
|
|
||||||
|
frame_open_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
uint32_t frontbuffer_width,
|
uint32_t frontbuffer_width,
|
||||||
uint32_t frontbuffer_height) {
|
uint32_t frontbuffer_height) {
|
||||||
@@ -355,23 +418,15 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||||||
// Queue up current command buffers.
|
// Queue up current command buffers.
|
||||||
// TODO(benvanik): bigger batches.
|
// TODO(benvanik): bigger batches.
|
||||||
std::vector<VkCommandBuffer> submit_buffers;
|
std::vector<VkCommandBuffer> submit_buffers;
|
||||||
if (current_command_buffer_) {
|
if (frame_open_) {
|
||||||
if (current_render_state_) {
|
|
||||||
render_cache_->EndRenderPass();
|
|
||||||
current_render_state_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = vkEndCommandBuffer(current_setup_buffer_);
|
|
||||||
CheckResult(status, "vkEndCommandBuffer");
|
|
||||||
status = vkEndCommandBuffer(current_command_buffer_);
|
|
||||||
CheckResult(status, "vkEndCommandBuffer");
|
|
||||||
|
|
||||||
// TODO(DrChat): If the setup buffer is empty, don't bother queueing it up.
|
// TODO(DrChat): If the setup buffer is empty, don't bother queueing it up.
|
||||||
submit_buffers.push_back(current_setup_buffer_);
|
submit_buffers.push_back(current_setup_buffer_);
|
||||||
submit_buffers.push_back(current_command_buffer_);
|
submit_buffers.push_back(current_command_buffer_);
|
||||||
|
EndFrame();
|
||||||
|
}
|
||||||
|
|
||||||
current_command_buffer_ = nullptr;
|
if (opened_batch) {
|
||||||
current_setup_buffer_ = nullptr;
|
command_buffer_pool_->EndBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
submit_buffers.push_back(copy_commands);
|
submit_buffers.push_back(copy_commands);
|
||||||
@@ -413,8 +468,6 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
command_buffer_pool_->EndBatch();
|
|
||||||
|
|
||||||
if (cache_clear_requested_) {
|
if (cache_clear_requested_) {
|
||||||
cache_clear_requested_ = false;
|
cache_clear_requested_ = false;
|
||||||
vkWaitForFences(*device_, 1, ¤t_batch_fence_, VK_TRUE, -1);
|
vkWaitForFences(*device_, 1, ¤t_batch_fence_, VK_TRUE, -1);
|
||||||
@@ -493,46 +546,10 @@ bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool started_command_buffer = false;
|
bool started_frame = false;
|
||||||
if (!current_command_buffer_) {
|
if (!frame_open_) {
|
||||||
// TODO(benvanik): bigger batches.
|
BeginFrame();
|
||||||
// TODO(DrChat): Decouple setup buffer from current batch.
|
started_frame = true;
|
||||||
current_batch_fence_ = command_buffer_pool_->BeginBatch();
|
|
||||||
current_command_buffer_ = command_buffer_pool_->AcquireEntry();
|
|
||||||
current_setup_buffer_ = command_buffer_pool_->AcquireEntry();
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo command_buffer_begin_info;
|
|
||||||
command_buffer_begin_info.sType =
|
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
||||||
command_buffer_begin_info.pNext = nullptr;
|
|
||||||
command_buffer_begin_info.flags =
|
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
||||||
command_buffer_begin_info.pInheritanceInfo = nullptr;
|
|
||||||
auto status = vkBeginCommandBuffer(current_command_buffer_,
|
|
||||||
&command_buffer_begin_info);
|
|
||||||
CheckResult(status, "vkBeginCommandBuffer");
|
|
||||||
|
|
||||||
status =
|
|
||||||
vkBeginCommandBuffer(current_setup_buffer_, &command_buffer_begin_info);
|
|
||||||
CheckResult(status, "vkBeginCommandBuffer");
|
|
||||||
|
|
||||||
static uint32_t frame = 0;
|
|
||||||
if (device_->is_renderdoc_attached() && !capturing_ &&
|
|
||||||
(FLAGS_vulkan_renderdoc_capture_all || trace_requested_)) {
|
|
||||||
if (queue_mutex_) {
|
|
||||||
queue_mutex_->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
capturing_ = true;
|
|
||||||
trace_requested_ = false;
|
|
||||||
device_->BeginRenderDocFrameCapture();
|
|
||||||
|
|
||||||
if (queue_mutex_) {
|
|
||||||
queue_mutex_->unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
started_command_buffer = true;
|
|
||||||
}
|
}
|
||||||
auto command_buffer = current_command_buffer_;
|
auto command_buffer = current_command_buffer_;
|
||||||
auto setup_buffer = current_setup_buffer_;
|
auto setup_buffer = current_setup_buffer_;
|
||||||
@@ -561,13 +578,13 @@ bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||||||
command_buffer, current_render_state_, vertex_shader, pixel_shader,
|
command_buffer, current_render_state_, vertex_shader, pixel_shader,
|
||||||
primitive_type, &pipeline);
|
primitive_type, &pipeline);
|
||||||
if (pipeline_status == PipelineCache::UpdateStatus::kMismatch ||
|
if (pipeline_status == PipelineCache::UpdateStatus::kMismatch ||
|
||||||
started_command_buffer) {
|
started_frame) {
|
||||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
pipeline);
|
pipeline);
|
||||||
} else if (pipeline_status == PipelineCache::UpdateStatus::kError) {
|
} else if (pipeline_status == PipelineCache::UpdateStatus::kError) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pipeline_cache_->SetDynamicState(command_buffer, started_command_buffer);
|
pipeline_cache_->SetDynamicState(command_buffer, started_frame);
|
||||||
|
|
||||||
// Pass registers to the shaders.
|
// Pass registers to the shaders.
|
||||||
if (!PopulateConstants(command_buffer, vertex_shader, pixel_shader)) {
|
if (!PopulateConstants(command_buffer, vertex_shader, pixel_shader)) {
|
||||||
@@ -899,26 +916,23 @@ bool VulkanCommandProcessor::IssueCopy() {
|
|||||||
assert_true(fetch->size == 6);
|
assert_true(fetch->size == 6);
|
||||||
const uint8_t* vertex_addr = memory_->TranslatePhysical(fetch->address << 2);
|
const uint8_t* vertex_addr = memory_->TranslatePhysical(fetch->address << 2);
|
||||||
trace_writer_.WriteMemoryRead(fetch->address << 2, fetch->size * 4);
|
trace_writer_.WriteMemoryRead(fetch->address << 2, fetch->size * 4);
|
||||||
int32_t dest_min_x = int32_t((std::min(
|
|
||||||
std::min(
|
float dest_points[6];
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 0), Endian(fetch->endian)),
|
for (int i = 0; i < 6; i++) {
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 8), Endian(fetch->endian))),
|
dest_points[i] =
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 16), Endian(fetch->endian)))));
|
GpuSwap(xe::load<float>(vertex_addr + i * 4), Endian(fetch->endian));
|
||||||
int32_t dest_max_x = int32_t((std::max(
|
}
|
||||||
std::max(
|
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 0), Endian(fetch->endian)),
|
// Note: The xenos only supports rectangle copies (luckily)
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 8), Endian(fetch->endian))),
|
int32_t dest_min_x = int32_t(
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 16), Endian(fetch->endian)))));
|
(std::min(std::min(dest_points[0], dest_points[2]), dest_points[4])));
|
||||||
int32_t dest_min_y = int32_t((std::min(
|
int32_t dest_max_x = int32_t(
|
||||||
std::min(
|
(std::max(std::max(dest_points[0], dest_points[2]), dest_points[4])));
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 4), Endian(fetch->endian)),
|
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 12), Endian(fetch->endian))),
|
int32_t dest_min_y = int32_t(
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 20), Endian(fetch->endian)))));
|
(std::min(std::min(dest_points[1], dest_points[3]), dest_points[5])));
|
||||||
int32_t dest_max_y = int32_t((std::max(
|
int32_t dest_max_y = int32_t(
|
||||||
std::max(
|
(std::max(std::max(dest_points[1], dest_points[3]), dest_points[5])));
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 4), Endian(fetch->endian)),
|
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 12), Endian(fetch->endian))),
|
|
||||||
GpuSwap(xe::load<float>(vertex_addr + 20), Endian(fetch->endian)))));
|
|
||||||
|
|
||||||
uint32_t color_edram_base = 0;
|
uint32_t color_edram_base = 0;
|
||||||
uint32_t depth_edram_base = 0;
|
uint32_t depth_edram_base = 0;
|
||||||
@@ -972,26 +986,10 @@ bool VulkanCommandProcessor::IssueCopy() {
|
|||||||
// For debugging purposes only (trace viewer)
|
// For debugging purposes only (trace viewer)
|
||||||
last_copy_base_ = texture->texture_info.guest_address;
|
last_copy_base_ = texture->texture_info.guest_address;
|
||||||
|
|
||||||
if (!current_command_buffer_) {
|
if (!frame_open_) {
|
||||||
current_batch_fence_ = command_buffer_pool_->BeginBatch();
|
BeginFrame();
|
||||||
current_command_buffer_ = command_buffer_pool_->AcquireEntry();
|
|
||||||
current_setup_buffer_ = command_buffer_pool_->AcquireEntry();
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo command_buffer_begin_info;
|
|
||||||
command_buffer_begin_info.sType =
|
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
||||||
command_buffer_begin_info.pNext = nullptr;
|
|
||||||
command_buffer_begin_info.flags =
|
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
||||||
command_buffer_begin_info.pInheritanceInfo = nullptr;
|
|
||||||
auto status = vkBeginCommandBuffer(current_command_buffer_,
|
|
||||||
&command_buffer_begin_info);
|
|
||||||
CheckResult(status, "vkBeginCommandBuffer");
|
|
||||||
|
|
||||||
status =
|
|
||||||
vkBeginCommandBuffer(current_setup_buffer_, &command_buffer_begin_info);
|
|
||||||
CheckResult(status, "vkBeginCommandBuffer");
|
|
||||||
} else if (current_render_state_) {
|
} else if (current_render_state_) {
|
||||||
|
// Copy commands cannot be issued within a render pass.
|
||||||
render_cache_->EndRenderPass();
|
render_cache_->EndRenderPass();
|
||||||
current_render_state_ = nullptr;
|
current_render_state_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ class VulkanCommandProcessor : public CommandProcessor {
|
|||||||
|
|
||||||
void WriteRegister(uint32_t index, uint32_t value) override;
|
void WriteRegister(uint32_t index, uint32_t value) override;
|
||||||
|
|
||||||
|
void BeginFrame();
|
||||||
|
void EndFrame();
|
||||||
|
|
||||||
void CreateSwapImage(VkCommandBuffer setup_buffer, VkExtent2D extents);
|
void CreateSwapImage(VkCommandBuffer setup_buffer, VkExtent2D extents);
|
||||||
void DestroySwapImage();
|
void DestroySwapImage();
|
||||||
|
|
||||||
@@ -123,6 +126,7 @@ class VulkanCommandProcessor : public CommandProcessor {
|
|||||||
|
|
||||||
std::unique_ptr<ui::vulkan::CommandBufferPool> command_buffer_pool_;
|
std::unique_ptr<ui::vulkan::CommandBufferPool> command_buffer_pool_;
|
||||||
|
|
||||||
|
bool frame_open_ = false;
|
||||||
const RenderState* current_render_state_ = nullptr;
|
const RenderState* current_render_state_ = nullptr;
|
||||||
VkCommandBuffer current_command_buffer_ = nullptr;
|
VkCommandBuffer current_command_buffer_ = nullptr;
|
||||||
VkCommandBuffer current_setup_buffer_ = nullptr;
|
VkCommandBuffer current_setup_buffer_ = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user