mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-31 10:32:30 +00:00
More clearing fixes. Also fix some memory leaks.
This commit is contained in:
parent
2e998891a4
commit
3284899844
@ -43,6 +43,7 @@
|
||||
#include "GPU/Vulkan/TextureCacheVulkan.h"
|
||||
#include "GPU/Vulkan/ShaderManagerVulkan.h"
|
||||
#include "GPU/Vulkan/PipelineManagerVulkan.h"
|
||||
#include "GPU/Vulkan/FramebufferVulkan.h"
|
||||
#include "GPU/Vulkan/GPU_Vulkan.h"
|
||||
|
||||
enum {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,8 +17,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU/Vulkan/VulkanUtil.h"
|
||||
#include "GPU/Common/FramebufferCommon.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
#include "GPU/Vulkan/VulkanUtil.h"
|
||||
|
||||
// TODO: WTF?
|
||||
@ -32,83 +34,164 @@ enum VulkanFBOColorDepth {
|
||||
class TextureCacheVulkan;
|
||||
class DrawEngineVulkan;
|
||||
class VulkanContext;
|
||||
class ShaderManagerVulkan;
|
||||
class VulkanTexture;
|
||||
class VulkanFramebuffer;
|
||||
|
||||
struct PostShaderUniforms {
|
||||
float texelDelta[2]; float pad[2];
|
||||
float pixelDelta[2]; float pad0[2];
|
||||
float time[4];
|
||||
};
|
||||
// Simple struct for asynchronous PBO readbacks
|
||||
// TODO: Probably will need a complete redesign.
|
||||
struct AsyncPBOVulkan {
|
||||
// handle;
|
||||
u32 maxSize;
|
||||
|
||||
u32 fb_address;
|
||||
u32 stride;
|
||||
u32 height;
|
||||
u32 size;
|
||||
GEBufferFormat format;
|
||||
bool reading;
|
||||
};
|
||||
|
||||
struct CardboardSettings {
|
||||
bool enabled;
|
||||
float leftEyeXPosition;
|
||||
float rightEyeXPosition;
|
||||
float screenYPosition;
|
||||
float screenWidth;
|
||||
float screenHeight;
|
||||
};
|
||||
|
||||
class FramebufferManagerVulkan : public FramebufferManagerCommon {
|
||||
public:
|
||||
FramebufferManagerVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {}
|
||||
// Subsequent commands will be enqueued on this buffer.
|
||||
void SetCmdBuffer(VkCommandBuffer cmd) { cmd_ = cmd; }
|
||||
FramebufferManagerVulkan(VulkanContext *vulkan);
|
||||
~FramebufferManagerVulkan();
|
||||
|
||||
virtual void ClearBuffer(bool keepState = false) override {
|
||||
throw std::logic_error("The method or operation is not implemented.");
|
||||
void SetTextureCache(TextureCacheVulkan *tc) {
|
||||
textureCache_ = tc;
|
||||
}
|
||||
void SetTextureCache(TextureCacheVulkan *texCache) { texCache_ = texCache; }
|
||||
void SetDrawEngine(DrawEngineVulkan *drawEngine) { drawEngine_ = drawEngine; }
|
||||
VulkanFramebuffer *GetTempFBO(int width, int height, VulkanFBOColorDepth colorDepth);
|
||||
|
||||
void RebindFramebuffer() override { } // This makes little sense with Vulkan's model.
|
||||
|
||||
bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override {
|
||||
return false;
|
||||
void SetShaderManager(ShaderManagerVulkan *sm) {
|
||||
shaderManager_ = sm;
|
||||
}
|
||||
void SetDrawEngine(DrawEngineVulkan *td) {
|
||||
transformDraw_ = td;
|
||||
}
|
||||
|
||||
void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override;
|
||||
void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override;
|
||||
void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override;
|
||||
|
||||
// If texture != 0, will bind it.
|
||||
// x,y,w,h are relative to destW, destH which fill out the target completely.
|
||||
void DrawActiveTexture(VulkanTexture *texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, VkPipeline pipeline, int uvRotation);
|
||||
|
||||
void DestroyAllFBOs();
|
||||
|
||||
virtual void Init() override;
|
||||
void EndFrame();
|
||||
void Resized();
|
||||
void DeviceLost();
|
||||
void CopyDisplayToOutput();
|
||||
int GetLineWidth();
|
||||
void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old);
|
||||
|
||||
void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst);
|
||||
|
||||
// For use when texturing from a framebuffer. May create a duplicate if target.
|
||||
void BindFramebufferColor(int stage, u32 fbRawAddress, VirtualFramebuffer *framebuffer, int flags);
|
||||
|
||||
// Reads a rectangular subregion of a framebuffer to the right position in its backing memory.
|
||||
void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) override;
|
||||
void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) override;
|
||||
|
||||
|
||||
virtual void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override {
|
||||
}
|
||||
|
||||
void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) override;
|
||||
|
||||
virtual void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override {
|
||||
throw std::logic_error("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
virtual void DisableState() override {
|
||||
}
|
||||
|
||||
virtual void FlushBeforeCopy() override;
|
||||
|
||||
void DecimateFBOs() override;
|
||||
|
||||
virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override {
|
||||
throw std::logic_error("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
virtual void DestroyFramebuf(VirtualFramebuffer *vfb) override {
|
||||
throw std::logic_error("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
virtual void ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u16 h, bool force = false) override {
|
||||
}
|
||||
|
||||
virtual void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) override {
|
||||
}
|
||||
|
||||
virtual void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) override {
|
||||
}
|
||||
|
||||
virtual void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) override {
|
||||
}
|
||||
|
||||
void DestroyAllFBOs();
|
||||
void Resized();
|
||||
void DeviceLost();
|
||||
|
||||
void CopyDisplayToOutput();
|
||||
void EndFrame();
|
||||
|
||||
std::vector<FramebufferInfo> GetFramebufferList();
|
||||
|
||||
bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;
|
||||
|
||||
void DestroyFramebuf(VirtualFramebuffer *vfb) override;
|
||||
void ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, u16 h, bool force = false) override;
|
||||
|
||||
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer);
|
||||
bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer);
|
||||
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer);
|
||||
static bool GetDisplayFramebuffer(GPUDebugBuffer &buffer);
|
||||
|
||||
virtual void RebindFramebuffer() override;
|
||||
|
||||
VulkanFramebuffer *GetTempFBO(u16 w, u16 h, VulkanFBOColorDepth depth = VK_FBO_8888);
|
||||
|
||||
// Cardboard Settings Calculator
|
||||
struct CardboardSettings * GetCardboardSettings(struct CardboardSettings * cardboardSettings);
|
||||
|
||||
protected:
|
||||
bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
virtual void DisableState() override;
|
||||
virtual void ClearBuffer(bool keepState = false);
|
||||
virtual void FlushBeforeCopy() override;
|
||||
virtual void DecimateFBOs() override;
|
||||
|
||||
// Used by ReadFramebufferToMemory and later framebuffer block copies
|
||||
virtual void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) override;
|
||||
|
||||
virtual void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) override;
|
||||
virtual void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) override;
|
||||
virtual void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) override;
|
||||
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
|
||||
|
||||
private:
|
||||
VulkanContext *vulkan_;
|
||||
VkCommandBuffer cmd_;
|
||||
void UpdatePostShaderUniforms(int bufferWidth, int bufferHeight, int renderWidth, int renderHeight);
|
||||
void CompileDraw2DProgram();
|
||||
void DestroyDraw2DProgram();
|
||||
|
||||
void SetNumExtraFBOs(int num);
|
||||
|
||||
void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently
|
||||
void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
|
||||
VulkanContext *vulkan_;
|
||||
|
||||
// The command buffer of the current framebuffer pass being rendered to.
|
||||
// One framebuffer can be used as a texturing source at multiple times in a frame,
|
||||
// but then the contents have to be copied out into a new texture every time.
|
||||
VkCommandBuffer curCmd_;
|
||||
|
||||
TextureCacheVulkan *texCache_;
|
||||
DrawEngineVulkan *drawEngine_;
|
||||
|
||||
// Used by DrawPixels
|
||||
VulkanTexture *drawPixelsTex_;
|
||||
GEBufferFormat drawPixelsTexFormat_;
|
||||
|
||||
int drawPixelsTexW_;
|
||||
int drawPixelsTexH_;
|
||||
|
||||
u8 *convBuf_;
|
||||
u32 convBufSize_;
|
||||
|
||||
TextureCacheVulkan *textureCache_;
|
||||
ShaderManagerVulkan *shaderManager_;
|
||||
DrawEngineVulkan *transformDraw_;
|
||||
|
||||
// Used by post-processing shader
|
||||
std::vector<FBO *> extraFBOs_;
|
||||
|
||||
bool resized_;
|
||||
|
||||
struct TempFBO {
|
||||
VulkanFramebuffer *fbo_vk;
|
||||
int last_frame_used;
|
||||
};
|
||||
|
||||
std::map<u64, TempFBO> tempFBOs_;
|
||||
|
||||
// Not used under ES currently.
|
||||
AsyncPBOVulkan *pixelBufObj_; //this isn't that large
|
||||
u8 currentPBO_;
|
||||
|
||||
// This gets copied to the current frame's push buffer as needed.
|
||||
PostShaderUniforms postUniforms_;
|
||||
};
|
||||
|
@ -394,7 +394,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *ctx)
|
||||
: vulkan_((VulkanContext *)ctx->GetAPIContext()),
|
||||
drawEngine_(vulkan_),
|
||||
textureCache_(vulkan_),
|
||||
framebufferManager_(vulkan_),
|
||||
resized_(false),
|
||||
gfxCtx_(ctx) {
|
||||
UpdateVsyncInterval(true);
|
||||
@ -402,14 +401,15 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *ctx)
|
||||
|
||||
shaderManager_ = new ShaderManagerVulkan(vulkan_);
|
||||
pipelineManager_ = new PipelineManagerVulkan(vulkan_);
|
||||
framebufferManager_ = new FramebufferManagerVulkan(vulkan_),
|
||||
drawEngine_.SetTextureCache(&textureCache_);
|
||||
drawEngine_.SetFramebufferManager(&framebufferManager_);
|
||||
drawEngine_.SetFramebufferManager(framebufferManager_);
|
||||
drawEngine_.SetShaderManager(shaderManager_);
|
||||
drawEngine_.SetPipelineManager(pipelineManager_);
|
||||
framebufferManager_.Init();
|
||||
framebufferManager_.SetTextureCache(&textureCache_);
|
||||
framebufferManager_.SetDrawEngine(&drawEngine_);
|
||||
textureCache_.SetFramebufferManager(&framebufferManager_);
|
||||
framebufferManager_->Init();
|
||||
framebufferManager_->SetTextureCache(&textureCache_);
|
||||
framebufferManager_->SetDrawEngine(&drawEngine_);
|
||||
textureCache_.SetFramebufferManager(framebufferManager_);
|
||||
textureCache_.SetDepalShaderCache(&depalShaderCache_);
|
||||
textureCache_.SetShaderManager(shaderManager_);
|
||||
textureCache_.SetTransformDrawEngine(&drawEngine_);
|
||||
@ -453,8 +453,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *ctx)
|
||||
}
|
||||
|
||||
GPU_Vulkan::~GPU_Vulkan() {
|
||||
framebufferManager_.DestroyAllFBOs();
|
||||
shaderManager_->ClearCache(true);
|
||||
framebufferManager_->DestroyAllFBOs();
|
||||
depalShaderCache_.Clear();
|
||||
delete shaderManager_;
|
||||
shaderManager_ = nullptr;
|
||||
@ -511,12 +510,12 @@ void GPU_Vulkan::BeginHostFrame() {
|
||||
shaderManager_->DirtyShader();
|
||||
shaderManager_->DirtyUniform(DIRTY_ALL);
|
||||
|
||||
framebufferManager_.BeginFrame();
|
||||
framebufferManager_->BeginFrame();
|
||||
}
|
||||
|
||||
void GPU_Vulkan::EndHostFrame() {
|
||||
drawEngine_.EndFrame();
|
||||
framebufferManager_.EndFrame();
|
||||
framebufferManager_->EndFrame();
|
||||
}
|
||||
|
||||
// Needs to be called on GPU thread, not reporting thread.
|
||||
@ -542,8 +541,8 @@ void GPU_Vulkan::Reinitialize() {
|
||||
void GPU_Vulkan::ReinitializeInternal() {
|
||||
textureCache_.Clear(true);
|
||||
depalShaderCache_.Clear();
|
||||
framebufferManager_.DestroyAllFBOs();
|
||||
framebufferManager_.Resized();
|
||||
framebufferManager_->DestroyAllFBOs();
|
||||
framebufferManager_->Resized();
|
||||
}
|
||||
|
||||
void GPU_Vulkan::InitClearInternal() {
|
||||
@ -601,7 +600,7 @@ void GPU_Vulkan::BeginFrameInternal() {
|
||||
|
||||
void GPU_Vulkan::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) {
|
||||
host->GPUNotifyDisplay(framebuf, stride, format);
|
||||
framebufferManager_.SetDisplayFramebuffer(framebuf, stride, format);
|
||||
framebufferManager_->SetDisplayFramebuffer(framebuf, stride, format);
|
||||
}
|
||||
|
||||
bool GPU_Vulkan::FramebufferDirty() {
|
||||
@ -610,7 +609,7 @@ bool GPU_Vulkan::FramebufferDirty() {
|
||||
SyncThread();
|
||||
}
|
||||
|
||||
VirtualFramebuffer *vfb = framebufferManager_.GetDisplayVFB();
|
||||
VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB();
|
||||
if (vfb) {
|
||||
bool dirty = vfb->dirtyAfterDisplay;
|
||||
vfb->dirtyAfterDisplay = false;
|
||||
@ -625,7 +624,7 @@ bool GPU_Vulkan::FramebufferReallyDirty() {
|
||||
SyncThread();
|
||||
}
|
||||
|
||||
VirtualFramebuffer *vfb = framebufferManager_.GetDisplayVFB();
|
||||
VirtualFramebuffer *vfb = framebufferManager_->GetDisplayVFB();
|
||||
if (vfb) {
|
||||
bool dirty = vfb->reallyDirtyAfterDisplay;
|
||||
vfb->reallyDirtyAfterDisplay = false;
|
||||
@ -644,7 +643,7 @@ void GPU_Vulkan::CopyDisplayToOutputInternal() {
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
framebufferManager_.CopyDisplayToOutput();
|
||||
framebufferManager_->CopyDisplayToOutput();
|
||||
|
||||
gstate_c.textureChanged = TEXCHANGE_UPDATED;
|
||||
}
|
||||
@ -774,7 +773,7 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {
|
||||
}
|
||||
|
||||
// This also makes skipping drawing very effective.
|
||||
framebufferManager_.SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
|
||||
framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
|
||||
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
|
||||
drawEngine_.SetupVertexDecoder(gstate.vertType);
|
||||
// Rough estimate, not sure what's correct.
|
||||
@ -850,7 +849,7 @@ void GPU_Vulkan::Execute_VertexTypeSkinning(u32 op, u32 diff) {
|
||||
|
||||
void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) {
|
||||
// This also make skipping drawing very effective.
|
||||
framebufferManager_.SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
|
||||
framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
|
||||
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
|
||||
// TODO: Should this eat some cycles? Probably yes. Not sure if important.
|
||||
return;
|
||||
@ -893,7 +892,7 @@ void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) {
|
||||
|
||||
void GPU_Vulkan::Execute_Spline(u32 op, u32 diff) {
|
||||
// This also make skipping drawing very effective.
|
||||
framebufferManager_.SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
|
||||
framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
|
||||
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
|
||||
// TODO: Should this eat some cycles? Probably yes. Not sure if important.
|
||||
return;
|
||||
@ -1935,7 +1934,7 @@ void GPU_Vulkan::UpdateStats() {
|
||||
gpuStats.numFragmentShaders = shaderManager_->GetNumFragmentShaders();
|
||||
gpuStats.numShaders = pipelineManager_->GetNumPipelines();
|
||||
gpuStats.numTextures = (int)textureCache_.NumLoadedTextures();
|
||||
gpuStats.numFBOs = (int)framebufferManager_.NumVFBs();
|
||||
gpuStats.numFBOs = (int)framebufferManager_->NumVFBs();
|
||||
}
|
||||
|
||||
void GPU_Vulkan::DoBlockTransfer(u32 skipDrawReason) {
|
||||
@ -1992,7 +1991,7 @@ void GPU_Vulkan::DoBlockTransfer(u32 skipDrawReason) {
|
||||
}
|
||||
|
||||
// Tell the framebuffer manager to take action if possible. If it does the entire thing, let's just return.
|
||||
if (!framebufferManager_.NotifyBlockTransferBefore(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason)) {
|
||||
if (!framebufferManager_->NotifyBlockTransferBefore(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason)) {
|
||||
// Do the copy! (Hm, if we detect a drawn video frame (see below) then we could maybe skip this?)
|
||||
// Can use GetPointerUnchecked because we checked the addresses above. We could also avoid them
|
||||
// entirely by walking a couple of pointers...
|
||||
@ -2015,7 +2014,7 @@ void GPU_Vulkan::DoBlockTransfer(u32 skipDrawReason) {
|
||||
}
|
||||
|
||||
textureCache_.Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT);
|
||||
framebufferManager_.NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
|
||||
framebufferManager_->NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
|
||||
}
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
@ -2041,17 +2040,17 @@ void GPU_Vulkan::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType
|
||||
else
|
||||
textureCache_.InvalidateAll(type);
|
||||
|
||||
if (type != GPU_INVALIDATE_ALL && framebufferManager_.MayIntersectFramebuffer(addr)) {
|
||||
if (type != GPU_INVALIDATE_ALL && framebufferManager_->MayIntersectFramebuffer(addr)) {
|
||||
// If we're doing block transfers, we shouldn't need this, and it'll only confuse us.
|
||||
// Vempire invalidates (with writeback) after drawing, but before blitting.
|
||||
if (!g_Config.bBlockTransferGPU || type == GPU_INVALIDATE_SAFE) {
|
||||
framebufferManager_.UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE);
|
||||
framebufferManager_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_Vulkan::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
if (!framebufferManager_->NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
// We use a little hack for Download/Upload using a VRAM mirror.
|
||||
// Since they're identical we don't need to copy.
|
||||
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
|
||||
@ -2062,18 +2061,18 @@ void GPU_Vulkan::PerformMemoryCopyInternal(u32 dest, u32 src, int size) {
|
||||
}
|
||||
|
||||
void GPU_Vulkan::PerformMemorySetInternal(u32 dest, u8 v, int size) {
|
||||
if (!framebufferManager_.NotifyFramebufferCopy(dest, dest, size, true, gstate_c.skipDrawReason)) {
|
||||
if (!framebufferManager_->NotifyFramebufferCopy(dest, dest, size, true, gstate_c.skipDrawReason)) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_Vulkan::PerformStencilUploadInternal(u32 dest, int size) {
|
||||
framebufferManager_.NotifyStencilUpload(dest, size);
|
||||
framebufferManager_->NotifyStencilUpload(dest, size);
|
||||
}
|
||||
|
||||
bool GPU_Vulkan::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
// Track stray copies of a framebuffer in RAM. MotoGP does this.
|
||||
if (framebufferManager_.MayIntersectFramebuffer(src) || framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
if (framebufferManager_->MayIntersectFramebuffer(src) || framebufferManager_->MayIntersectFramebuffer(dest)) {
|
||||
if (IsOnSeparateCPUThread()) {
|
||||
GPUEvent ev(GPU_EVENT_FB_MEMCPY);
|
||||
ev.fb_memcpy.dst = dest;
|
||||
@ -2095,7 +2094,7 @@ bool GPU_Vulkan::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
|
||||
bool GPU_Vulkan::PerformMemorySet(u32 dest, u8 v, int size) {
|
||||
// This may indicate a memset, usually to 0, of a framebuffer.
|
||||
if (framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
if (framebufferManager_->MayIntersectFramebuffer(dest)) {
|
||||
Memory::Memset(dest, v, size);
|
||||
|
||||
if (IsOnSeparateCPUThread()) {
|
||||
@ -2136,7 +2135,7 @@ bool GPU_Vulkan::PerformMemoryUpload(u32 dest, int size) {
|
||||
}
|
||||
|
||||
bool GPU_Vulkan::PerformStencilUpload(u32 dest, int size) {
|
||||
if (framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
if (framebufferManager_->MayIntersectFramebuffer(dest)) {
|
||||
if (IsOnSeparateCPUThread()) {
|
||||
GPUEvent ev(GPU_EVENT_FB_STENCIL_UPLOAD);
|
||||
ev.fb_stencil_upload.dst = dest;
|
||||
@ -2156,15 +2155,15 @@ void GPU_Vulkan::ClearCacheNextFrame() {
|
||||
|
||||
void GPU_Vulkan::Resized() {
|
||||
resized_ = true;
|
||||
framebufferManager_.Resized();
|
||||
framebufferManager_->Resized();
|
||||
}
|
||||
|
||||
void GPU_Vulkan::ClearShaderCache() {
|
||||
shaderManager_->ClearCache(true);
|
||||
// TODO
|
||||
}
|
||||
|
||||
std::vector<FramebufferInfo> GPU_Vulkan::GetFramebufferList() {
|
||||
return framebufferManager_.GetFramebufferList();
|
||||
return framebufferManager_->GetFramebufferList();
|
||||
}
|
||||
|
||||
void GPU_Vulkan::DoState(PointerWrap &p) {
|
||||
@ -2178,8 +2177,9 @@ void GPU_Vulkan::DoState(PointerWrap &p) {
|
||||
depalShaderCache_.Clear();
|
||||
|
||||
gstate_c.textureChanged = TEXCHANGE_UPDATED;
|
||||
framebufferManager_.DestroyAllFBOs();
|
||||
shaderManager_->ClearCache(true);
|
||||
framebufferManager_->DestroyAllFBOs();
|
||||
shaderManager_->ClearShaders();
|
||||
pipelineManager_->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,13 @@
|
||||
#include <deque>
|
||||
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/Vulkan/FramebufferVulkan.h"
|
||||
#include "GPU/Vulkan/DrawEngineVulkan.h"
|
||||
#include "GPU/Vulkan/PipelineManagerVulkan.h"
|
||||
#include "GPU/Vulkan/TextureCacheVulkan.h"
|
||||
#include "GPU/Vulkan/DepalettizeShaderVulkan.h"
|
||||
|
||||
class ShaderManager;
|
||||
class FramebufferManagerVulkan;
|
||||
class ShaderManagerVulkan;
|
||||
class LinkedShader;
|
||||
|
||||
class GPU_Vulkan : public GPUCommon {
|
||||
@ -178,7 +178,7 @@ private:
|
||||
|
||||
GraphicsContext *gfxCtx_;
|
||||
VulkanContext *vulkan_;
|
||||
FramebufferManagerVulkan framebufferManager_;
|
||||
FramebufferManagerVulkan *framebufferManager_;
|
||||
TextureCacheVulkan textureCache_;
|
||||
DepalShaderCacheVulkan depalShaderCache_;
|
||||
DrawEngineVulkan drawEngine_;
|
||||
|
@ -12,6 +12,10 @@ PipelineManagerVulkan::PipelineManagerVulkan(VulkanContext *vulkan) : vulkan_(vu
|
||||
}
|
||||
|
||||
PipelineManagerVulkan::~PipelineManagerVulkan() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void PipelineManagerVulkan::Clear() {
|
||||
// This should kill off all the shaders at once.
|
||||
// This could also be an opportunity to store the whole cache to disk. Will need to also
|
||||
// store the keys.
|
||||
|
@ -81,7 +81,9 @@ public:
|
||||
~PipelineManagerVulkan();
|
||||
|
||||
VulkanPipeline *GetOrCreatePipeline(VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VkShaderModule vShader, VkShaderModule fShader, bool useHwTransform);
|
||||
int GetNumPipelines() const { return 0; }
|
||||
int GetNumPipelines() const { return (int)pipelines_.size(); }
|
||||
|
||||
void Clear();
|
||||
|
||||
std::string DebugGetObjectString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
|
||||
std::vector<std::string> DebugGetObjectIDs(DebugShaderType type);
|
||||
|
@ -181,6 +181,7 @@ ShaderManagerVulkan::ShaderManagerVulkan(VulkanContext *vulkan)
|
||||
}
|
||||
|
||||
ShaderManagerVulkan::~ShaderManagerVulkan() {
|
||||
ClearShaders();
|
||||
delete[] codeBuffer_;
|
||||
}
|
||||
|
||||
@ -447,15 +448,14 @@ void ShaderManagerVulkan::Clear() {
|
||||
vsCache_.clear();
|
||||
lastFSID_.clear();
|
||||
lastVSID_.clear();
|
||||
}
|
||||
|
||||
void ShaderManagerVulkan::ClearShaders() {
|
||||
Clear();
|
||||
DirtyShader();
|
||||
DirtyUniform(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void ShaderManagerVulkan::ClearCache(bool deleteThem) {
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
void ShaderManagerVulkan::DirtyShader() {
|
||||
// Forget the last shader ID
|
||||
lastFSID_.clear();
|
||||
|
@ -217,9 +217,8 @@ public:
|
||||
ShaderManagerVulkan(VulkanContext *vulkan);
|
||||
~ShaderManagerVulkan();
|
||||
|
||||
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
|
||||
void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform);
|
||||
|
||||
void ClearShaders();
|
||||
void DirtyShader();
|
||||
void DirtyLastShader();
|
||||
|
||||
|
@ -905,8 +905,7 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
|
||||
surface,
|
||||
&presentModeCount, NULL);
|
||||
assert(res == VK_SUCCESS);
|
||||
VkPresentModeKHR *presentModes =
|
||||
(VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR));
|
||||
VkPresentModeKHR *presentModes = new VkPresentModeKHR[presentModeCount];
|
||||
assert(presentModes);
|
||||
res = fpGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[0],
|
||||
surface,
|
||||
@ -944,7 +943,7 @@ void VulkanContext::InitSwapchain(VkCommandBuffer cmd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// queued for display):
|
||||
@ -1650,7 +1649,7 @@ bool GLSLtoSPV(const VkShaderStageFlagBits shader_type,
|
||||
const char *pshader,
|
||||
std::vector<unsigned int> &spirv, std::string *errorMessage) {
|
||||
|
||||
glslang::TProgram& program = *new glslang::TProgram;
|
||||
glslang::TProgram program;
|
||||
const char *shaderStrings[1];
|
||||
TBuiltInResource Resources;
|
||||
init_resources(Resources);
|
||||
@ -1659,33 +1658,30 @@ bool GLSLtoSPV(const VkShaderStageFlagBits shader_type,
|
||||
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
|
||||
|
||||
EShLanguage stage = FindLanguage(shader_type);
|
||||
glslang::TShader* shader = new glslang::TShader(stage);
|
||||
glslang::TShader shader(stage);
|
||||
|
||||
shaderStrings[0] = pshader;
|
||||
shader->setStrings(shaderStrings, 1);
|
||||
shader.setStrings(shaderStrings, 1);
|
||||
|
||||
if (!shader->parse(&Resources, 100, false, messages)) {
|
||||
puts(shader->getInfoLog());
|
||||
puts(shader->getInfoDebugLog());
|
||||
if (!shader.parse(&Resources, 100, false, messages)) {
|
||||
puts(shader.getInfoLog());
|
||||
puts(shader.getInfoDebugLog());
|
||||
if (errorMessage) {
|
||||
*errorMessage = shader->getInfoLog();
|
||||
(*errorMessage) += shader->getInfoDebugLog();
|
||||
*errorMessage = shader.getInfoLog();
|
||||
(*errorMessage) += shader.getInfoDebugLog();
|
||||
}
|
||||
return false; // something didn't work
|
||||
}
|
||||
|
||||
program.addShader(shader);
|
||||
|
||||
//
|
||||
// Program-level processing...
|
||||
//
|
||||
// Note that program does not take ownership of &shader, so this is fine.
|
||||
program.addShader(&shader);
|
||||
|
||||
if (!program.link(messages)) {
|
||||
puts(shader->getInfoLog());
|
||||
puts(shader->getInfoDebugLog());
|
||||
puts(shader.getInfoLog());
|
||||
puts(shader.getInfoDebugLog());
|
||||
if (errorMessage) {
|
||||
*errorMessage = shader->getInfoLog();
|
||||
(*errorMessage) += shader->getInfoDebugLog();
|
||||
*errorMessage = shader.getInfoLog();
|
||||
(*errorMessage) += shader.getInfoDebugLog();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -279,6 +279,7 @@ public:
|
||||
~Thin3DVKShaderSet() {
|
||||
vshader->Release();
|
||||
fshader->Release();
|
||||
delete[] ubo_;
|
||||
}
|
||||
bool Link();
|
||||
|
||||
@ -667,7 +668,9 @@ Thin3DVKContext::~Thin3DVKContext() {
|
||||
vkDestroyCommandPool(device_, cmdPool_, nullptr);
|
||||
// This also destroys all descriptor sets.
|
||||
for (int i = 0; i < 2; i++) {
|
||||
frame_[i].descSets_.clear();
|
||||
vkDestroyDescriptorPool(device_, frame_[i].descriptorPool, nullptr);
|
||||
delete frame_[i].pushBuffer;
|
||||
}
|
||||
vkDestroyDescriptorSetLayout(device_, descriptorSetLayout_, nullptr);
|
||||
vkDestroyPipelineLayout(device_, pipelineLayout_, nullptr);
|
||||
|
@ -46,7 +46,9 @@
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifndef strdup
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user