mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Add a hidden debug option [Graphics]GfxDebugSplitSubmit to try to narrow down some Vulkan issues, see #10163. Also improve some asserts.
This commit is contained in:
parent
acdb89c898
commit
b6911d2764
@ -18,6 +18,7 @@
|
||||
// Additionally, Common/Vulkan/* , including this file, are also licensed
|
||||
// under the public domain.
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Vulkan/VulkanMemory.h"
|
||||
|
||||
VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size) : device_(vulkan->GetDevice()), buf_(0), offset_(0), size_(size), writePtr_(nullptr) {
|
||||
@ -44,7 +45,7 @@ bool VulkanPushBuffer::AddBuffer() {
|
||||
|
||||
VkResult res = vkCreateBuffer(device_, &b, nullptr, &info.buffer);
|
||||
if (VK_SUCCESS != res) {
|
||||
ELOG("vkCreateBuffer failed! result=%d", (int)res);
|
||||
_assert_msg_(G3D, false, "vkCreateBuffer failed! result=%d", (int)res);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -61,7 +62,7 @@ bool VulkanPushBuffer::AddBuffer() {
|
||||
|
||||
res = vkAllocateMemory(device_, &alloc, nullptr, &info.deviceMemory);
|
||||
if (VK_SUCCESS != res) {
|
||||
ELOG("vkAllocateMemory failed! result=%d", (int)res);
|
||||
_assert_msg_(G3D, false, "vkAllocateMemory failed! size=%d result=%d", (int)reqs.size, (int)res);
|
||||
vkDestroyBuffer(device_, info.buffer, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
@ -545,6 +545,7 @@ 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(false),
|
||||
|
@ -218,6 +218,7 @@ public:
|
||||
bool bHardwareTessellation;
|
||||
std::string sPostShaderName; // Off for off.
|
||||
bool bGfxDebugOutput;
|
||||
bool bGfxDebugSplitSubmit;
|
||||
|
||||
// Sound
|
||||
bool bEnableSound;
|
||||
|
@ -473,7 +473,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView
|
||||
descAlloc.descriptorSetCount = 1;
|
||||
VkResult result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc);
|
||||
// Even in release mode, this is bad.
|
||||
_assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space in pool. sz=%d", (int)frame->descSets.size());
|
||||
_assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space in pool. sz=%d res=%d", (int)frame->descSets.size(), (int)result);
|
||||
|
||||
// We just don't write to the slots we don't care about.
|
||||
// We need 8 now that we support secondary texture bindings.
|
||||
@ -1041,8 +1041,6 @@ DrawEngineVulkan::TessellationDataTransferVulkan::~TessellationDataTransferVulka
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) {
|
||||
colStride = 4;
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
// TODO: This SHOULD work without padding but I can't get it to work on nvidia, so had
|
||||
// to expand to vec4. Driver bug?
|
||||
struct TessData {
|
||||
@ -1064,6 +1062,5 @@ void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&po
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) {
|
||||
assert(pos);
|
||||
// Nothing to do here!
|
||||
}
|
||||
|
@ -278,6 +278,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
|
||||
VkPipeline pipeline;
|
||||
VkResult result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipe, nullptr, &pipeline);
|
||||
if (result != VK_SUCCESS) {
|
||||
_assert_msg_(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result));
|
||||
ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result));
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -212,7 +212,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
||||
return false;
|
||||
}
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
|
||||
bool splitSubmit = g_Config.bGfxDebugSplitSubmit;
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, splitSubmit);
|
||||
bool success = draw_->CreatePresets();
|
||||
assert(success); // Doesn't fail, we include the compiler.
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
|
@ -762,19 +762,19 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) {
|
||||
if (frameData.hasInitCommands) {
|
||||
cmdBufs[numCmdBufs++] = frameData.initCmd;
|
||||
frameData.hasInitCommands = false;
|
||||
}
|
||||
if (false) {
|
||||
// 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_(G3D, false, "Lost the Vulkan device!");
|
||||
} else {
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed! result=%d", (int)res);
|
||||
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_(G3D, false, "Lost the Vulkan device!");
|
||||
} else {
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%d", (int)res);
|
||||
}
|
||||
numCmdBufs = 0;
|
||||
}
|
||||
numCmdBufs = 0;
|
||||
}
|
||||
cmdBufs[numCmdBufs++] = frameData.mainCmd;
|
||||
|
||||
@ -795,7 +795,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) {
|
||||
if (res == VK_ERROR_DEVICE_LOST) {
|
||||
_assert_msg_(G3D, false, "Lost the Vulkan device!");
|
||||
} else {
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed! result=%d", (int)res);
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%d", (int)splitSubmit_, (int)res);
|
||||
}
|
||||
|
||||
// When !triggerFence, we notify after syncing with Vulkan.
|
||||
@ -823,8 +823,8 @@ void VulkanRenderManager::EndSubmitFrame(int frame) {
|
||||
present.waitSemaphoreCount = 1;
|
||||
|
||||
VkResult res = vkQueuePresentKHR(vulkan_->GetGraphicsQueue(), &present);
|
||||
// TODO: Deal with VK_SUBOPTIMAL_WSI ?
|
||||
if (res == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
// TODO: Deal with VK_SUBOPTIMAL_KHR ?
|
||||
if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) {
|
||||
// ignore, it'll be fine. this happens sometimes during resizes, and we do make sure to recreate the swap chain.
|
||||
} else {
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueuePresentKHR failed! result=%d", (int)res);
|
||||
|
@ -208,6 +208,10 @@ public:
|
||||
return !framebuffers_.empty();
|
||||
}
|
||||
|
||||
void SetSplitSubmit(bool split) {
|
||||
splitSubmit_ = split;
|
||||
}
|
||||
|
||||
private:
|
||||
bool InitBackbufferFramebuffers(int width, int height);
|
||||
bool InitDepthStencilBuffer(VkCommandBuffer cmd); // Used for non-buffered rendering.
|
||||
@ -259,6 +263,7 @@ private:
|
||||
bool insideFrame_ = false;
|
||||
VKRStep *curRenderStep_ = nullptr;
|
||||
std::vector<VKRStep *> steps_;
|
||||
bool splitSubmit_ = false;
|
||||
|
||||
// Execution time state
|
||||
bool run_ = true;
|
||||
|
@ -665,7 +665,7 @@ DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapt
|
||||
DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, D3D_FEATURE_LEVEL featureLevel, HWND hWnd);
|
||||
#endif
|
||||
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *context);
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *context, bool split);
|
||||
|
||||
// UBs for the preset shaders
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "Common/Vulkan/SPIRVDisasm.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/display.h"
|
||||
@ -348,7 +349,7 @@ class VKFramebuffer;
|
||||
|
||||
class VKContext : public DrawContext {
|
||||
public:
|
||||
VKContext(VulkanContext *vulkan);
|
||||
VKContext(VulkanContext *vulkan, bool splitSubmit);
|
||||
virtual ~VKContext();
|
||||
|
||||
const DeviceCaps &GetDeviceCaps() const override {
|
||||
@ -674,7 +675,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, const TextureDesc &desc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
VKContext::VKContext(VulkanContext *vulkan)
|
||||
VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
|
||||
: vulkan_(vulkan), caps_{}, renderManager_(vulkan) {
|
||||
caps_.anisoSupported = vulkan->GetFeaturesAvailable().samplerAnisotropy != 0;
|
||||
caps_.geometryShaderSupported = vulkan->GetFeaturesAvailable().geometryShader != 0;
|
||||
@ -755,6 +756,8 @@ VKContext::VKContext(VulkanContext *vulkan)
|
||||
assert(VK_SUCCESS == res);
|
||||
|
||||
pipelineCache_ = vulkan_->CreatePipelineCache();
|
||||
|
||||
renderManager_.SetSplitSubmit(splitSubmit);
|
||||
}
|
||||
|
||||
VKContext::~VKContext() {
|
||||
@ -1188,8 +1191,8 @@ void VKContext::Clear(int clearMask, uint32_t colorval, float depthVal, int sten
|
||||
renderManager_.Clear(colorval, depthVal, stencilVal, mask);
|
||||
}
|
||||
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *vulkan) {
|
||||
return new VKContext(vulkan);
|
||||
DrawContext *T3DCreateVulkanContext(VulkanContext *vulkan, bool split) {
|
||||
return new VKContext(vulkan, split);
|
||||
}
|
||||
|
||||
void AddFeature(std::vector<std::string> &features, const char *name, VkBool32 available, VkBool32 enabled) {
|
||||
|
Loading…
Reference in New Issue
Block a user