Vulkan CP: Code refactoring
This commit is contained in:
parent
c416cbb61d
commit
90b0541d72
|
@ -251,6 +251,69 @@ void VulkanCommandProcessor::DestroySwapImage() {
|
|||
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,
|
||||
uint32_t frontbuffer_width,
|
||||
uint32_t frontbuffer_height) {
|
||||
|
@ -355,23 +418,15 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||
// Queue up current command buffers.
|
||||
// TODO(benvanik): bigger batches.
|
||||
std::vector<VkCommandBuffer> submit_buffers;
|
||||
if (current_command_buffer_) {
|
||||
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");
|
||||
|
||||
if (frame_open_) {
|
||||
// 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_command_buffer_);
|
||||
EndFrame();
|
||||
}
|
||||
|
||||
current_command_buffer_ = nullptr;
|
||||
current_setup_buffer_ = nullptr;
|
||||
if (opened_batch) {
|
||||
command_buffer_pool_->EndBatch();
|
||||
}
|
||||
|
||||
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_) {
|
||||
cache_clear_requested_ = false;
|
||||
vkWaitForFences(*device_, 1, ¤t_batch_fence_, VK_TRUE, -1);
|
||||
|
@ -493,46 +546,10 @@ bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool started_command_buffer = false;
|
||||
if (!current_command_buffer_) {
|
||||
// TODO(benvanik): bigger batches.
|
||||
// TODO(DrChat): Decouple setup buffer from current batch.
|
||||
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;
|
||||
bool started_frame = false;
|
||||
if (!frame_open_) {
|
||||
BeginFrame();
|
||||
started_frame = true;
|
||||
}
|
||||
auto command_buffer = current_command_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,
|
||||
primitive_type, &pipeline);
|
||||
if (pipeline_status == PipelineCache::UpdateStatus::kMismatch ||
|
||||
started_command_buffer) {
|
||||
started_frame) {
|
||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline);
|
||||
} else if (pipeline_status == PipelineCache::UpdateStatus::kError) {
|
||||
return false;
|
||||
}
|
||||
pipeline_cache_->SetDynamicState(command_buffer, started_command_buffer);
|
||||
pipeline_cache_->SetDynamicState(command_buffer, started_frame);
|
||||
|
||||
// Pass registers to the shaders.
|
||||
if (!PopulateConstants(command_buffer, vertex_shader, pixel_shader)) {
|
||||
|
@ -899,26 +916,23 @@ bool VulkanCommandProcessor::IssueCopy() {
|
|||
assert_true(fetch->size == 6);
|
||||
const uint8_t* vertex_addr = memory_->TranslatePhysical(fetch->address << 2);
|
||||
trace_writer_.WriteMemoryRead(fetch->address << 2, fetch->size * 4);
|
||||
int32_t dest_min_x = int32_t((std::min(
|
||||
std::min(
|
||||
GpuSwap(xe::load<float>(vertex_addr + 0), Endian(fetch->endian)),
|
||||
GpuSwap(xe::load<float>(vertex_addr + 8), Endian(fetch->endian))),
|
||||
GpuSwap(xe::load<float>(vertex_addr + 16), Endian(fetch->endian)))));
|
||||
int32_t dest_max_x = int32_t((std::max(
|
||||
std::max(
|
||||
GpuSwap(xe::load<float>(vertex_addr + 0), Endian(fetch->endian)),
|
||||
GpuSwap(xe::load<float>(vertex_addr + 8), Endian(fetch->endian))),
|
||||
GpuSwap(xe::load<float>(vertex_addr + 16), Endian(fetch->endian)))));
|
||||
int32_t dest_min_y = int32_t((std::min(
|
||||
std::min(
|
||||
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)))));
|
||||
int32_t dest_max_y = int32_t((std::max(
|
||||
std::max(
|
||||
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)))));
|
||||
|
||||
float dest_points[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
dest_points[i] =
|
||||
GpuSwap(xe::load<float>(vertex_addr + i * 4), Endian(fetch->endian));
|
||||
}
|
||||
|
||||
// Note: The xenos only supports rectangle copies (luckily)
|
||||
int32_t dest_min_x = int32_t(
|
||||
(std::min(std::min(dest_points[0], dest_points[2]), dest_points[4])));
|
||||
int32_t dest_max_x = int32_t(
|
||||
(std::max(std::max(dest_points[0], dest_points[2]), dest_points[4])));
|
||||
|
||||
int32_t dest_min_y = int32_t(
|
||||
(std::min(std::min(dest_points[1], dest_points[3]), dest_points[5])));
|
||||
int32_t dest_max_y = int32_t(
|
||||
(std::max(std::max(dest_points[1], dest_points[3]), dest_points[5])));
|
||||
|
||||
uint32_t color_edram_base = 0;
|
||||
uint32_t depth_edram_base = 0;
|
||||
|
@ -972,26 +986,10 @@ bool VulkanCommandProcessor::IssueCopy() {
|
|||
// For debugging purposes only (trace viewer)
|
||||
last_copy_base_ = texture->texture_info.guest_address;
|
||||
|
||||
if (!current_command_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");
|
||||
if (!frame_open_) {
|
||||
BeginFrame();
|
||||
} else if (current_render_state_) {
|
||||
// Copy commands cannot be issued within a render pass.
|
||||
render_cache_->EndRenderPass();
|
||||
current_render_state_ = nullptr;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,9 @@ class VulkanCommandProcessor : public CommandProcessor {
|
|||
|
||||
void WriteRegister(uint32_t index, uint32_t value) override;
|
||||
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
|
||||
void CreateSwapImage(VkCommandBuffer setup_buffer, VkExtent2D extents);
|
||||
void DestroySwapImage();
|
||||
|
||||
|
@ -123,6 +126,7 @@ class VulkanCommandProcessor : public CommandProcessor {
|
|||
|
||||
std::unique_ptr<ui::vulkan::CommandBufferPool> command_buffer_pool_;
|
||||
|
||||
bool frame_open_ = false;
|
||||
const RenderState* current_render_state_ = nullptr;
|
||||
VkCommandBuffer current_command_buffer_ = nullptr;
|
||||
VkCommandBuffer current_setup_buffer_ = nullptr;
|
||||
|
|
Loading…
Reference in New Issue