Permalink
Browse files

Add a QueueRunner logging facility. Set up a subpass dependency for t…

…he backbuffer pass.
  • Loading branch information...
hrydgard committed Oct 31, 2017
1 parent 330bdb8 commit 90d4296a6ad3ebff8a2a84456e45cb567c88db65
@@ -225,6 +225,7 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor
// TODO: We can just change the texture format and flip some bits around instead of this.
// Could share code with the texture cache perhaps.
// Could also convert directly into the pushbuffer easily.
const uint8_t *data = srcPixels;
if (srcPixelFormat != GE_FORMAT_8888 || srcStride != width) {
u32 neededSize = width * height * 4;
@@ -68,15 +68,15 @@ void VulkanQueueRunner::InitBackbufferRenderPass() {
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments[1].flags = 0;
VkAttachmentReference color_reference = {};
VkAttachmentReference color_reference{};
color_reference.attachment = 0;
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_reference{};
depth_reference.attachment = 1;
depth_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.flags = 0;
subpass.inputAttachmentCount = 0;
@@ -88,14 +88,23 @@ void VulkanQueueRunner::InitBackbufferRenderPass() {
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
VkRenderPassCreateInfo rp_info = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
rp_info.pNext = nullptr;
// For the built-in layout transitions.
VkSubpassDependency dep{};
dep.srcSubpass = VK_SUBPASS_EXTERNAL;
dep.dstSubpass = 0;
dep.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dep.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dep.srcAccessMask = 0;
dep.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dep.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo rp_info{ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
rp_info.attachmentCount = 2;
rp_info.pAttachments = attachments;
rp_info.subpassCount = 1;
rp_info.pSubpasses = &subpass;
rp_info.dependencyCount = 0;
rp_info.pDependencies = nullptr;
rp_info.dependencyCount = 1;
rp_info.pDependencies = &dep;
res = vkCreateRenderPass(vulkan_->GetDevice(), &rp_info, nullptr, &backbufferRenderPass_);
assert(res == VK_SUCCESS);
@@ -112,7 +121,7 @@ void VulkanQueueRunner::InitRenderpasses() {
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // TODO: Look into auto-transitioning to SAMPLED when appropriate.
attachments[0].flags = 0;
attachments[1].format = vulkan_->GetDeviceInfo().preferredDepthStencilFormat;
@@ -125,15 +134,15 @@ void VulkanQueueRunner::InitRenderpasses() {
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments[1].flags = 0;
VkAttachmentReference color_reference = {};
VkAttachmentReference color_reference{};
color_reference.attachment = 0;
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_reference = {};
VkAttachmentReference depth_reference{};
depth_reference.attachment = 1;
depth_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.flags = 0;
subpass.inputAttachmentCount = 0;
@@ -145,13 +154,12 @@ void VulkanQueueRunner::InitRenderpasses() {
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
VkRenderPassCreateInfo rp = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
VkRenderPassCreateInfo rp{ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
rp.attachmentCount = 2;
rp.pAttachments = attachments;
rp.subpassCount = 1;
rp.pSubpasses = &subpass;
rp.dependencyCount = 0;
rp.pDependencies = nullptr;
for (int depth = 0; depth < 3; depth++) {
switch ((VKRRenderPassAction)depth) {
@@ -201,6 +209,73 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, const std::vector<VKRStep
}
}
void VulkanQueueRunner::LogSteps(const std::vector<VKRStep *> &steps) {
ILOG("=======================================");
for (int i = 0; i < steps.size(); i++) {
const VKRStep &step = *steps[i];
switch (step.stepType) {
case VKRStepType::RENDER:
LogRenderPass(step);
break;
case VKRStepType::COPY:
LogCopy(step);
break;
case VKRStepType::BLIT:
LogBlit(step);
break;
case VKRStepType::READBACK:
LogReadback(step);
break;
}
}
}
void VulkanQueueRunner::LogRenderPass(const VKRStep &pass) {
int fb = (int)(intptr_t)(pass.render.framebuffer ? pass.render.framebuffer->framebuf : 0);
ILOG("RenderPass Begin(%x)", fb);
for (auto &cmd : pass.commands) {
switch (cmd.cmd) {
case VKRRenderCommand::BIND_PIPELINE:
ILOG(" BindPipeline(%x)", (int)(intptr_t)cmd.pipeline.pipeline);
break;
case VKRRenderCommand::BLEND:
ILOG(" Blend(%f, %f, %f, %f)", cmd.blendColor.color[0], cmd.blendColor.color[1], cmd.blendColor.color[2], cmd.blendColor.color[3]);
break;
case VKRRenderCommand::CLEAR:
ILOG(" Clear");
break;
case VKRRenderCommand::DRAW:
ILOG(" Draw(%d)", cmd.draw.count);
break;
case VKRRenderCommand::DRAW_INDEXED:
ILOG(" DrawIndexed(%d)", cmd.drawIndexed.count);
break;
case VKRRenderCommand::SCISSOR:
ILOG(" Scissor(%d, %d, %d, %d)", (int)cmd.scissor.scissor.offset.x, (int)cmd.scissor.scissor.offset.y, (int)cmd.scissor.scissor.extent.width, (int)cmd.scissor.scissor.extent.height);
break;
case VKRRenderCommand::STENCIL:
ILOG(" Stencil(ref=%d, compare=%d, write=%d)", cmd.stencil.stencilRef, cmd.stencil.stencilCompareMask, cmd.stencil.stencilWriteMask);
break;
case VKRRenderCommand::VIEWPORT:
ILOG(" Viewport(%f, %f, %f, %f, %f, %f)", cmd.viewport.vp.x, cmd.viewport.vp.y, cmd.viewport.vp.width, cmd.viewport.vp.height, cmd.viewport.vp.minDepth, cmd.viewport.vp.maxDepth);
break;
}
}
ILOG("RenderPass End(%x)", fb);
}
void VulkanQueueRunner::LogCopy(const VKRStep &pass) {
ILOG("Copy()");
}
void VulkanQueueRunner::LogBlit(const VKRStep &pass) {
ILOG("Blit()");
}
void VulkanQueueRunner::LogReadback(const VKRStep &pass) {
ILOG("Readback");
}
void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer cmd) {
// TODO: If there are multiple, we can transition them together.
for (const auto &iter : step.preTransitions) {
@@ -141,6 +141,7 @@ class VulkanQueueRunner {
backbuffer_ = fb;
}
void RunSteps(VkCommandBuffer cmd, const std::vector<VKRStep *> &steps);
void LogSteps(const std::vector<VKRStep *> &steps);
void CreateDeviceObjects();
void DestroyDeviceObjects();
@@ -168,6 +169,11 @@ class VulkanQueueRunner {
void PerformBlit(const VKRStep &pass, VkCommandBuffer cmd);
void PerformReadback(const VKRStep &pass, VkCommandBuffer cmd);
void LogRenderPass(const VKRStep &pass);
void LogCopy(const VKRStep &pass);
void LogBlit(const VKRStep &pass);
void LogReadback(const VKRStep &pass);
static void SetupTransitionToTransferSrc(VKRImage &img, VkImageMemoryBarrier &barrier, VkPipelineStageFlags &stage, VkImageAspectFlags aspect);
static void SetupTransitionToTransferDst(VKRImage &img, VkImageMemoryBarrier &barrier, VkPipelineStageFlags &stage, VkImageAspectFlags aspect);
@@ -597,13 +597,13 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) {
cmdBufs.push_back(frameData.mainCmd);
VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
if (triggerFence) {
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &acquireSemaphore_;
}
VkPipelineStageFlags waitStage[1] = { VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT };
VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT };
submit_info.pWaitDstStageMask = waitStage;
submit_info.commandBufferCount = (uint32_t)cmdBufs.size();
submit_info.pCommandBuffers = cmdBufs.data();
@@ -612,7 +612,12 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) {
submit_info.pSignalSemaphores = &renderingCompleteSemaphore_;
}
res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFence ? frameData.fence : VK_NULL_HANDLE);
assert(res == VK_SUCCESS);
if (res == VK_ERROR_DEVICE_LOST) {
// _assert_msg_(G3D, false, "Lost the Vulkan device! What did we do wrong?");
ELOG("DEVICE LOST");
} else {
assert(res == VK_SUCCESS);
}
if (useThread) {
VLOG("PULL: Frame %d.readyForFence = true", frame);
@@ -655,6 +660,7 @@ void VulkanRenderManager::Run(int frame) {
FrameData &frameData = frameData_[frame];
auto &stepsOnThread = frameData_[frame].steps;
VkCommandBuffer cmd = frameData.mainCmd;
// queueRunner_.LogSteps(stepsOnThread);
queueRunner_.RunSteps(cmd, stepsOnThread);
stepsOnThread.clear();
@@ -677,6 +683,8 @@ void VulkanRenderManager::FlushSync() {
Submit(frame, false);
// This is brutal! Should probably wait for a fence instead, not that it'll matter much since we'll
// still stall everything.
vkDeviceWaitIdle(vulkan_->GetDevice());
// At this point we can resume filling the command buffers for the current frame since

0 comments on commit 90d4296

Please sign in to comment.