mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Remove splitSubmit setting. Now we submit init commands before the acquire.
This commit is contained in:
parent
143be816cc
commit
242efba6f7
12 changed files with 59 additions and 50 deletions
|
@ -579,7 +579,6 @@ void GLRenderManager::EndSubmitFrame(int frame) {
|
|||
void GLRenderManager::Run(int frame) {
|
||||
BeginSubmitFrame(frame);
|
||||
|
||||
|
||||
FrameData &frameData = frameData_[frame];
|
||||
|
||||
auto &stepsOnThread = frameData_[frame].steps;
|
||||
|
|
|
@ -1129,7 +1129,6 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Don't execute empty renderpasses that keep the contents.
|
||||
if (step.commands.empty() && step.render.colorLoad == VKRRenderPassLoadAction::KEEP && step.render.depthLoad == VKRRenderPassLoadAction::KEEP && step.render.stencilLoad == VKRRenderPassLoadAction::KEEP) {
|
||||
// Flush the pending barrier
|
||||
|
@ -1179,6 +1178,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
|
|||
|
||||
// This reads the layout of the color and depth images, and chooses a render pass using them that
|
||||
// will transition to the desired final layout.
|
||||
//
|
||||
// NOTE: Flushes recordBarrier_.
|
||||
VKRRenderPass *renderPass = PerformBindFramebufferAsRenderTarget(step, cmd);
|
||||
|
||||
|
|
|
@ -1412,6 +1412,9 @@ void VulkanRenderManager::Wipe() {
|
|||
// the backbuffer image acquisition.
|
||||
void VulkanRenderManager::BeginSubmitFrame(int frame) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
|
||||
SubmitInitCommands(frame);
|
||||
|
||||
if (!frameData.hasBegun) {
|
||||
// Get the index of the next available swapchain image, and a semaphore to block command buffer execution on.
|
||||
VkResult res = vkAcquireNextImageKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), UINT64_MAX, acquireSemaphore_, (VkFence)VK_NULL_HANDLE, &frameData.curSwapchainImage);
|
||||
|
@ -1438,38 +1441,53 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) {
|
|||
}
|
||||
}
|
||||
|
||||
void VulkanRenderManager::SubmitInitCommands(int frame) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
if (!frameData.hasInitCommands) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frameData.profilingEnabled_) {
|
||||
// Pre-allocated query ID 1.
|
||||
vkCmdWriteTimestamp(frameData.initCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frameData.profile.queryPool, 1);
|
||||
}
|
||||
|
||||
VkResult res = vkEndCommandBuffer(frameData.initCmd);
|
||||
_assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res));
|
||||
|
||||
VkCommandBuffer cmdBufs[1];
|
||||
int numCmdBufs = 0;
|
||||
|
||||
cmdBufs[numCmdBufs++] = frameData.initCmd;
|
||||
// Send the init commands off separately, so they can be processed while we're building the rest of the list.
|
||||
// (Likely the CPU will be more than a frame ahead anyway, but this will help when we try to work on latency).
|
||||
VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||
submit_info.commandBufferCount = (uint32_t)numCmdBufs;
|
||||
submit_info.pCommandBuffers = cmdBufs;
|
||||
res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE);
|
||||
if (res == VK_ERROR_DEVICE_LOST) {
|
||||
_assert_msg_(false, "Lost the Vulkan device in split submit! If this happens again, switch Graphics Backend away from Vulkan");
|
||||
} else {
|
||||
_assert_msg_(res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res));
|
||||
}
|
||||
numCmdBufs = 0;
|
||||
|
||||
frameData.hasInitCommands = false;
|
||||
}
|
||||
|
||||
void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
if (frameData.hasInitCommands) {
|
||||
if (frameData.profilingEnabled_ && triggerFrameFence) {
|
||||
// Pre-allocated query ID 1.
|
||||
vkCmdWriteTimestamp(frameData.initCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frameData.profile.queryPool, 1);
|
||||
}
|
||||
VkResult res = vkEndCommandBuffer(frameData.initCmd);
|
||||
_assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res));
|
||||
}
|
||||
|
||||
VkResult res = vkEndCommandBuffer(frameData.mainCmd);
|
||||
_assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res));
|
||||
|
||||
VkCommandBuffer cmdBufs[2];
|
||||
SubmitInitCommands(frame);
|
||||
|
||||
// Submit the main and final cmdbuf, ending by signalling the fence.
|
||||
|
||||
VkCommandBuffer cmdBufs[1];
|
||||
int numCmdBufs = 0;
|
||||
if (frameData.hasInitCommands) {
|
||||
cmdBufs[numCmdBufs++] = frameData.initCmd;
|
||||
if (splitSubmit_) {
|
||||
// Send the init commands off separately. Used this once to confirm that the cause of a device loss was in the init cmdbuf.
|
||||
VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||
submit_info.commandBufferCount = (uint32_t)numCmdBufs;
|
||||
submit_info.pCommandBuffers = cmdBufs;
|
||||
res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE);
|
||||
if (res == VK_ERROR_DEVICE_LOST) {
|
||||
_assert_msg_(false, "Lost the Vulkan device in split submit! If this happens again, switch Graphics Backend away from Vulkan");
|
||||
} else {
|
||||
_assert_msg_(res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res));
|
||||
}
|
||||
numCmdBufs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cmdBufs[numCmdBufs++] = frameData.mainCmd;
|
||||
|
||||
VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||
|
@ -1489,7 +1507,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) {
|
|||
if (res == VK_ERROR_DEVICE_LOST) {
|
||||
_assert_msg_(false, "Lost the Vulkan device in vkQueueSubmit! If this happens again, switch Graphics Backend away from Vulkan");
|
||||
} else {
|
||||
_assert_msg_(res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res));
|
||||
_assert_msg_(res == VK_SUCCESS, "vkQueueSubmit failed (main)! result=%s", VulkanResultToString(res));
|
||||
}
|
||||
|
||||
// When !triggerFence, we notify after syncing with Vulkan.
|
||||
|
|
|
@ -445,10 +445,6 @@ public:
|
|||
return !framebuffers_.empty();
|
||||
}
|
||||
|
||||
void SetSplitSubmit(bool split) {
|
||||
splitSubmit_ = split;
|
||||
}
|
||||
|
||||
void SetInflightFrames(int f) {
|
||||
newInflightFrames_ = f < 1 || f > VulkanContext::MAX_INFLIGHT_FRAMES ? VulkanContext::MAX_INFLIGHT_FRAMES : f;
|
||||
}
|
||||
|
@ -479,6 +475,7 @@ private:
|
|||
void BeginSubmitFrame(int frame);
|
||||
void EndSubmitFrame(int frame);
|
||||
void Submit(int frame, bool triggerFence);
|
||||
void SubmitInitCommands(int frame);
|
||||
|
||||
// Bad for performance but sometimes necessary for synchronous CPU readbacks (screenshots and whatnot).
|
||||
void FlushSync();
|
||||
|
@ -508,10 +505,11 @@ private:
|
|||
bool readbackFenceUsed = false;
|
||||
|
||||
// These are on different threads so need separate pools.
|
||||
VkCommandPool cmdPoolInit;
|
||||
VkCommandPool cmdPoolMain;
|
||||
VkCommandPool cmdPoolInit; // Written to from main thread
|
||||
VkCommandPool cmdPoolMain; // Written to from render thread, which also submits
|
||||
VkCommandBuffer initCmd;
|
||||
VkCommandBuffer mainCmd;
|
||||
|
||||
bool hasInitCommands = false;
|
||||
std::vector<VKRStep *> steps;
|
||||
|
||||
|
@ -550,7 +548,6 @@ private:
|
|||
BoundingRect curRenderArea_;
|
||||
|
||||
std::vector<VKRStep *> steps_;
|
||||
bool splitSubmit_ = false;
|
||||
|
||||
// Execution time state
|
||||
bool run_ = true;
|
||||
|
|
|
@ -361,7 +361,7 @@ class VKFramebuffer;
|
|||
|
||||
class VKContext : public DrawContext {
|
||||
public:
|
||||
VKContext(VulkanContext *vulkan, bool splitSubmit);
|
||||
VKContext(VulkanContext *vulkan);
|
||||
virtual ~VKContext();
|
||||
|
||||
const DeviceCaps &GetDeviceCaps() const override {
|
||||
|
@ -762,7 +762,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
|
|||
return true;
|
||||
}
|
||||
|
||||
VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
|
||||
VKContext::VKContext(VulkanContext *vulkan)
|
||||
: vulkan_(vulkan), renderManager_(vulkan) {
|
||||
shaderLanguageDesc_.Init(GLSL_VULKAN);
|
||||
|
||||
|
@ -914,8 +914,6 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
|
|||
VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO };
|
||||
res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_);
|
||||
_assert_(VK_SUCCESS == res);
|
||||
|
||||
renderManager_.SetSplitSubmit(splitSubmit);
|
||||
}
|
||||
|
||||
VKContext::~VKContext() {
|
||||
|
@ -1395,8 +1393,8 @@ void VKContext::Clear(int clearMask, uint32_t colorval, float depthVal, int sten
|
|||
renderManager_.Clear(colorval, depthVal, stencilVal, mask);
|
||||
}
|
||||
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *vulkan, bool split) {
|
||||
return new VKContext(vulkan, split);
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *vulkan) {
|
||||
return new VKContext(vulkan);
|
||||
}
|
||||
|
||||
void AddFeature(std::vector<std::string> &features, const char *name, VkBool32 available, VkBool32 enabled) {
|
||||
|
|
|
@ -31,6 +31,6 @@ DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapt
|
|||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> adapterNames);
|
||||
#endif
|
||||
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *context, bool splitSubmit);
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *context);
|
||||
|
||||
} // namespace Draw
|
||||
|
|
|
@ -938,7 +938,6 @@ static ConfigSetting graphicsSettings[] = {
|
|||
ReportedConfigSetting("FragmentTestCache", &g_Config.bFragmentTestCache, true, true, true),
|
||||
|
||||
ConfigSetting("GfxDebugOutput", &g_Config.bGfxDebugOutput, false, false, false),
|
||||
ConfigSetting("GfxDebugSplitSubmit", &g_Config.bGfxDebugSplitSubmit, false, false, false),
|
||||
ConfigSetting("LogFrameDrops", &g_Config.bLogFrameDrops, false, true, false),
|
||||
|
||||
ConfigSetting("InflightFrames", &g_Config.iInflightFrames, 3, true, false),
|
||||
|
|
|
@ -176,6 +176,7 @@ public:
|
|||
bool bSustainedPerformanceMode; // Android: Slows clocks down to avoid overheating/speed fluctuations.
|
||||
bool bIgnoreScreenInsets; // Android: Center screen disregarding insets if this is enabled.
|
||||
bool bVSync;
|
||||
|
||||
int iFrameSkip;
|
||||
int iFrameSkipType;
|
||||
int iFastForwardMode; // See FastForwardMode in ConfigValues.h.
|
||||
|
@ -242,7 +243,6 @@ public:
|
|||
bool bShaderChainRequires60FPS;
|
||||
std::string sTextureShaderName;
|
||||
bool bGfxDebugOutput;
|
||||
bool bGfxDebugSplitSubmit;
|
||||
int iInflightFrames;
|
||||
bool bRenderDuplicateFrames;
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode,
|
|||
return false;
|
||||
}
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(vulkan_, false);
|
||||
draw_ = Draw::T3DCreateVulkanContext(vulkan_);
|
||||
SetGPUBackend(GPUBackend::VULKAN);
|
||||
bool success = draw_->CreatePresets();
|
||||
_assert_(success);
|
||||
|
|
|
@ -131,9 +131,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
|||
return false;
|
||||
}
|
||||
|
||||
bool splitSubmit = g_Config.bGfxDebugSplitSubmit;
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(vulkan_, splitSubmit);
|
||||
draw_ = Draw::T3DCreateVulkanContext(vulkan_);
|
||||
SetGPUBackend(GPUBackend::VULKAN, vulkan_->GetPhysicalDeviceProperties(deviceNum).properties.deviceName);
|
||||
bool success = draw_->CreatePresets();
|
||||
_assert_msg_(success, "Failed to compile preset shaders");
|
||||
|
|
|
@ -101,7 +101,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB
|
|||
|
||||
bool success = true;
|
||||
if (g_Vulkan->InitSwapchain()) {
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit);
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
SetGPUBackend(GPUBackend::VULKAN);
|
||||
success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.
|
||||
_assert_msg_(success, "Failed to compile preset shaders");
|
||||
|
|
|
@ -137,7 +137,7 @@ void LibretroVulkanContext::CreateDrawContext() {
|
|||
return;
|
||||
}
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(vk, false);
|
||||
draw_ = Draw::T3DCreateVulkanContext(vk);
|
||||
((VulkanRenderManager*)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER))->SetInflightFrames(g_Config.iInflightFrames);
|
||||
SetGPUBackend(GPUBackend::VULKAN);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue