mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #10479 from hrydgard/vulkan-renderpass-cache
Vulkan: Create renderpass objects on demand.
This commit is contained in:
commit
2f24ff85ee
24 changed files with 150 additions and 115 deletions
|
@ -209,7 +209,7 @@ void FramebufferManagerCommon::SetNumExtraFBOs(int num) {
|
|||
}
|
||||
currentRenderVfb_ = 0;
|
||||
if (num != 0)
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
|
||||
// Heuristics to figure out the size of FBO to create.
|
||||
|
@ -607,12 +607,12 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe
|
|||
// FBO in a frame. This means that some games won't be able to avoid the on-some-GPUs
|
||||
// performance-crushing framebuffer reloads from RAM, but we'll have to live with that.
|
||||
if (vfb->last_frame_render != gpuStats.numFlips) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
} else {
|
||||
// This should only happen very briefly when toggling useBufferedRendering_.
|
||||
|
@ -721,7 +721,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int
|
|||
MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height, u1, v1);
|
||||
|
||||
if (useBufferedRendering_ && vfb && vfb->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
draw_->SetScissorRect(0, 0, vfb->renderWidth, vfb->renderHeight);
|
||||
} else {
|
||||
|
@ -849,7 +849,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
DEBUG_LOG(FRAMEBUF, "Display disabled, displaying only black");
|
||||
// No framebuffer to display! Clear to black.
|
||||
if (useBufferedRendering_) {
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -914,7 +914,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
if (!vfb) {
|
||||
if (useBufferedRendering_) {
|
||||
// Bind and clear the backbuffer. This should be the first time during the frame that it's bound.
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
// Just a pointer to plain memory to draw. We should create a framebuffer, then draw to it.
|
||||
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
|
||||
|
@ -927,7 +927,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
// No framebuffer to display! Clear to black.
|
||||
if (useBufferedRendering_) {
|
||||
// Bind and clear the backbuffer. This should be the first time during the frame that it's bound.
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -964,7 +964,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
float v1 = (272.0f + offsetY) / (float)vfb->bufferHeight;
|
||||
|
||||
if (!usePostShader_) {
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsTexture(vfb->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
|
||||
DrawTextureFlags flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
|
||||
|
@ -988,7 +988,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
}
|
||||
} else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) {
|
||||
// An additional pass, post-processing shader to the extra FBO.
|
||||
draw_->BindFramebufferAsRenderTarget(extraFBOs_[0], { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(extraFBOs_[0], { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsTexture(vfb->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
int fbo_w, fbo_h;
|
||||
draw_->GetFramebufferDimensions(extraFBOs_[0], &fbo_w, &fbo_h);
|
||||
|
@ -1001,7 +1001,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
DrawTextureFlags flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
|
||||
DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, flags);
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
|
||||
|
||||
// Use the extra FBO, with applied post-processing shader, as a texture.
|
||||
|
@ -1034,12 +1034,12 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
|
|||
|
||||
/*
|
||||
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
|
||||
draw_->BindFramebufferAsRenderTarget(extraFBOs_[0], { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(extraFBOs_[0], { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
}*/
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsTexture(vfb->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
|
||||
// We are doing the DrawActiveTexture call directly to the backbuffer here. Hence, we must
|
||||
|
@ -1190,17 +1190,17 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w,
|
|||
if (old.fbo) {
|
||||
INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format);
|
||||
if (vfb->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
if (!skipCopy && !g_Config.bDisableSlowFramebufEffects) {
|
||||
BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0);
|
||||
}
|
||||
}
|
||||
fbosToDelete_.push_back(old.fbo);
|
||||
if (needGLESRebinds_) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
|
||||
if (!vfb->fbo) {
|
||||
|
@ -2115,10 +2115,10 @@ void FramebufferManagerCommon::DownloadFramebufferForClut(u32 fb_address, u32 lo
|
|||
|
||||
void FramebufferManagerCommon::RebindFramebuffer() {
|
||||
if (currentRenderVfb_ && currentRenderVfb_->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
} else {
|
||||
// Should this even happen? It could while debugging, but maybe we can just skip binding at all.
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE);
|
||||
}
|
||||
|
|
|
@ -461,10 +461,10 @@ void FramebufferManagerD3D11::BindPostShader(const PostShaderUniforms &uniforms)
|
|||
|
||||
void FramebufferManagerD3D11::RebindFramebuffer() {
|
||||
if (currentRenderVfb_ && currentRenderVfb_->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
} else {
|
||||
// Should this even happen?
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,7 +482,7 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G
|
|||
// and blit with a shader to that, then replace the FBO on vfb. Stencil would still be complex
|
||||
// to exactly reproduce in 4444 and 8888 formats.
|
||||
if (old == GE_FORMAT_565) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
|
||||
// TODO: There's no way this does anything useful :(
|
||||
context_->OMSetDepthStencilState(stockD3D11.depthDisabledStencilWrite, 0xFF);
|
||||
|
@ -591,7 +591,7 @@ bool FramebufferManagerD3D11::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb)
|
|||
return false;
|
||||
}
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -634,7 +634,7 @@ void FramebufferManagerD3D11::SimpleBlit(
|
|||
|
||||
// Unbind the texture first to avoid the D3D11 hazard check (can't set render target to things bound as textures and vice versa, not even temporarily).
|
||||
draw_->BindTexture(0, nullptr);
|
||||
draw_->BindFramebufferAsRenderTarget(dest, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(dest, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsTexture(src, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
Bind2DShader();
|
||||
|
@ -657,7 +657,7 @@ void FramebufferManagerD3D11::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
|||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if they recently switched from non-buffered.
|
||||
if (useBufferedRendering_) {
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZ
|
|||
float v1 = 1.0f;
|
||||
MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1);
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
} else {
|
||||
// something is wrong...
|
||||
}
|
||||
|
|
|
@ -398,7 +398,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra
|
|||
context_->PSSetShaderResources(1, 1, &clutTexture);
|
||||
framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY);
|
||||
context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
shaderApply.Shade();
|
||||
|
||||
framebufferManagerD3D11_->RebindFramebuffer();
|
||||
|
|
|
@ -319,7 +319,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
|||
return;
|
||||
}
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
|
||||
// Technically, we should at this point re-interpret the bytes of the old format to the new.
|
||||
// That might get tricky, and could cause unnecessary slowness in some games.
|
||||
|
@ -478,7 +478,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
|||
return false;
|
||||
}
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -490,7 +490,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
|||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if we recently switched from non-buffered.
|
||||
if (useBufferedRendering_)
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer
|
|||
u16 h = dstBuffer->renderHeight;
|
||||
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
D3DVIEWPORT9 vp{ 0, 0, w, h, 0.0f, 1.0f };
|
||||
device_->SetViewport(&vp);
|
||||
|
|
|
@ -425,7 +425,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
|
|||
LPDIRECT3DTEXTURE9 clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
|
||||
Draw::Framebuffer *depalFBO = framebufferManagerDX9_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
float xoff = -0.5f / framebuffer->renderWidth;
|
||||
|
|
|
@ -504,9 +504,9 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE
|
|||
// to exactly reproduce in 4444 and 8888 formats.
|
||||
|
||||
if (old == GE_FORMAT_565) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
|
||||
RebindFramebuffer();
|
||||
|
@ -640,11 +640,11 @@ void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb)
|
|||
|
||||
// Discard the previous contents of this buffer where possible.
|
||||
if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) {
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
} else if (gl_extensions.IsGLES) {
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
|||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if they recently switched from non-buffered.
|
||||
if (useBufferedRendering_)
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -708,7 +708,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
|
|||
if (useBlit) {
|
||||
draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST);
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(dst->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(dst->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsTexture(src->fbo, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
// Make sure our 2D drawing program is ready. Compiles only if not already compiled.
|
||||
|
@ -980,7 +980,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::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
const GLenum target = GL_FRAMEBUFFER;
|
||||
#else
|
||||
const GLenum target = GL_READ_FRAMEBUFFER;
|
||||
|
@ -1044,11 +1044,11 @@ void FramebufferManagerGLES::EndFrame() {
|
|||
continue;
|
||||
}
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(temp.second.fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(temp.second.fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT };
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments);
|
||||
}
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP , Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP , Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
|
|
@ -160,9 +160,9 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe
|
|||
Draw::Framebuffer *blitFBO = nullptr;
|
||||
if (useBlit) {
|
||||
blitFBO = GetTempFBO(w, h, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
} else if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
}
|
||||
glViewport(0, 0, w, h);
|
||||
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE);
|
||||
|
|
|
@ -493,7 +493,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
|||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
GLuint clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
Draw::Framebuffer *depalFBO = framebufferManagerGL_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
TextureShaderApplier shaderApply(depal, framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
|
|
|
@ -213,7 +213,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
|
|||
u1 = 1.0f;
|
||||
}
|
||||
if (!hasImage) {
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
|
|||
if (GetGPUBackend() == GPUBackend::VULKAN) {
|
||||
std::swap(v0, v1);
|
||||
}
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
Draw::Viewport viewport = { 0.0f, 0.0f, dstwidth, dstheight, 0.0f, 1.0f };
|
||||
draw_->SetViewports(1, &viewport);
|
||||
draw_->SetScissorRect(0, 0, dstwidth, dstheight);
|
||||
|
|
|
@ -394,9 +394,9 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb,
|
|||
// to exactly reproduce in 4444 and 8888 formats.
|
||||
|
||||
if (old == GE_FORMAT_565) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
} else {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,7 +467,7 @@ bool FramebufferManagerVulkan::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb
|
|||
return false;
|
||||
}
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -479,7 +479,7 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
|
|||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if they recently switched from non-buffered.
|
||||
if (useBufferedRendering_)
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP });
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip
|
|||
}
|
||||
|
||||
// TODO: Find a nice way to clear alpha here too.
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE);
|
||||
return true;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip
|
|||
float v1 = 1.0f;
|
||||
MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight, u1, v1);
|
||||
if (dstBuffer->fbo) {
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR });
|
||||
draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
|
||||
} else {
|
||||
// something is wrong...
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr
|
|||
|
||||
Draw::Framebuffer *depalFBO = framebufferManager_->GetTempFBO(
|
||||
framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
|
||||
|
||||
Vulkan2D::Vertex verts[4] = {
|
||||
{ -1, -1, 0.0f, 0, 0 },
|
||||
|
|
|
@ -1022,9 +1022,9 @@ void EmuScreen::preRender() {
|
|||
if ((!useBufferedRendering && !g_Config.bSoftwareRendering) || Core_IsStepping()) {
|
||||
// We need to clear here already so that drawing during the frame is done on a clean slate.
|
||||
if (Core_IsStepping() && gpuStats.numFlips != 0) {
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE });
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE });
|
||||
} else {
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 });
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 });
|
||||
}
|
||||
|
||||
Viewport viewport;
|
||||
|
@ -1057,7 +1057,7 @@ void EmuScreen::render() {
|
|||
// It's possible this might be set outside PSP_RunLoopFor().
|
||||
// In this case, we need to double check it here.
|
||||
checkPowerDown();
|
||||
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR });
|
||||
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR });
|
||||
renderUI();
|
||||
return;
|
||||
}
|
||||
|
@ -1092,12 +1092,12 @@ void EmuScreen::render() {
|
|||
coreState = CORE_RUNNING;
|
||||
} else if (coreState == CORE_STEPPING) {
|
||||
// If we're stepping, it's convenient not to clear the screen.
|
||||
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE });
|
||||
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE });
|
||||
} else {
|
||||
// Didn't actually reach the end of the frame, ran out of the blockTicks cycles.
|
||||
// In this case we need to bind and wipe the backbuffer, at least.
|
||||
// It's possible we never ended up outputted anything - make sure we have the backbuffer cleared
|
||||
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR });
|
||||
thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR });
|
||||
}
|
||||
checkPowerDown();
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
void VulkanQueueRunner::CreateDeviceObjects() {
|
||||
ILOG("VulkanQueueRunner::CreateDeviceObjects");
|
||||
InitBackbufferRenderPass();
|
||||
InitRenderpasses();
|
||||
|
||||
#if 0
|
||||
// Just to check whether it makes sense to split some of these. drawidx is way bigger than the others...
|
||||
|
@ -67,11 +66,12 @@ void VulkanQueueRunner::DestroyDeviceObjects() {
|
|||
vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_);
|
||||
readbackBufferSize_ = 0;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(renderPasses_); i++) {
|
||||
assert(renderPasses_[i] != VK_NULL_HANDLE);
|
||||
vulkan_->Delete().QueueDeleteRenderPass(renderPasses_[i]);
|
||||
renderPasses_[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
renderPasses_.Iterate([&](const RPKey &rpkey, VkRenderPass rp) {
|
||||
_assert_(rp != VK_NULL_HANDLE);
|
||||
vulkan_->Delete().QueueDeleteRenderPass(rp);
|
||||
});
|
||||
renderPasses_.Clear();
|
||||
|
||||
assert(backbufferRenderPass_ != VK_NULL_HANDLE);
|
||||
vulkan_->Delete().QueueDeleteRenderPass(backbufferRenderPass_);
|
||||
backbufferRenderPass_ = VK_NULL_HANDLE;
|
||||
|
@ -141,13 +141,28 @@ void VulkanQueueRunner::InitBackbufferRenderPass() {
|
|||
assert(res == VK_SUCCESS);
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::InitRenderpasses() {
|
||||
// Create a bunch of render pass objects, for normal rendering with a depth buffer,
|
||||
// with clearing, without clearing, and dont-care for both depth/stencil and color, so 3*3=9 combos.
|
||||
VkRenderPass VulkanQueueRunner::GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction) {
|
||||
RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction };
|
||||
auto pass = renderPasses_.Get(key);
|
||||
if (pass) {
|
||||
return pass;
|
||||
}
|
||||
|
||||
VkAttachmentDescription attachments[2] = {};
|
||||
attachments[0].format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
switch (colorLoadAction) {
|
||||
case VKRRenderPassAction::CLEAR:
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
break;
|
||||
case VKRRenderPassAction::KEEP:
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
break;
|
||||
case VKRRenderPassAction::DONT_CARE:
|
||||
default:
|
||||
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
break;
|
||||
}
|
||||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
|
@ -157,9 +172,29 @@ void VulkanQueueRunner::InitRenderpasses() {
|
|||
|
||||
attachments[1].format = vulkan_->GetDeviceInfo().preferredDepthStencilFormat;
|
||||
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
switch (depthLoadAction) {
|
||||
case VKRRenderPassAction::CLEAR:
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
break;
|
||||
case VKRRenderPassAction::KEEP:
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
break;
|
||||
case VKRRenderPassAction::DONT_CARE:
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
break;
|
||||
}
|
||||
switch (stencilLoadAction) {
|
||||
case VKRRenderPassAction::CLEAR:
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
break;
|
||||
case VKRRenderPassAction::KEEP:
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
break;
|
||||
case VKRRenderPassAction::DONT_CARE:
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
break;
|
||||
}
|
||||
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
@ -192,31 +227,10 @@ void VulkanQueueRunner::InitRenderpasses() {
|
|||
rp.pSubpasses = &subpass;
|
||||
rp.dependencyCount = 0;
|
||||
|
||||
for (int depth = 0; depth < 3; depth++) {
|
||||
switch ((VKRRenderPassAction)depth) {
|
||||
case VKRRenderPassAction::CLEAR:
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
break;
|
||||
case VKRRenderPassAction::KEEP:
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
break;
|
||||
case VKRRenderPassAction::DONT_CARE:
|
||||
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
break;
|
||||
}
|
||||
for (int color = 0; color < 3; color++) {
|
||||
switch ((VKRRenderPassAction)color) {
|
||||
case VKRRenderPassAction::CLEAR: attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; break;
|
||||
case VKRRenderPassAction::KEEP: attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; break;
|
||||
case VKRRenderPassAction::DONT_CARE: attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; break;
|
||||
}
|
||||
int index = RPIndex((VKRRenderPassAction)color, (VKRRenderPassAction)depth);
|
||||
vkCreateRenderPass(vulkan_->GetDevice(), &rp, nullptr, &renderPasses_[index]);
|
||||
}
|
||||
}
|
||||
VkResult res = vkCreateRenderPass(vulkan_->GetDevice(), &rp, nullptr, &pass);
|
||||
_assert_(res == VK_SUCCESS);
|
||||
renderPasses_.Insert(key, pass);
|
||||
return pass;
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, const std::vector<VKRStep *> &steps) {
|
||||
|
@ -596,7 +610,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step
|
|||
fb->depth.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
|
||||
renderPass = renderPasses_[RPIndex(step.render.color, step.render.depthStencil)];
|
||||
renderPass = GetRenderPass(step.render.color, step.render.depthStencil, step.render.depthStencil);
|
||||
if (step.render.color == VKRRenderPassAction::CLEAR) {
|
||||
Uint8x4ToFloat4(clearVal[0].color.float32, step.render.clearColor);
|
||||
numClearVals = 1;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
|
||||
#include "Common/Hashmaps.h"
|
||||
#include "Common/Vulkan/VulkanContext.h"
|
||||
#include "math/dataconv.h"
|
||||
#include "thin3d/DataFormat.h"
|
||||
|
@ -87,7 +88,7 @@ enum class VKRStepType : uint8_t {
|
|||
READBACK_IMAGE,
|
||||
};
|
||||
|
||||
enum class VKRRenderPassAction {
|
||||
enum class VKRRenderPassAction : uint8_t {
|
||||
DONT_CARE,
|
||||
CLEAR,
|
||||
KEEP,
|
||||
|
@ -144,7 +145,7 @@ struct VKRStep {
|
|||
|
||||
class VulkanQueueRunner {
|
||||
public:
|
||||
VulkanQueueRunner(VulkanContext *vulkan) : vulkan_(vulkan) {}
|
||||
VulkanQueueRunner(VulkanContext *vulkan) : vulkan_(vulkan), renderPasses_(16) {}
|
||||
void SetBackbuffer(VkFramebuffer fb, VkImage img) {
|
||||
backbuffer_ = fb;
|
||||
backbufferImage_ = img;
|
||||
|
@ -158,9 +159,7 @@ public:
|
|||
VkRenderPass GetBackbufferRenderPass() const {
|
||||
return backbufferRenderPass_;
|
||||
}
|
||||
VkRenderPass GetRenderPass(int i) const {
|
||||
return renderPasses_[i];
|
||||
}
|
||||
VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction);
|
||||
|
||||
inline int RPIndex(VKRRenderPassAction color, VKRRenderPassAction depth) {
|
||||
return (int)depth * 3 + (int)color;
|
||||
|
@ -170,7 +169,6 @@ public:
|
|||
|
||||
private:
|
||||
void InitBackbufferRenderPass();
|
||||
void InitRenderpasses();
|
||||
|
||||
void PerformBindFramebufferAsRenderTarget(const VKRStep &pass, VkCommandBuffer cmd);
|
||||
void PerformRenderPass(const VKRStep &pass, VkCommandBuffer cmd);
|
||||
|
@ -197,9 +195,16 @@ private:
|
|||
VkFramebuffer curFramebuffer_ = VK_NULL_HANDLE;
|
||||
|
||||
VkRenderPass backbufferRenderPass_ = VK_NULL_HANDLE;
|
||||
|
||||
struct RPKey {
|
||||
VKRRenderPassAction colorAction;
|
||||
VKRRenderPassAction depthAction;
|
||||
VKRRenderPassAction stencilAction;
|
||||
};
|
||||
|
||||
// Renderpasses, all combinations of preserving or clearing or dont-care-ing fb contents.
|
||||
// TODO: Create these on demand.
|
||||
VkRenderPass renderPasses_[9]{};
|
||||
DenseHashMap<RPKey, VkRenderPass, (VkRenderPass)VK_NULL_HANDLE> renderPasses_;
|
||||
|
||||
// Readback buffer. Currently we only support synchronous readback, so we only really need one.
|
||||
// We size it generously.
|
||||
|
|
|
@ -194,15 +194,15 @@ public:
|
|||
|
||||
VkCommandBuffer GetInitCmd();
|
||||
|
||||
VkRenderPass GetRenderPass(int pass) const {
|
||||
return queueRunner_.GetRenderPass(pass);
|
||||
VkRenderPass GetRenderPass(VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction) {
|
||||
return queueRunner_.GetRenderPass(colorLoadAction, depthLoadAction, stencilLoadAction);
|
||||
}
|
||||
VkRenderPass GetBackbufferRenderPass() const {
|
||||
VkRenderPass GetBackbufferRenderPass() {
|
||||
return queueRunner_.GetBackbufferRenderPass();
|
||||
}
|
||||
VkRenderPass GetCompatibleRenderPass() const {
|
||||
VkRenderPass GetCompatibleRenderPass() {
|
||||
if (curRenderStep_ && curRenderStep_->render.framebuffer != nullptr) {
|
||||
return queueRunner_.GetRenderPass(0);
|
||||
return queueRunner_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR);
|
||||
} else {
|
||||
return queueRunner_.GetBackbufferRenderPass();
|
||||
}
|
||||
|
|
|
@ -532,6 +532,7 @@ enum class RPAction {
|
|||
struct RenderPassInfo {
|
||||
RPAction color;
|
||||
RPAction depth;
|
||||
RPAction stencil;
|
||||
uint32_t clearColor;
|
||||
float clearDepth;
|
||||
uint8_t clearStencil;
|
||||
|
|
|
@ -1460,8 +1460,15 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren
|
|||
Uint8x4ToFloat4(cv, rp.clearColor);
|
||||
context_->ClearRenderTargetView(curRenderTargetView_, cv);
|
||||
}
|
||||
if (rp.depth == RPAction::CLEAR && curDepthStencilView_) {
|
||||
context_->ClearDepthStencilView(curDepthStencilView_, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, rp.clearDepth, rp.clearStencil);
|
||||
int mask = 0;
|
||||
if (rp.depth == RPAction::CLEAR) {
|
||||
mask |= D3D11_CLEAR_DEPTH;
|
||||
}
|
||||
if (rp.stencil == RPAction::CLEAR) {
|
||||
mask |= D3D11_CLEAR_STENCIL;
|
||||
}
|
||||
if (mask && curDepthStencilView_) {
|
||||
context_->ClearDepthStencilView(curDepthStencilView_, mask, rp.clearDepth, rp.clearStencil);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1079,7 +1079,10 @@ void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPa
|
|||
clearFlags |= D3DCLEAR_TARGET;
|
||||
}
|
||||
if (rp.depth == RPAction::CLEAR) {
|
||||
clearFlags |= D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL;
|
||||
clearFlags |= D3DCLEAR_ZBUFFER;
|
||||
}
|
||||
if (rp.stencil == RPAction::CLEAR) {
|
||||
clearFlags |= D3DCLEAR_STENCIL;
|
||||
}
|
||||
if (clearFlags) {
|
||||
dxstate.scissorTest.force(false);
|
||||
|
|
|
@ -1661,9 +1661,12 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render
|
|||
#else
|
||||
glClearDepth(rp.clearDepth);
|
||||
#endif
|
||||
glClearStencil(rp.clearStencil);
|
||||
clearFlags |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
clearFlags |= GL_DEPTH_BUFFER_BIT;
|
||||
glstate.depthWrite.force(GL_TRUE);
|
||||
}
|
||||
if (rp.stencil == RPAction::CLEAR) {
|
||||
glClearStencil(rp.clearStencil);
|
||||
clearFlags |= GL_STENCIL_BUFFER_BIT;
|
||||
glstate.stencilFunc.force(GL_ALWAYS, 0, 0);
|
||||
glstate.stencilMask.force(0xFF);
|
||||
}
|
||||
|
@ -1677,6 +1680,8 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render
|
|||
}
|
||||
if (rp.depth == RPAction::CLEAR) {
|
||||
glstate.depthWrite.restore();
|
||||
}
|
||||
if (rp.stencil == RPAction::CLEAR) {
|
||||
glstate.stencilFunc.restore();
|
||||
glstate.stencilMask.restore();
|
||||
}
|
||||
|
|
|
@ -462,7 +462,7 @@ public:
|
|||
switch (obj) {
|
||||
case NativeObject::FRAMEBUFFER_RENDERPASS:
|
||||
// Return a representative renderpass.
|
||||
return (uintptr_t)renderManager_.GetRenderPass(0);
|
||||
return (uintptr_t)renderManager_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR);
|
||||
case NativeObject::BACKBUFFER_RENDERPASS:
|
||||
return (uintptr_t)renderManager_.GetBackbufferRenderPass();
|
||||
case NativeObject::COMPATIBLE_RENDERPASS:
|
||||
|
@ -1295,7 +1295,7 @@ private:
|
|||
|
||||
Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
VkCommandBuffer cmd = renderManager_.GetInitCmd();
|
||||
VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetRenderPass(0), desc.width, desc.height);
|
||||
VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR), desc.width, desc.height);
|
||||
return new VKFramebuffer(vkrfb);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ void UIScreen::preRender() {
|
|||
}
|
||||
draw->BeginFrame();
|
||||
// Bind and clear the back buffer
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 });
|
||||
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 });
|
||||
|
||||
Draw::Viewport viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue