mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-30 19:24:23 +01:00
Add a QueueRunner logging facility. Set up a subpass dependency for the backbuffer pass.
This commit is contained in:
1 parent
330bdb8be8
commit
90d4296a6a
4 files changed
+105
-15
No files matched your search
@@ -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,7 +68,7 @@ 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;
|
||||
|
||||
@@ -76,7 +76,7 @@ void VulkanQueueRunner::InitBackbufferRenderPass() {
|
||||
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 @@ public:
|
||||
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 @@ private:
|
||||
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
|
||||
|
||||
Reference in new issue
Block a user