Merge pull request #10079 from hrydgard/vulkan-android-fixes

Vulkan lost-device fixes
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2017-11-10 16:11:58 +01:00
commit f014735ebf
29 files changed
+326 -214

No files matched your search

+122 -2
View File
@@ -65,6 +65,16 @@ std::string VulkanVendorString(uint32_t vendorId) {
}
}
const char *PresentModeString(VkPresentModeKHR presentMode) {
switch (presentMode) {
case VK_PRESENT_MODE_IMMEDIATE_KHR: return "IMMEDIATE";
case VK_PRESENT_MODE_MAILBOX_KHR: return "MAILBOX";
case VK_PRESENT_MODE_FIFO_KHR: return "FIFO";
case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return "FIFO_RELAXED";
default: return "UNKNOWN";
}
}
VulkanContext::VulkanContext() {
if (!VulkanLoad()) {
init_error_ = "Failed to load Vulkan driver library";
@@ -165,8 +175,13 @@ VkResult VulkanContext::CreateInstance(const char *app_name, int app_ver, uint32
}
VulkanContext::~VulkanContext() {
assert(instance_ == VK_NULL_HANDLE);
}
void VulkanContext::DestroyInstance() {
vkDestroyInstance(instance_, nullptr);
VulkanFree();
instance_ = VK_NULL_HANDLE;
}
void VulkanContext::BeginFrame() {
@@ -214,6 +229,7 @@ bool VulkanContext::InitObjects() {
}
void VulkanContext::DestroyObjects() {
ILOG("VulkanContext::DestroyObjects (including swapchain)");
if (swapchain_ != VK_NULL_HANDLE)
vkDestroySwapchainKHR(device_, swapchain_, nullptr);
swapchain_ = VK_NULL_HANDLE;
@@ -580,12 +596,15 @@ void VulkanContext::InitSurfaceAndroid(ANativeWindow *wnd, int width, int height
void VulkanContext::ReinitSurfaceAndroid(int width, int height) {
if (surface_ != VK_NULL_HANDLE) {
ILOG("Destroying Android Vulkan surface (%d, %d)", width_, height_);
vkDestroySurfaceKHR(instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE;
}
VkResult U_ASSERT_ONLY res;
ILOG("Creating Android Vulkan surface (%d, %d)", width, height);
VkAndroidSurfaceCreateInfoKHR android = { VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR };
android.flags = 0;
android.window = native_window;
@@ -710,7 +729,7 @@ bool VulkanContext::InitSwapchain() {
// to fall back in a sensible way.
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
for (size_t i = 0; i < presentModeCount; i++) {
ILOG("Supported present mode: %d", presentModes[i]);
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
}
for (size_t i = 0; i < presentModeCount; i++) {
if (swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
@@ -734,7 +753,7 @@ bool VulkanContext::InitSwapchain() {
// HACK
swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
#endif
ILOG("Chosen present mode: %d", swapchainPresentMode);
ILOG("Chosen present mode: %d (%s)", swapchainPresentMode, PresentModeString(swapchainPresentMode));
delete[] presentModes;
// Determine the number of VkImage's to use in the swap chain (we desire to
// own only 1 image at a time, besides the images being displayed and
@@ -797,6 +816,7 @@ VkFence VulkanContext::CreateFence(bool presignalled) {
}
void VulkanContext::DestroyDevice() {
ILOG("VulkanContext::DestroyDevice (performing deletes)");
// If there happen to be any pending deletes, now is a good time.
for (int i = 0; i < ARRAY_SIZE(frame_); i++) {
frame_[i].deleteList.PerformDeletes(device_);
@@ -962,3 +982,103 @@ const char *VulkanResultToString(VkResult res) {
return "VK_ERROR_...(unknown)";
}
}
void VulkanDeleteList::Take(VulkanDeleteList &del) {
assert(cmdPools_.size() == 0);
assert(descPools_.size() == 0);
assert(modules_.size() == 0);
assert(buffers_.size() == 0);
assert(bufferViews_.size() == 0);
assert(images_.size() == 0);
assert(imageViews_.size() == 0);
assert(deviceMemory_.size() == 0);
assert(samplers_.size() == 0);
assert(pipelines_.size() == 0);
assert(pipelineCaches_.size() == 0);
assert(renderPasses_.size() == 0);
assert(framebuffers_.size() == 0);
assert(callbacks_.size() == 0);
cmdPools_ = std::move(del.cmdPools_);
descPools_ = std::move(del.descPools_);
modules_ = std::move(del.modules_);
buffers_ = std::move(del.buffers_);
bufferViews_ = std::move(del.bufferViews_);
images_ = std::move(del.images_);
imageViews_ = std::move(del.imageViews_);
deviceMemory_ = std::move(del.deviceMemory_);
samplers_ = std::move(del.samplers_);
pipelines_ = std::move(del.pipelines_);
pipelineCaches_ = std::move(del.pipelineCaches_);
renderPasses_ = std::move(del.renderPasses_);
framebuffers_ = std::move(del.framebuffers_);
pipelineLayouts_ = std::move(del.pipelineLayouts_);
descSetLayouts_ = std::move(del.descSetLayouts_);
callbacks_ = std::move(del.callbacks_);
}
void VulkanDeleteList::PerformDeletes(VkDevice device) {
for (auto &cmdPool : cmdPools_) {
vkDestroyCommandPool(device, cmdPool, nullptr);
}
cmdPools_.clear();
for (auto &descPool : descPools_) {
vkDestroyDescriptorPool(device, descPool, nullptr);
}
descPools_.clear();
for (auto &module : modules_) {
vkDestroyShaderModule(device, module, nullptr);
}
modules_.clear();
for (auto &buf : buffers_) {
vkDestroyBuffer(device, buf, nullptr);
}
buffers_.clear();
for (auto &bufView : bufferViews_) {
vkDestroyBufferView(device, bufView, nullptr);
}
bufferViews_.clear();
for (auto &image : images_) {
vkDestroyImage(device, image, nullptr);
}
images_.clear();
for (auto &imageView : imageViews_) {
vkDestroyImageView(device, imageView, nullptr);
}
imageViews_.clear();
for (auto &mem : deviceMemory_) {
vkFreeMemory(device, mem, nullptr);
}
deviceMemory_.clear();
for (auto &sampler : samplers_) {
vkDestroySampler(device, sampler, nullptr);
}
samplers_.clear();
for (auto &pipeline : pipelines_) {
vkDestroyPipeline(device, pipeline, nullptr);
}
pipelines_.clear();
for (auto &pcache : pipelineCaches_) {
vkDestroyPipelineCache(device, pcache, nullptr);
}
pipelineCaches_.clear();
for (auto &renderPass : renderPasses_) {
vkDestroyRenderPass(device, renderPass, nullptr);
}
renderPasses_.clear();
for (auto &framebuffer : framebuffers_) {
vkDestroyFramebuffer(device, framebuffer, nullptr);
}
framebuffers_.clear();
for (auto &pipeLayout : pipelineLayouts_) {
vkDestroyPipelineLayout(device, pipeLayout, nullptr);
}
pipelineLayouts_.clear();
for (auto &descSetLayout : descSetLayouts_) {
vkDestroyDescriptorSetLayout(device, descSetLayout, nullptr);
}
descSetLayouts_.clear();
for (auto &callback : callbacks_) {
callback.func(callback.userdata);
}
callbacks_.clear();
}
+5 -100
View File
@@ -71,6 +71,7 @@ class VulkanDeleteList {
};
public:
// NOTE: These all take reference handles so they can zero the input value.
void QueueDeleteCommandPool(VkCommandPool &pool) { cmdPools_.push_back(pool); pool = VK_NULL_HANDLE; }
void QueueDeleteDescriptorPool(VkDescriptorPool &pool) { descPools_.push_back(pool); pool = VK_NULL_HANDLE; }
void QueueDeleteShaderModule(VkShaderModule &module) { modules_.push_back(module); module = VK_NULL_HANDLE; }
@@ -88,105 +89,8 @@ public:
void QueueDeleteDescriptorSetLayout(VkDescriptorSetLayout &descSetLayout) { descSetLayouts_.push_back(descSetLayout); descSetLayout = VK_NULL_HANDLE; }
void QueueCallback(void(*func)(void *userdata), void *userdata) { callbacks_.push_back(Callback(func, userdata)); }
void Take(VulkanDeleteList &del) {
assert(cmdPools_.size() == 0);
assert(descPools_.size() == 0);
assert(modules_.size() == 0);
assert(buffers_.size() == 0);
assert(bufferViews_.size() == 0);
assert(images_.size() == 0);
assert(imageViews_.size() == 0);
assert(deviceMemory_.size() == 0);
assert(samplers_.size() == 0);
assert(pipelines_.size() == 0);
assert(pipelineCaches_.size() == 0);
assert(renderPasses_.size() == 0);
assert(framebuffers_.size() == 0);
assert(callbacks_.size() == 0);
cmdPools_ = std::move(del.cmdPools_);
descPools_ = std::move(del.descPools_);
modules_ = std::move(del.modules_);
buffers_ = std::move(del.buffers_);
bufferViews_ = std::move(del.bufferViews_);
images_ = std::move(del.images_);
imageViews_ = std::move(del.imageViews_);
deviceMemory_ = std::move(del.deviceMemory_);
samplers_ = std::move(del.samplers_);
pipelines_ = std::move(del.pipelines_);
pipelineCaches_ = std::move(del.pipelineCaches_);
renderPasses_ = std::move(del.renderPasses_);
framebuffers_ = std::move(del.framebuffers_);
pipelineLayouts_ = std::move(del.pipelineLayouts_);
descSetLayouts_ = std::move(del.descSetLayouts_);
callbacks_ = std::move(del.callbacks_);
}
void PerformDeletes(VkDevice device) {
for (auto &cmdPool : cmdPools_) {
vkDestroyCommandPool(device, cmdPool, nullptr);
}
cmdPools_.clear();
for (auto &descPool : descPools_) {
vkDestroyDescriptorPool(device, descPool, nullptr);
}
descPools_.clear();
for (auto &module : modules_) {
vkDestroyShaderModule(device, module, nullptr);
}
modules_.clear();
for (auto &buf : buffers_) {
vkDestroyBuffer(device, buf, nullptr);
}
buffers_.clear();
for (auto &bufView : bufferViews_) {
vkDestroyBufferView(device, bufView, nullptr);
}
bufferViews_.clear();
for (auto &image : images_) {
vkDestroyImage(device, image, nullptr);
}
images_.clear();
for (auto &imageView : imageViews_) {
vkDestroyImageView(device, imageView, nullptr);
}
imageViews_.clear();
for (auto &mem : deviceMemory_) {
vkFreeMemory(device, mem, nullptr);
}
deviceMemory_.clear();
for (auto &sampler : samplers_) {
vkDestroySampler(device, sampler, nullptr);
}
samplers_.clear();
for (auto &pipeline : pipelines_) {
vkDestroyPipeline(device, pipeline, nullptr);
}
pipelines_.clear();
for (auto &pcache : pipelineCaches_) {
vkDestroyPipelineCache(device, pcache, nullptr);
}
pipelineCaches_.clear();
for (auto &renderPass : renderPasses_) {
vkDestroyRenderPass(device, renderPass, nullptr);
}
renderPasses_.clear();
for (auto &framebuffer : framebuffers_) {
vkDestroyFramebuffer(device, framebuffer, nullptr);
}
framebuffers_.clear();
for (auto &pipeLayout : pipelineLayouts_) {
vkDestroyPipelineLayout(device, pipeLayout, nullptr);
}
pipelineLayouts_.clear();
for (auto &descSetLayout : descSetLayouts_) {
vkDestroyDescriptorSetLayout(device, descSetLayout, nullptr);
}
descSetLayouts_.clear();
for (auto &callback : callbacks_) {
callback.func(callback.userdata);
}
callbacks_.clear();
}
void Take(VulkanDeleteList &del);
void PerformDeletes(VkDevice device);
private:
std::vector<VkCommandPool> cmdPools_;
@@ -214,7 +118,8 @@ public:
~VulkanContext();
VkResult CreateInstance(const char *app_name, int app_ver, uint32_t flags);
void DestroyInstance();
int GetBestPhysicalDevice();
void ChooseDevice(int physical_device);
bool EnableDeviceExtension(const char *extension);
-1
View File
@@ -78,7 +78,6 @@ void VulkanPushBuffer::Destroy(VulkanContext *vulkan) {
vulkan->Delete().QueueDeleteBuffer(info.buffer);
vulkan->Delete().QueueDeleteDeviceMemory(info.deviceMemory);
}
buffers_.clear();
}
+1 -1
View File
@@ -172,7 +172,7 @@ bool UpdateScreenScale(int width, int height) {
dp_yres = new_dp_yres;
pixel_xres = width;
pixel_yres = height;
INFO_LOG(SYSTEM, "pixel_res: %dx%d", pixel_xres, pixel_yres);
INFO_LOG(SYSTEM, "pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres);
NativeResized();
return true;
}
-7
View File
@@ -137,13 +137,6 @@ void SoftwareTransform(
bool throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0;
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
// TODO: Split up into multiple draw calls for GLES 2.0 where you can't guarantee support for more than 0x10000 verts.
#if defined(MOBILE_DEVICE)
if (vertexCount > 0x10000/3)
vertexCount = 0x10000/3;
#endif
float uscale = 1.0f;
float vscale = 1.0f;
if (throughmode) {
+8 -1
View File
@@ -701,8 +701,15 @@ rotateVBO:
params.allowSeparateAlphaClear = true;
int maxIndex = indexGen.MaxIndex();
int vertexCount = indexGen.VertexCount();
// TODO: Split up into multiple draw calls for GLES 2.0 where you can't guarantee support for more than 0x10000 verts.
#if defined(MOBILE_DEVICE)
if (vertexCount > 0x10000 / 3)
vertexCount = 0x10000 / 3;
#endif
SoftwareTransform(
prim, indexGen.VertexCount(),
prim, vertexCount,
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
maxIndex, drawBuffer, numTrans, drawIndexed, &params, &result);
ApplyDrawStateLate();
+15 -3
View File
@@ -60,14 +60,26 @@ static VkFormat GetClutDestFormat(GEPaletteFormat format, VkComponentMapping *co
DepalShaderCacheVulkan::DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan)
: draw_(draw), vulkan_(vulkan) {
std::string errors;
vshader_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, depal_vs, &errors);
assert(vshader_ != VK_NULL_HANDLE);
DeviceRestore(draw, vulkan);
}
DepalShaderCacheVulkan::~DepalShaderCacheVulkan() {
DeviceLost();
}
void DepalShaderCacheVulkan::DeviceLost() {
Clear();
vulkan_->Delete().QueueDeleteShaderModule(vshader_);
draw_ = nullptr;
vulkan_ = nullptr;
}
void DepalShaderCacheVulkan::DeviceRestore(Draw::DrawContext *draw, VulkanContext *vulkan) {
draw_ = draw;
vulkan_ = vulkan;
std::string errors;
vshader_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, depal_vs, &errors);
assert(vshader_ != VK_NULL_HANDLE);
}
DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
+2
View File
@@ -52,6 +52,8 @@ class DepalShaderCacheVulkan : public DepalShaderCacheCommon {
public:
DepalShaderCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan);
~DepalShaderCacheVulkan();
void DeviceLost();
void DeviceRestore(Draw::DrawContext *draw, VulkanContext *vulkan);
// This also uploads the palette and binds the correct texture.
DepalShaderVulkan *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat);
+10 -9
View File
@@ -93,8 +93,6 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan, Draw::DrawContext *dra
indexGen.Setup(decIndex);
InitDeviceObjects();
tessDataTransfer = new TessellationDataTransferVulkan(vulkan, draw);
}
void DrawEngineVulkan::InitDeviceObjects() {
@@ -206,6 +204,8 @@ void DrawEngineVulkan::InitDeviceObjects() {
assert(VK_SUCCESS == res);
vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE);
tessDataTransfer = new TessellationDataTransferVulkan(vulkan_, draw_);
}
DrawEngineVulkan::~DrawEngineVulkan() {
@@ -214,8 +214,6 @@ DrawEngineVulkan::~DrawEngineVulkan() {
FreeMemoryPages(splineBuffer, SPLINE_BUFFER_SIZE);
DestroyDeviceObjects();
delete tessDataTransfer;
}
void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) {
@@ -241,6 +239,9 @@ void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) {
}
void DrawEngineVulkan::DestroyDeviceObjects() {
delete tessDataTransfer;
tessDataTransfer = nullptr;
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
frame_[i].Destroy(vulkan_);
}
@@ -249,11 +250,9 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
if (nullSampler_ != VK_NULL_HANDLE)
vulkan_->Delete().QueueDeleteSampler(nullSampler_);
if (pipelineLayout_ != VK_NULL_HANDLE)
vkDestroyPipelineLayout(vulkan_->GetDevice(), pipelineLayout_, nullptr);
pipelineLayout_ = VK_NULL_HANDLE;
vulkan_->Delete().QueueDeletePipelineLayout(pipelineLayout_);
if (descriptorSetLayout_ != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(vulkan_->GetDevice(), descriptorSetLayout_, nullptr);
descriptorSetLayout_ = VK_NULL_HANDLE;
vulkan_->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_);
if (nullTexture_) {
nullTexture_->Destroy();
delete nullTexture_;
@@ -262,6 +261,7 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
vertexCache_->Destroy(vulkan_);
delete vertexCache_;
vertexCache_ = nullptr;
vai_.Clear(); // Need to clear this to get rid of all remaining references to the dead buffers.
}
void DrawEngineVulkan::DeviceLost() {
@@ -269,8 +269,9 @@ void DrawEngineVulkan::DeviceLost() {
DirtyAllUBOs();
}
void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan) {
void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) {
vulkan_ = vulkan;
draw_ = draw;
InitDeviceObjects();
}
+1 -1
View File
@@ -137,7 +137,7 @@ public:
}
void DeviceLost();
void DeviceRestore(VulkanContext *vulkan);
void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw);
void SetupVertexDecoder(u32 vertType);
void SetupVertexDecoderInternal(u32 vertType);
+3 -3
View File
@@ -88,8 +88,7 @@ FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, Vulk
convBufSize_(0),
textureCacheVulkan_(nullptr),
shaderManagerVulkan_(nullptr),
pipelinePostShader_(VK_NULL_HANDLE),
depalVulkan_(draw, vulkan) {
pipelinePostShader_(VK_NULL_HANDLE) {
InitDeviceObjects();
@@ -593,8 +592,9 @@ void FramebufferManagerVulkan::DeviceLost() {
DestroyDeviceObjects();
}
void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan) {
void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) {
vulkan_ = vulkan;
draw_ = draw;
vulkan2D_->DeviceRestore(vulkan_);
InitDeviceObjects();
+1 -2
View File
@@ -70,7 +70,7 @@ public:
void Resized() override;
void DeviceLost();
void DeviceRestore(VulkanContext *vulkan);
void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw);
int GetLineWidth();
void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override;
@@ -120,7 +120,6 @@ private:
DrawEngineVulkan *drawEngineVulkan_;
VulkanPushBuffer *push_;
DepalShaderCacheVulkan depalVulkan_;
enum {
MAX_COMMAND_BUFFERS = 32,
};
+11 -4
View File
@@ -781,13 +781,16 @@ void GPU_Vulkan::FastLoadBoneMatrix(u32 target) {
}
void GPU_Vulkan::InitDeviceObjects() {
ILOG("GPU_Vulkan::InitDeviceObjects");
// Initialize framedata
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
assert(!frameData_[i].push_);
frameData_[i].push_ = new VulkanPushBuffer(vulkan_, 64 * 1024);
}
}
void GPU_Vulkan::DestroyDeviceObjects() {
ILOG("GPU_Vulkan::DestroyDeviceObjects");
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
if (frameData_[i].push_) {
frameData_[i].push_->Destroy(vulkan_);
@@ -804,21 +807,25 @@ void GPU_Vulkan::DeviceLost() {
drawEngine_.DeviceLost();
pipelineManager_->DeviceLost();
textureCacheVulkan_->DeviceLost();
depalShaderCache_.Clear();
depalShaderCache_.DeviceLost();
shaderManagerVulkan_->ClearShaders();
}
void GPU_Vulkan::DeviceRestore() {
vulkan_ = (VulkanContext *)PSP_CoreParameter().graphicsContext->GetAPIContext();
draw_ = (Draw::DrawContext *)PSP_CoreParameter().graphicsContext->GetDrawContext();
InitDeviceObjects();
CheckGPUFeatures();
BuildReportingInfo();
UpdateCmdInfo();
framebufferManagerVulkan_->DeviceRestore(vulkan_);
drawEngine_.DeviceRestore(vulkan_);
framebufferManagerVulkan_->DeviceRestore(vulkan_, draw_);
drawEngine_.DeviceRestore(vulkan_, draw_);
pipelineManager_->DeviceRestore(vulkan_);
textureCacheVulkan_->DeviceRestore(vulkan_);
textureCacheVulkan_->DeviceRestore(vulkan_, draw_);
shaderManagerVulkan_->DeviceRestore(vulkan_);
depalShaderCache_.DeviceRestore(draw_, vulkan_);
}
void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) {
-2
View File
@@ -119,8 +119,6 @@ private:
// Manages state and pipeline objects
PipelineManagerVulkan *pipelineManager_;
int lastVsync_;
VkCommandBuffer curCmd_;
int vertexCost_ = 0;
std::string reportingPrimaryInfo_;
+15 -26
View File
@@ -126,36 +126,14 @@ void SamplerCache::DeviceRestore(VulkanContext *vulkan) {
TextureCacheVulkan::TextureCacheVulkan(Draw::DrawContext *draw, VulkanContext *vulkan)
: TextureCacheCommon(draw),
vulkan_(vulkan),
samplerCache_(vulkan),
texelsScaledThisFrame_(0) {
samplerCache_(vulkan) {
timesInvalidatedAllThisFrame_ = 0;
lastBoundTexture = nullptr;
allocator_ = new VulkanDeviceAllocator(vulkan_, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE);
VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samp.magFilter = VK_FILTER_NEAREST;
samp.minFilter = VK_FILTER_NEAREST;
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_);
DeviceRestore(vulkan, draw);
SetupTextureDecoder();
}
TextureCacheVulkan::~TextureCacheVulkan() {
vulkan_->Delete().QueueDeleteSampler(samplerNearest_);
Clear(true);
if (allocator_) {
allocator_->Destroy();
// We have to delete on queue, so this can free its queued deletions.
vulkan_->Delete().QueueCallback([](void *ptr) {
auto allocator = static_cast<VulkanDeviceAllocator *>(ptr);
delete allocator;
}, allocator_);
}
DeviceLost();
}
void TextureCacheVulkan::SetFramebufferManager(FramebufferManagerVulkan *fbManager) {
@@ -183,17 +161,28 @@ void TextureCacheVulkan::DeviceLost() {
}
samplerCache_.DeviceLost();
vulkan_->Delete().QueueDeleteSampler(samplerNearest_);
nextTexture_ = nullptr;
}
void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan) {
void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) {
vulkan_ = vulkan;
draw_ = draw;
assert(!allocator_);
allocator_ = new VulkanDeviceAllocator(vulkan_, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE);
samplerCache_.DeviceRestore(vulkan);
VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samp.magFilter = VK_FILTER_NEAREST;
samp.minFilter = VK_FILTER_NEAREST;
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_);
}
void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
+8 -8
View File
@@ -72,7 +72,7 @@ public:
void EndFrame();
void DeviceLost();
void DeviceRestore(VulkanContext *vulkan);
void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw);
void SetFramebufferManager(FramebufferManagerVulkan *fbManager);
void SetDepalShaderCache(DepalShaderCacheVulkan *dpCache) {
@@ -122,19 +122,19 @@ private:
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override;
void BuildTexture(TexCacheEntry *const entry, bool replaceImages) override;
VulkanContext *vulkan_;
VulkanDeviceAllocator *allocator_;
VulkanPushBuffer *push_;
VulkanContext *vulkan_ = nullptr;
VulkanDeviceAllocator *allocator_ = nullptr;
VulkanPushBuffer *push_ = nullptr;
SamplerCache samplerCache_;
TextureScalerVulkan scaler;
CachedTextureVulkan *lastBoundTexture;
CachedTextureVulkan *lastBoundTexture = nullptr;
int decimationCounter_;
int texelsScaledThisFrame_;
int timesInvalidatedAllThisFrame_;
int decimationCounter_ = 0;
int texelsScaledThisFrame_ = 0;
int timesInvalidatedAllThisFrame_ = 0;
FramebufferManagerVulkan *framebufferManagerVulkan_;
DepalShaderCacheVulkan *depalShaderCache_;
+2 -2
View File
@@ -46,11 +46,11 @@ void Vulkan2D::DestroyDeviceObjects() {
VkDevice device = vulkan_->GetDevice();
if (descriptorSetLayout_ != VK_NULL_HANDLE) {
vkDestroyDescriptorSetLayout(device, descriptorSetLayout_, nullptr);
vulkan_->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_);
descriptorSetLayout_ = VK_NULL_HANDLE;
}
if (pipelineLayout_ != VK_NULL_HANDLE) {
vkDestroyPipelineLayout(device, pipelineLayout_, nullptr);
vulkan_->Delete().QueueDeletePipelineLayout(pipelineLayout_);
pipelineLayout_ = VK_NULL_HANDLE;
}
+4
View File
@@ -1104,12 +1104,16 @@ void EmuScreen::deviceLost() {
ILOG("EmuScreen::deviceLost()");
if (gpu)
gpu->DeviceLost();
else
ILOG("No gpu to deviceLost!");
}
void EmuScreen::deviceRestore() {
ILOG("EmuScreen::deviceRestore()");
if (gpu)
gpu->DeviceRestore();
else
ILOG("No gpu to deviceRestore!");
RecreateViews();
}
+17 -1
View File
@@ -127,6 +127,8 @@ std::unique_ptr<ManagedTexture> uiTexture;
ScreenManager *screenManager;
std::string config_filename;
bool g_graphicsInited;
#ifdef IOS
bool iosCanUseJit;
bool targetIsJailbroken;
@@ -675,10 +677,13 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) {
#endif
g_gameInfoCache = new GameInfoCache();
g_graphicsInited = true;
ILOG("NativeInitGraphics completed");
}
void NativeShutdownGraphics() {
g_graphicsInited = false;
ILOG("NativeShutdownGraphics");
#ifdef _WIN32
@@ -817,6 +822,7 @@ void NativeRender(GraphicsContext *graphicsContext) {
}
if (resized) {
ILOG("resized was set to true - resizing");
resized = false;
if (uiContext) {
@@ -839,6 +845,12 @@ void NativeRender(GraphicsContext *graphicsContext) {
graphicsContext->Resize();
screenManager->resized();
// Do not enable unless you are testing device-loss on Windows
#if 0
screenManager->deviceLost();
screenManager->deviceRestore();
#endif
// TODO: Move this to new GraphicsContext objects for each backend.
#ifndef _WIN32
if (GetGPUBackend() == GPUBackend::OPENGL) {
@@ -1072,7 +1084,11 @@ void NativeMessageReceived(const char *message, const char *value) {
void NativeResized() {
// NativeResized can come from any thread so we just set a flag, then process it later.
resized = true;
if (g_graphicsInited) {
resized = true;
} else {
ILOG("NativeResized ignored, not initialized");
}
}
void NativeSetRestarting() {
+2
View File
@@ -218,6 +218,8 @@ void WindowsVulkanContext::Shutdown() {
g_Vulkan->DestroyObjects();
g_Vulkan->DestroyDevice();
g_Vulkan->DestroyDebugMsgCallback();
g_Vulkan->DestroyInstance();
delete g_Vulkan;
g_Vulkan = nullptr;
+30 -10
View File
@@ -189,6 +189,11 @@ static VulkanContext *g_Vulkan;
class AndroidVulkanContext : public AndroidGraphicsContext {
public:
AndroidVulkanContext() : draw_(nullptr) {}
~AndroidVulkanContext() {
delete g_Vulkan;
g_Vulkan = nullptr;
}
bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override;
void Shutdown() override;
void SwapInterval(int interval) override;
@@ -270,10 +275,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags,
}
bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) {
if (g_Vulkan) {
return false;
}
ILOG("AndroidVulkanContext::Init");
init_glslang();
g_LogOptions.breakOnError = true;
@@ -282,7 +284,10 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
ILOG("Creating vulkan context");
Version gitVer(PPSSPP_GIT_VERSION);
g_Vulkan = new VulkanContext();
if (!g_Vulkan) {
g_Vulkan = new VulkanContext();
}
if (VK_SUCCESS != g_Vulkan->CreateInstance("PPSSPP", gitVer.ToInteger(), VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED)) {
ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
delete g_Vulkan;
@@ -326,6 +331,7 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
bool success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.
assert(success);
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
ILOG("AndroidVulkanContext::Init completed");
return true;
}
@@ -334,22 +340,27 @@ void AndroidVulkanContext::Shutdown() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
delete draw_;
draw_ = nullptr;
ILOG("Calling NativeShutdownGraphics");
NativeShutdownGraphics();
g_Vulkan->WaitUntilQueueIdle();
g_Vulkan->DestroyObjects();
g_Vulkan->DestroyDebugMsgCallback();
g_Vulkan->DestroyDevice();
g_Vulkan->DestroyDebugMsgCallback();
delete g_Vulkan;
g_Vulkan = nullptr;
g_Vulkan->DestroyInstance();
// We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app.
finalize_glslang();
ILOG("AndroidVulkanContext::Shutdown completed");
}
void AndroidVulkanContext::SwapBuffers() {
}
void AndroidVulkanContext::Resize() {
ILOG("AndroidVulkanContext::Resize begin (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects();
@@ -357,6 +368,7 @@ void AndroidVulkanContext::Resize() {
g_Vulkan->ReinitSurfaceAndroid(pixel_xres, pixel_yres);
g_Vulkan->InitObjects();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
ILOG("AndroidVulkanContext::Resize end (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
}
void AndroidVulkanContext::SwapInterval(int interval) {
@@ -729,6 +741,9 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env,
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv *, jclass, jint bufw, jint bufh, jint format) {
ILOG("NativeApp.backbufferResize(%d x %d)", bufw, bufh);
bool new_size = pixel_xres != bufw || pixel_yres != bufh;
int old_w = pixel_xres;
int old_h = pixel_yres;
// pixel_*res is the backbuffer resolution.
pixel_xres = bufw;
pixel_yres = bufh;
@@ -755,7 +770,12 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv
ILOG("dp_xres=%d dp_yres=%d", dp_xres, dp_yres);
ILOG("pixel_xres=%d pixel_yres=%d", pixel_xres, pixel_yres);
NativeResized();
if (new_size) {
ILOG("Size change detected (previously %d,%d) - calling NativeResized()", old_w, old_h);
NativeResized();
} else {
ILOG("Size didn't change.");
}
}
@@ -1124,7 +1144,7 @@ retry:
ProcessFrameCommands(env);
}
ILOG("After render loop.");
ILOG("Leaving EGL/Vulkan render loop.");
g_gameInfoCache->WorkQueue()->Flush();
NativeDeviceLost();
@@ -58,7 +58,7 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C
// Remember to loadLibrary your JNI .so in a static {} block
// Adjust these as necessary
private static String TAG = "NativeActivity";
private static String TAG = "PPSSPPNativeActivity";
// Allows us to skip a lot of initialization on secondary calls to onCreate.
private static boolean initialized = false;
@@ -518,24 +518,29 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C
}
}
Point desiredSize = new Point();
@Override
public void surfaceCreated(SurfaceHolder holder) {
pixelWidth = holder.getSurfaceFrame().width();
pixelHeight = holder.getSurfaceFrame().height();
Log.d(TAG, "Surface created. pixelWidth=" + pixelWidth + ", pixelHeight=" + pixelHeight);
NativeApp.setDisplayParameters(pixelWidth, pixelHeight, (int)densityDpi, refreshRate);
Point sz = new Point();
getDesiredBackbufferSize(sz);
Log.d(TAG, "Setting fixed size " + sz.x + " x " + sz.y);
getDesiredBackbufferSize(desiredSize);
Log.d(TAG, "Setting fixed size " + desiredSize.x + " x " + desiredSize.y);
if (mGLSurfaceView != null) {
mGLSurfaceView.getHolder().setFixedSize(sz.x, sz.y);
mGLSurfaceView.getHolder().setFixedSize(desiredSize.x, desiredSize.y);
} else {
mSurfaceView.getHolder().setFixedSize(sz.x, sz.y);
mSurfaceView.getHolder().setFixedSize(desiredSize.x, desiredSize.y);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (width != desiredSize.x || height != desiredSize.y) {
Log.w(TAG, "Surface changed but not to desired size. Ignoring.");
return;
}
Log.w(TAG, "Surface changed. Resolution: " + width + "x" + height + " Format: " + format);
NativeApp.backbufferResize(width, height, format);
mSurface = holder.getSurface();
@@ -647,10 +652,10 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C
loseAudioFocus(this.audioManager, this.audioFocusChangeListener);
NativeApp.pause();
if (!javaGL) {
Log.i(TAG, "Pausing surface view");
mSurfaceView.onPause();
Log.i(TAG, "Joining render thread");
Log.i(TAG, "Joining render thread...");
joinRenderLoopThread();
Log.i(TAG, "Joined render thread");
} else {
if (mGLSurfaceView != null) {
mGLSurfaceView.onPause();
+1 -1
View File
@@ -53,7 +53,7 @@ void OutputDebugStringUTF8(const char *p);
// Must only be used for logging
#ifndef APP_NAME
#define APP_NAME "NativeApp"
#define APP_NAME "PPSSPP"
#endif
#ifdef _DEBUG
+4 -2
View File
@@ -29,7 +29,8 @@ TextDrawerAndroid::TextDrawerAndroid(Draw::DrawContext *draw) : TextDrawer(draw)
} else {
ELOG("Failed to find class: '%s'", textRendererClassName);
}
dpiScale_ = 1.0f;
dpiScale_ = CalculateDPIScale();
ILOG("Initializing TextDrawerAndroid with DPI scale %f", dpiScale_);
}
TextDrawerAndroid::~TextDrawerAndroid() {
@@ -269,7 +270,8 @@ void TextDrawerAndroid::OncePerFrame() {
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
ILOG("Scale changed - wiping cache");
// TODO: Don't bother if it's a no-op (cache already empty)
ILOG("DPI Scale changed (%f to %f) - wiping font cache (%d items, %d fonts)", dpiScale_, newDpiScale, (int)cache_.size(), (int)fontMap_.size());
dpiScale_ = newDpiScale;
ClearCache();
fontMap_.clear(); // size is precomputed using dpiScale_.
+13 -6
View File
@@ -2,13 +2,14 @@
#include "VulkanQueueRunner.h"
#include "VulkanRenderManager.h"
// Debug help: adb logcat -s DEBUG NativeActivity NativeApp PPSSPP
// Debug help: adb logcat -s DEBUG PPSSPPNativeActivity PPSSPP
// TODO: This is only enough for 4x render resolution / 4x texture upscale for debugger.
// Maybe we should use a dynamically allocated one for larger?
const uint32_t readbackBufferSize = 2048 * 2048 * 4;
void VulkanQueueRunner::CreateDeviceObjects() {
ILOG("VulkanQueueRunner::CreateDeviceObjects");
InitBackbufferRenderPass();
InitRenderpasses();
@@ -36,16 +37,22 @@ void VulkanQueueRunner::CreateDeviceObjects() {
}
void VulkanQueueRunner::DestroyDeviceObjects() {
ILOG("VulkanQueueRunner::DestroyDeviceObjects");
VkDevice device = vulkan_->GetDevice();
vulkan_->Delete().QueueDeleteDeviceMemory(readbackMemory_);
vkFreeMemory(device, readbackMemory_, nullptr);
readbackMemory_ = VK_NULL_HANDLE;
vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_);
readbackBuffer_ = VK_NULL_HANDLE;
for (int i = 0; i < ARRAY_SIZE(renderPasses_); i++) {
assert(renderPasses_[i] != VK_NULL_HANDLE);
vkDestroyRenderPass(device, renderPasses_[i], nullptr);
vulkan_->Delete().QueueDeleteRenderPass(renderPasses_[i]);
renderPasses_[i] = VK_NULL_HANDLE;
}
assert(backbufferRenderPass_ != VK_NULL_HANDLE);
vkDestroyRenderPass(device, backbufferRenderPass_, nullptr);
vulkan_->Delete().QueueDeleteRenderPass(backbufferRenderPass_);
backbufferRenderPass_ = VK_NULL_HANDLE;
}
void VulkanQueueRunner::InitBackbufferRenderPass() {
@@ -419,8 +426,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
VkClearRect rc{};
rc.baseArrayLayer = 0;
rc.layerCount = 1;
rc.rect.extent.width = curWidth;
rc.rect.extent.height = curHeight;
rc.rect.extent.width = (uint32_t)curWidth;
rc.rect.extent.height = (uint32_t)curHeight;
VkClearAttachment attachments[2];
if (c.clear.clearMask & VK_IMAGE_ASPECT_COLOR_BIT) {
VkClearAttachment &attachment = attachments[numAttachments++];
@@ -436,7 +443,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
attachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
}
if (c.clear.clearMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
attachment.clearValue.depthStencil.stencil = c.clear.clearStencil;
attachment.clearValue.depthStencil.stencil = (uint32_t)c.clear.clearStencil;
attachment.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
}
+30 -8
View File
@@ -194,12 +194,12 @@ void VulkanRenderManager::CreateBackbuffers() {
run_ = true;
// Won't necessarily be 0.
threadInitFrame_ = vulkan_->GetCurFrame();
VLOG("starting thread");
ILOG("Starting Vulkan submission thread (threadInitFrame_ = %d)", vulkan_->GetCurFrame());
thread_ = std::thread(&VulkanRenderManager::ThreadFunc, this);
}
}
void VulkanRenderManager::StopThread(bool shutdown) {
void VulkanRenderManager::StopThread() {
if (useThread && run_) {
run_ = false;
// Stop the thread.
@@ -215,12 +215,21 @@ void VulkanRenderManager::StopThread(bool shutdown) {
}
}
thread_.join();
VLOG("thread joined.");
ILOG("Vulkan submission thread joined. Frame=%d", vulkan_->GetCurFrame());
// Eat whatever has been queued up for this frame if anything.
Wipe();
// Wait for any fences to finish and be resignaled, so we don't have sync issues.
// Also clean out any queued data, which might refer to things that might not be valid
// when we restart...
for (int i = 0; i < vulkan_->GetInflightFrames(); i++) {
auto &frameData = frameData_[i];
if (frameData.readyForRun || frameData.hasInitCommands || frameData.steps.size() != 0) {
Crash();
}
frameData.readyForRun = false;
frameData.steps.clear();
std::unique_lock<std::mutex> lock(frameData.push_mutex);
while (!frameData.readyForFence) {
@@ -228,11 +237,13 @@ void VulkanRenderManager::StopThread(bool shutdown) {
frameData.push_condVar.wait(lock);
}
}
} else {
ILOG("Vulkan submission thread was already stopped.");
}
}
void VulkanRenderManager::DestroyBackbuffers() {
StopThread(false);
StopThread();
vulkan_->WaitUntilQueueIdle();
VkDevice device = vulkan_->GetDevice();
@@ -253,7 +264,8 @@ void VulkanRenderManager::DestroyBackbuffers() {
}
VulkanRenderManager::~VulkanRenderManager() {
StopThread(true);
ILOG("VulkanRenderManager destructor");
StopThread();
vulkan_->WaitUntilQueueIdle();
VkDevice device = vulkan_->GetDevice();
@@ -274,6 +286,7 @@ void VulkanRenderManager::ThreadFunc() {
setCurrentThreadName("RenderMan");
int threadFrame = threadInitFrame_;
bool nextFrame = false;
bool firstFrame = true;
while (true) {
{
if (nextFrame) {
@@ -301,9 +314,17 @@ void VulkanRenderManager::ThreadFunc() {
assert(frameData.type == VKRRunType::END || frameData.type == VKRRunType::SYNC);
}
VLOG("PULL: Running frame %d", threadFrame);
if (firstFrame) {
ILOG("Running first frame (%d)", threadFrame);
firstFrame = false;
}
Run(threadFrame);
VLOG("PULL: Finished frame %d", threadFrame);
}
// Wait for the device to be done with everything, before tearing stuff down.
vkDeviceWaitIdle(vulkan_->GetDevice());
VLOG("PULL: Quitting");
}
@@ -330,6 +351,9 @@ void VulkanRenderManager::BeginFrame() {
// Must be after the fence - this performs deletes.
VLOG("PUSH: BeginFrame %d", curFrame);
if (!run_) {
WLOG("BeginFrame while !run_!");
}
vulkan_->BeginFrame();
insideFrame_ = true;
@@ -368,9 +392,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR
curRenderStep_ = nullptr;
}
if (curRenderStep_ && curRenderStep_->commands.size() == 0) {
#ifdef _DEBUG
ILOG("Empty render step. Usually happens after uploading pixels..");
#endif
VLOG("Empty render step. Usually happens after uploading pixels..");
}
VKRStep *step = new VKRStep{ VKRStepType::RENDER };
+1 -1
View File
@@ -222,7 +222,7 @@ private:
void FlushSync();
void EndSyncFrame(int frame);
void StopThread(bool shutdown);
void StopThread();
// Permanent objects
VkSemaphore acquireSemaphore_;
+4 -4
View File
@@ -193,7 +193,7 @@ public:
const std::string &GetSource() const { return source_; }
~VKShaderModule() {
if (module_) {
vkDestroyShaderModule(device_, module_, nullptr);
vulkan_->Delete().QueueDeleteShaderModule(module_);
}
}
VkShaderModule Get() const { return module_; }
@@ -202,7 +202,7 @@ public:
}
private:
VkDevice device_;
VulkanContext *vulkan_;
VkShaderModule module_;
VkShaderStageFlagBits vkstage_;
bool ok_;
@@ -211,9 +211,9 @@ private:
};
bool VKShaderModule::Compile(VulkanContext *vulkan, ShaderLanguage language, const uint8_t *data, size_t size) {
vulkan_ = vulkan;
// We'll need this to free it later.
device_ = vulkan->GetDevice();
this->source_ = (const char *)data;
source_ = (const char *)data;
std::vector<uint32_t> spirv;
if (!GLSLtoSPV(vkstage_, source_.c_str(), spirv)) {
return false;
+3 -1
View File
@@ -31,7 +31,9 @@ void PrioritizedWorkQueue::Flush() {
flush_count++;
}
queue_.clear();
ILOG("Flushed %d un-executed tasks", flush_count);
if (flush_count > 0) {
ILOG("PrioritizedWorkQueue: Flushed %d un-executed tasks", flush_count);
}
}
bool PrioritizedWorkQueue::WaitUntilDone(bool all) {