Skip to content

Commit

Permalink
Fix a number of bugs and stuff affecting Vulkan on Mali
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed May 30, 2017
1 parent bd9f3af commit c173da4
Show file tree
Hide file tree
Showing 18 changed files with 91 additions and 63 deletions.
38 changes: 17 additions & 21 deletions Common/Vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ VulkanContext::VulkanContext(const char *app_name, int app_ver, uint32_t flags)
instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
#endif
device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
// device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME);

if (flags & VULKAN_FLAG_VALIDATE) {
for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) {
Expand Down Expand Up @@ -217,11 +218,9 @@ void VulkanContext::QueueBeforeSurfaceRender(VkCommandBuffer cmd) {

VkCommandBuffer VulkanContext::BeginFrame() {
FrameData *frame = &frame_[curFrame_];

// Get the index of the next available swapchain image, and a semaphore to block command buffer execution on.
// Now, I wonder if we should do this early in the frame or late? Right now we do it early, which should be fine.
VkResult res = vkAcquireNextImageKHR(device_, swap_chain_, UINT64_MAX, acquireSemaphore, VK_NULL_HANDLE, &current_buffer);

// TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
// return codes
assert(res == VK_SUCCESS);
Expand Down Expand Up @@ -252,16 +251,13 @@ VkCommandBuffer VulkanContext::BeginSurfaceRenderPass(VkClearValue clear_values[
rp_begin.renderArea.extent.height = height_;
rp_begin.clearValueCount = 2;
rp_begin.pClearValues = clear_values;

// We don't really need to record this at this point in time, but hey, at some point we'll start this
// pass anyway so might as well do it now (although you can imagine getting away with just a stretchblt and not
// even starting a final render pass if there's nothing to overlay... hm. Uncommon though on mobile).
vkCmdBeginRenderPass(frame->cmdBuf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
return frame->cmdBuf;
}

void VulkanContext::EndSurfaceRenderPass() {
FrameData *frame = &frame_[curFrame_];
ILOG("VulkanContext::EndSurfaceRenderPass");
vkCmdEndRenderPass(frame->cmdBuf);
}

Expand Down Expand Up @@ -292,21 +288,21 @@ void VulkanContext::EndFrame() {
VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &acquireSemaphore;
VkPipelineStageFlags waitStage[1] = { VK_PIPELINE_STAGE_TOP_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();
submit_info.signalSemaphoreCount = 0;
submit_info.pSignalSemaphores = NULL;
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &renderingCompleteSemaphore;
res = vkQueueSubmit(gfx_queue_, 1, &submit_info, frame->fence);
assert(res == VK_SUCCESS);

VkPresentInfoKHR present = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
present.swapchainCount = 1;
present.pSwapchains = &swap_chain_;
present.pImageIndices = &current_buffer;
present.pWaitSemaphores = NULL;
present.waitSemaphoreCount = 0;
present.pWaitSemaphores = &renderingCompleteSemaphore;
present.waitSemaphoreCount = 1;
present.pResults = NULL;

res = vkQueuePresentKHR(gfx_queue_, &present);
Expand Down Expand Up @@ -949,13 +945,11 @@ void VulkanContext::InitQueue() {
vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_);
ILOG("gfx_queue_: %p", gfx_queue_);

VkSemaphoreCreateInfo acquireSemaphoreCreateInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
acquireSemaphoreCreateInfo.flags = 0;

res = vkCreateSemaphore(device_,
&acquireSemaphoreCreateInfo,
NULL,
&acquireSemaphore);
VkSemaphoreCreateInfo semaphoreCreateInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
semaphoreCreateInfo.flags = 0;
res = vkCreateSemaphore(device_, &semaphoreCreateInfo, NULL, &acquireSemaphore);
assert(res == VK_SUCCESS);
res = vkCreateSemaphore(device_, &semaphoreCreateInfo, NULL, &renderingCompleteSemaphore);
assert(res == VK_SUCCESS);
}

Expand Down Expand Up @@ -1070,7 +1064,9 @@ bool VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
&swapchainImageCount, NULL);
assert(res == VK_SUCCESS);

VkImage* swapchainImages = (VkImage*)malloc(swapchainImageCount * sizeof(VkImage));
ILOG("Vulkan swapchain image count: %d", swapchainImageCount);

VkImage* swapchainImages = new VkImage[swapchainImageCount];
assert(swapchainImages);
res = vkGetSwapchainImagesKHR(device_, swap_chain_, &swapchainImageCount, swapchainImages);
assert(res == VK_SUCCESS);
Expand Down Expand Up @@ -1108,8 +1104,7 @@ bool VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
swapChainBuffers.push_back(sc_buffer);
assert(res == VK_SUCCESS);
}
free(swapchainImages);

delete[] swapchainImages;
current_buffer = 0;

return true;
Expand Down Expand Up @@ -1249,6 +1244,7 @@ void VulkanContext::DestroySwapChain() {
swap_chain_ = VK_NULL_HANDLE;
swapChainBuffers.clear();
vkDestroySemaphore(device_, acquireSemaphore, NULL);
vkDestroySemaphore(device_, renderingCompleteSemaphore, NULL);
}

void VulkanContext::DestroyFramebuffers() {
Expand Down
1 change: 1 addition & 0 deletions Common/Vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ class VulkanContext {

private:
VkSemaphore acquireSemaphore;
VkSemaphore renderingCompleteSemaphore;

#ifdef _WIN32
HINSTANCE connection; // hInstance - Windows Instance
Expand Down
1 change: 1 addition & 0 deletions Common/Vulkan/VulkanMemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class VulkanPushBuffer {
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_;
Expand Down
2 changes: 2 additions & 0 deletions GPU/GLES/DrawEngineGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ void DrawEngineGLES::DoFlush() {
PROFILE_THIS_SCOPE("flush");
CHECK_GL_ERROR_IF_DEBUG();



gpuStats.numFlushes++;
gpuStats.numTrackedVertexArrays = (int)vai_.size();

Expand Down
2 changes: 1 addition & 1 deletion GPU/GLES/FramebufferManagerGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
#ifdef USING_GLES2
// GLES3 doesn't support using GL_READ_FRAMEBUFFER here.
draw_->BindFramebufferAsRenderTarget(vfb->fbo);
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
const GLenum target = GL_FRAMEBUFFER;
#else
const GLenum target = GL_READ_FRAMEBUFFER;
Expand Down
2 changes: 1 addition & 1 deletion GPU/GLES/GPU_GLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) {
return;
}

// This also makes skipping drawing very effective.
// This also makes skipping drawing very effective. This function can change the framebffer.
framebufferManagerGL_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
drawEngine_.SetupVertexDecoder(gstate.vertType);
Expand Down
2 changes: 1 addition & 1 deletion GPU/Software/SoftGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
u1 = 1.0f;
}
if (!hasImage) {
draw_->Clear(Draw::FB_COLOR_BIT, 0, 0, 0);
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE });
return;
}

Expand Down
5 changes: 4 additions & 1 deletion GPU/Vulkan/DrawEngineVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,10 @@ void DrawEngineVulkan::DirtyAllUBOs() {
// The inline wrapper in the header checks for numDrawCalls == 0d
void DrawEngineVulkan::DoFlush() {
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::RENDERPASS_COMMANDBUFFER);
VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::CURRENT_RENDERPASS);
if (!rp)
Crash();

gpuStats.numFlushes++;

FrameData *frame = &frame_[curFrame_ & 1];
Expand Down Expand Up @@ -847,7 +851,6 @@ void DrawEngineVulkan::DoFlush() {
Uint8x4ToFloat4(bc, dynState.blendColor);
vkCmdSetBlendConstants(cmd, bc);
}

dirtyUniforms_ |= shaderManager_->UpdateUniforms();

shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
Expand Down
5 changes: 5 additions & 0 deletions GPU/Vulkan/FramebufferVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,9 @@ VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, V
}
// Currently rendering to this framebuffer. Need to make a copy.
if (!skipCopy && framebuffer == currentRenderVfb_) {
// ignore this case for now, doesn't work
ILOG("Texturing from current render Vfb!");
return VK_NULL_HANDLE;
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
Draw::Framebuffer *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, (Draw::FBColorDepth)framebuffer->colorDepth);
if (renderCopy) {
Expand Down Expand Up @@ -1036,6 +1039,8 @@ void FramebufferManagerVulkan::FlushBeforeCopy() {
// all the irrelevant state checking it'll use to decide what to do. Should
// do something more focused here.
SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
if (!draw_->GetNativeObject(Draw::NativeObject::CURRENT_RENDERPASS))
Crash();
drawEngine_->Flush();
}

Expand Down
2 changes: 2 additions & 0 deletions GPU/Vulkan/GPU_Vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {

// This also makes skipping drawing very effective.
framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
if (!draw_->GetNativeObject(Draw::NativeObject::CURRENT_RENDERPASS))
Crash();

if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
drawEngine_.SetupVertexDecoder(gstate.vertType);
Expand Down
3 changes: 3 additions & 0 deletions GPU/Vulkan/PipelineManagerVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip

VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, VkRenderPass renderPass, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform) {
VulkanPipelineKey key;
if (!renderPass)
Crash();

key.raster = rasterKey;
key.renderPass = renderPass;
key.useHWTransform = useHwTransform;
Expand Down
2 changes: 1 addition & 1 deletion GPU/Vulkan/ShaderManagerVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

#ifdef _WIN32
#define SHADERLOG
//#define SHADERLOG
#endif

#include <map>
Expand Down
1 change: 1 addition & 0 deletions GPU/Vulkan/TextureCacheVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry, bool replaceIm
entry->vkTex = nullptr;
}
} else {
entry->vkTex->texture_->TransitionForUpload();
// TODO: If reusing an existing texture object, we must transition it into the correct layout.
}
lastBoundTexture = entry->vkTex;
Expand Down
2 changes: 1 addition & 1 deletion UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ void EmuScreen::preRender() {
// We do, however, start the frame in other ways.

bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
if (!useBufferedRendering) {
if (!useBufferedRendering && !g_Config.bSoftwareRendering) {
// We need to clear here already so that drawing during the frame is done on a clean slate.
DrawContext *draw = screenManager()->getDrawContext();
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 });
Expand Down
2 changes: 1 addition & 1 deletion UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ void GameSettingsScreen::CreateViews() {
renderingBackendChoice->HideChoice(2); // D3D11
}
#endif
#if !defined(_WIN32)
#if !defined(_WIN32) && !PPSSPP_PLATFORM(ANDROID)
// TODO: Add dynamic runtime check for Vulkan support on Android
renderingBackendChoice->HideChoice(3);
#endif
Expand Down
2 changes: 1 addition & 1 deletion UI/MiscScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ void LogoScreen::render() {
dc.DrawTextShadow(boot_filename.c_str(), bounds.centerX(), bounds.centerY() + 180, textColor, ALIGN_CENTER);
}

#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
#if (defined(_WIN32) && !PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(ANDROID)
// Draw the graphics API, except on UWP where it's always D3D11
dc.DrawText(screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME).c_str(), bounds.centerX(), bounds.y2() - 100, textColor, ALIGN_CENTER);
#endif
Expand Down
2 changes: 1 addition & 1 deletion ext/native/thin3d/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,7 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render
glstate.colorMask.force(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
if (rp.depth == RPAction::CLEAR) {
glClearDepth(rp.clearDepth);
glClearDepthf(rp.clearDepth);
glClearStencil(rp.clearStencil);
clearFlags |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
glstate.depthWrite.force(GL_TRUE);
Expand Down
Loading

0 comments on commit c173da4

Please sign in to comment.