Permalink
Browse files

Merge pull request #10201 from hrydgard/1.5-crash-fixes

1.5 crash fixes
  • Loading branch information...
hrydgard committed Nov 29, 2017
2 parents e9303fd + 04913be commit 4766a9678aff6d422359433d340da4fb9323e2e8
@@ -134,6 +134,27 @@ size_t VulkanPushBuffer::GetTotalSize() const {
return sum;
}
void VulkanPushBuffer::Map() {
assert(!writePtr_);
VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
assert(writePtr_);
assert(VK_SUCCESS == res);
}
void VulkanPushBuffer::Unmap() {
assert(writePtr_);
/*
// Should not need this since we use coherent memory.
VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
range.offset = 0;
range.size = offset_;
range.memory = buffers_[buf_].deviceMemory;
vkFlushMappedMemoryRanges(device_, 1, &range);
*/
vkUnmapMemory(device_, buffers_[buf_].deviceMemory);
writePtr_ = nullptr;
}
VulkanDeviceAllocator::VulkanDeviceAllocator(VulkanContext *vulkan, size_t minSlabSize, size_t maxSlabSize)
: vulkan_(vulkan), lastSlab_(0), minSlabSize_(minSlabSize), maxSlabSize_(maxSlabSize), memoryTypeIndex_(UNDEFINED_MEMORY_TYPE), destroyed_(false) {
assert((minSlabSize_ & (SLAB_GRAIN_SIZE - 1)) == 0);
@@ -46,26 +46,9 @@ class VulkanPushBuffer {
Unmap();
}
void Map() {
assert(!writePtr_);
VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_));
assert(writePtr_);
assert(VK_SUCCESS == res);
}
void Map();
void Unmap() {
assert(writePtr_);
/*
// Should not need this since we use coherent memory.
VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
range.offset = 0;
range.size = offset_;
range.memory = buffers_[buf_].deviceMemory;
vkFlushMappedMemoryRanges(device_, 1, &range);
*/
vkUnmapMemory(device_, buffers_[buf_].deviceMemory);
writePtr_ = nullptr;
}
void Unmap();
// When using the returned memory, make sure to bind the returned vkbuf.
// This will later allow for handling overflow correctly.
@@ -635,7 +635,7 @@ size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) {
// TODO: Double? Does it ever happen?
default:
_assert_msg_(HLE, false, "Invalid argmask character: %c", argmask[i]);
_dbg_assert_msg_(HLE, false, "Invalid argmask character: %c", argmask[i]);
APPEND_FMT(" -- invalid arg format: %c -- %08x", argmask[i], regval);
break;
}
@@ -673,7 +673,7 @@ void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res,
// TODO: For now, floats are just shown as bits.
fmt = "%s%08x=%s(%s)%s";
} else {
_assert_msg_(HLE, false, "Invalid return format: %c", retmask);
_dbg_assert_msg_(HLE, false, "Invalid return format: %c", retmask);
fmt = "%s%08llx=%s(%s)%s";
}
@@ -136,6 +136,8 @@ FramebufferManagerCommon::~FramebufferManagerCommon() {
DestroyFramebuf(vfb);
}
bvfbs_.clear();
SetNumExtraFBOs(0);
}
void FramebufferManagerCommon::Init() {
@@ -198,7 +200,7 @@ bool FramebufferManagerCommon::ShouldDownloadFramebuffer(const VirtualFramebuffe
void FramebufferManagerCommon::SetNumExtraFBOs(int num) {
for (size_t i = 0; i < extraFBOs_.size(); i++) {
extraFBOs_[i]->Release();
extraFBOs_[i]->ReleaseAssertLast();
}
extraFBOs_.clear();
for (int i = 0; i < num; i++) {
@@ -207,7 +209,8 @@ void FramebufferManagerCommon::SetNumExtraFBOs(int num) {
extraFBOs_.push_back(fbo);
}
currentRenderVfb_ = 0;
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
if (num != 0)
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
}
// Heuristics to figure out the size of FBO to create.
@@ -250,7 +250,6 @@ FramebufferManagerGLES::~FramebufferManagerGLES() {
if (stencilUploadProgram_) {
glsl_destroy(stencilUploadProgram_);
}
SetNumExtraFBOs(0);
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
it->second.fbo->Release();
@@ -247,9 +247,11 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
delete nullTexture_;
nullTexture_ = nullptr;
}
vertexCache_->Destroy(vulkan_);
delete vertexCache_;
vertexCache_ = nullptr;
if (vertexCache_) {
vertexCache_->Destroy(vulkan_);
delete vertexCache_;
vertexCache_ = nullptr;
}
// Need to clear this to get rid of all remaining references to the dead buffers.
vai_.Iterate([](uint32_t hash, VertexArrayInfoVulkan *vai) {
delete vai;
@@ -301,8 +301,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &rasterKey, const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform) {
VulkanPipelineKey key{};
if (!renderPass)
Crash();
_assert_msg_(G3D, renderPass, "Can't create a pipeline with a null renderpass");
key.raster = rasterKey;
key.renderPass = renderPass;
@@ -613,12 +613,14 @@ static void UIThemeInit() {
void RenderOverlays(UIContext *dc, void *userdata);
void NativeInitGraphics(GraphicsContext *graphicsContext) {
bool NativeInitGraphics(GraphicsContext *graphicsContext) {
ILOG("NativeInitGraphics");
_assert_msg_(G3D, graphicsContext, "No graphics context!");
using namespace Draw;
Core_SetGraphicsContext(graphicsContext);
g_draw = graphicsContext->GetDrawContext();
_assert_msg_(G3D, g_draw, "No draw context available!");
ui_draw2d.SetAtlas(&ui_atlas);
ui_draw2d_front.SetAtlas(&ui_atlas);
@@ -694,6 +696,7 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) {
g_graphicsInited = true;
ILOG("NativeInitGraphics completed");
return true;
}
void NativeShutdownGraphics() {
@@ -742,6 +742,8 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env,
if (javaGL && !graphicsContext) {
graphicsContext = new AndroidJavaEGLGraphicsContext();
} else if (!graphicsContext) {
_assert_msg_(G3D, false, "No graphics context in displayInit?");
}
if (renderer_inited) {
@@ -750,7 +752,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env,
NativeShutdownGraphics();
NativeDeviceRestore();
NativeInitGraphics(graphicsContext);
ILOG("Restored.");
} else {
ILOG("NativeApp.displayInit() first time");
@@ -1139,6 +1140,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
}
delete graphicsContext;
graphicsContext = nullptr;
return false;
}
@@ -49,7 +49,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
// Runs after NativeInit() at some point. May (and probably should) call OpenGL.
// Should not initialize anything screen-size-dependent - do that in NativeResized.
void NativeInitGraphics(GraphicsContext *graphicsContext);
bool NativeInitGraphics(GraphicsContext *graphicsContext);
// Signals that you need to forget all buffered OpenGL resources,
// like textures, vbo etc.
@@ -517,8 +517,8 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
// Now, if the image needs transitioning, let's transition.
// The backbuffer does not, that's handled by VulkanContext.
if (step.render.framebuffer->color.layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
VkAccessFlags srcAccessMask;
VkPipelineStageFlags srcStage;
VkAccessFlags srcAccessMask = 0;
VkPipelineStageFlags srcStage = 0;
switch (fb->color.layout) {
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
@@ -533,7 +533,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected color layout %d", (int)fb->color.layout);
break;
}
@@ -545,8 +545,8 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
if (fb->depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
VkAccessFlags srcAccessMask;
VkPipelineStageFlags srcStage;
VkAccessFlags srcAccessMask = 0;
VkPipelineStageFlags srcStage = 0;
switch (fb->depth.layout) {
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
@@ -562,7 +562,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected depth layout %d", (int)fb->color.layout);
break;
}
@@ -791,7 +791,8 @@ void VulkanQueueRunner::SetupTransitionToTransferSrc(VKRImage &img, VkImageMemor
stage |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "Transition from this layout to transfer src not supported (%d)", (int)img.layout);
break;
}
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
@@ -826,7 +827,8 @@ void VulkanQueueRunner::SetupTransitionToTransferDst(VKRImage &img, VkImageMemor
stage |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
break;
default:
Crash();
_dbg_assert_msg_(G3D, false, "Transition from this layout to transfer dst not supported (%d)", (int)img.layout);
break;
}
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
@@ -869,7 +871,8 @@ void VulkanQueueRunner::PerformReadback(const VKRStep &step, VkCommandBuffer cmd
srcImage = &step.readback.src->depth;
}
else {
assert(false);
_dbg_assert_msg_(G3D, false, "No image aspect to readback?");
return;
}
VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
@@ -4,6 +4,7 @@
#include "base/logging.h"
#include "thin3d/thin3d.h"
#include "Common/Log.h"
#include "Common/ColorConv.h"
namespace Draw {
@@ -75,11 +76,26 @@ bool RefCountedObject::Release() {
}
}
else {
_dbg_assert_msg_(G3D, false, "Refcount (%d) invalid for object %p - corrupt?", refcount_, this);
}
return false;
}
bool RefCountedObject::ReleaseAssertLast() {
_dbg_assert_msg_(G3D, refcount_ == 1, "RefCountedObject: Expected to be the last reference, but isn't!");
if (refcount_ > 0 && refcount_ < 10000) {
refcount_--;
if (refcount_ == 0) {
delete this;
return true;
}
} else {
ELOG("Refcount (%d) invalid for object %p - corrupt?", refcount_, this);
}
return false;
}
// ================================== PIXEL/FRAGMENT SHADERS
// The Vulkan ones can be re-used with modern GL later if desired, as they're just GLSL.
@@ -346,6 +346,7 @@ class RefCountedObject {
void AddRef() { refcount_++; }
bool Release();
bool ReleaseAssertLast();
private:
int refcount_;
@@ -1298,7 +1298,6 @@ uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const {
// use this frame's init command buffer.
class VKFramebuffer : public Framebuffer {
public:
// Inherits ownership so no AddRef.
VKFramebuffer(VKRFramebuffer *fb) : buf_(fb) {}
~VKFramebuffer() {
buf_->vulkan_->Delete().QueueCallback([](void *fb) {

0 comments on commit 4766a96

Please sign in to comment.