mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
Merge pull request #13760 from hrydgard/fix-dirt-graphics
Fix car lighting issues in DiRT 2.
This commit is contained in:
19 files changed
+82
-71
No files matched your search
@@ -35,6 +35,7 @@ class D3D11BlendState;
|
||||
class D3D11DepthStencilState;
|
||||
class D3D11SamplerState;
|
||||
class D3D11RasterState;
|
||||
class D3D11Framebuffer;
|
||||
|
||||
class D3D11DrawContext : public DrawContext {
|
||||
public:
|
||||
@@ -71,7 +72,9 @@ public:
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override;
|
||||
// color must be 0, for now.
|
||||
Framebuffer *GetCurrentRenderTarget() override {
|
||||
return curRenderTarget_;
|
||||
}
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override;
|
||||
@@ -182,6 +185,7 @@ private:
|
||||
ID3D11Texture2D *bbDepthStencilTex_ = nullptr;
|
||||
ID3D11DepthStencilView *bbDepthStencilView_ = nullptr;
|
||||
|
||||
Framebuffer *curRenderTarget_ = nullptr;
|
||||
ID3D11RenderTargetView *curRenderTargetView_ = nullptr;
|
||||
ID3D11DepthStencilView *curDepthStencilView_ = nullptr;
|
||||
// Needed to rotate stencil/viewport rectangles properly
|
||||
@@ -1585,6 +1589,7 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren
|
||||
curRTWidth_ = fb->Width();
|
||||
curRTHeight_ = fb->Height();
|
||||
}
|
||||
curRenderTarget_ = fb;
|
||||
} else {
|
||||
if (curRenderTargetView_ == bbRenderTargetView_ && curDepthStencilView_ == bbDepthStencilView_) {
|
||||
// No need to switch, but let's fallthrough to clear!
|
||||
@@ -1595,6 +1600,7 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren
|
||||
curRTWidth_ = bbWidth_;
|
||||
curRTHeight_ = bbHeight_;
|
||||
}
|
||||
curRenderTarget_ = nullptr;
|
||||
}
|
||||
if (rp.color == RPAction::CLEAR && curRenderTargetView_) {
|
||||
float cv[4]{};
|
||||
@@ -1616,7 +1622,6 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren
|
||||
stepId_++;
|
||||
}
|
||||
|
||||
// color must be 0, for now.
|
||||
void D3D11DrawContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {
|
||||
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
|
||||
switch (channelBit) {
|
||||
|
||||
@@ -520,7 +520,9 @@ public:
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override;
|
||||
// color must be 0, for now.
|
||||
Framebuffer *GetCurrentRenderTarget() override {
|
||||
return curRenderTarget_;
|
||||
}
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) override;
|
||||
@@ -615,6 +617,7 @@ private:
|
||||
int curVBufferOffsets_[4]{};
|
||||
D3D9Buffer *curIBuffer_ = nullptr;
|
||||
int curIBufferOffset_ = 0;
|
||||
Framebuffer *curRenderTarget_ = nullptr;
|
||||
|
||||
// Framebuffer state
|
||||
LPDIRECT3DSURFACE9 deviceRTsurf = 0;
|
||||
@@ -1139,9 +1142,11 @@ void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPa
|
||||
D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo;
|
||||
device_->SetRenderTarget(0, fb->surf);
|
||||
device_->SetDepthStencilSurface(fb->depthstencil);
|
||||
curRenderTarget_ = fb;
|
||||
} else {
|
||||
device_->SetRenderTarget(0, deviceRTsurf);
|
||||
device_->SetDepthStencilSurface(deviceDSsurf);
|
||||
curRenderTarget_ = nullptr;
|
||||
}
|
||||
|
||||
int clearFlags = 0;
|
||||
|
||||
@@ -361,7 +361,9 @@ public:
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override;
|
||||
// color must be 0, for now.
|
||||
Framebuffer *GetCurrentRenderTarget() override {
|
||||
return curRenderTarget_;
|
||||
}
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
|
||||
void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override;
|
||||
@@ -487,6 +489,7 @@ private:
|
||||
int curVBufferOffsets_[4]{};
|
||||
OpenGLBuffer *curIBuffer_ = nullptr;
|
||||
int curIBufferOffset_ = 0;
|
||||
Framebuffer *curRenderTarget_ = nullptr;
|
||||
|
||||
uint8_t stencilRef_ = 0;
|
||||
|
||||
@@ -1320,6 +1323,7 @@ void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Render
|
||||
GLRRenderPassAction stencil = (GLRRenderPassAction)rp.stencil;
|
||||
|
||||
renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer_ : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil, tag);
|
||||
curRenderTarget_ = fb;
|
||||
}
|
||||
|
||||
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) {
|
||||
|
||||
@@ -1234,12 +1234,12 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
|
||||
|
||||
VKRFramebuffer *fb = step.render.framebuffer;
|
||||
|
||||
VkPipeline lastPipeline = VK_NULL_HANDLE;
|
||||
|
||||
auto &commands = step.commands;
|
||||
|
||||
// We can do a little bit of state tracking here to eliminate some calls into the driver.
|
||||
// The stencil ones are very commonly mostly redundant so let's eliminate them where possible.
|
||||
// Might also want to consider scissor and viewport.
|
||||
VkPipeline lastPipeline = VK_NULL_HANDLE;
|
||||
int lastStencilWriteMask = -1;
|
||||
int lastStencilCompareMask = -1;
|
||||
int lastStencilReference = -1;
|
||||
|
||||
@@ -392,7 +392,9 @@ public:
|
||||
|
||||
// These functions should be self explanatory.
|
||||
void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override;
|
||||
// color must be 0, for now.
|
||||
Framebuffer *GetCurrentRenderTarget() override {
|
||||
return curFramebuffer_;
|
||||
}
|
||||
void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override;
|
||||
|
||||
uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) override;
|
||||
@@ -517,7 +519,7 @@ private:
|
||||
VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE;
|
||||
VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE;
|
||||
VkPipelineCache pipelineCache_ = VK_NULL_HANDLE;
|
||||
VKFramebuffer *curFramebuffer_ = nullptr;
|
||||
Framebuffer *curFramebuffer_ = nullptr;
|
||||
|
||||
VkDevice device_;
|
||||
VkQueue queue_;
|
||||
@@ -1539,7 +1541,6 @@ void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPass
|
||||
curFramebuffer_ = fb;
|
||||
}
|
||||
|
||||
// color must be 0, for now.
|
||||
void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {
|
||||
VKFramebuffer *fb = (VKFramebuffer *)fbo;
|
||||
|
||||
|
||||
@@ -578,6 +578,7 @@ public:
|
||||
// These functions should be self explanatory.
|
||||
// Binding a zero render target means binding the backbuffer.
|
||||
virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0;
|
||||
virtual Framebuffer *GetCurrentRenderTarget() = 0;
|
||||
|
||||
// binding must be < MAX_TEXTURE_SLOTS (0, 1 are okay if it's 2).
|
||||
virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0;
|
||||
|
||||
@@ -471,10 +471,10 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir
|
||||
// Note: We prefer Blit ahead of Copy here, since at least on GL, Copy will always also copy stencil which we don't want. See #9740.
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT_TO_DEPTH)) {
|
||||
draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth");
|
||||
RebindFramebuffer("BlitFramebufferDepth");
|
||||
RebindFramebuffer("After BlitFramebufferDepth");
|
||||
} else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) {
|
||||
draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth");
|
||||
RebindFramebuffer("BlitFramebufferDepth");
|
||||
RebindFramebuffer("After BlitFramebufferDepth");
|
||||
}
|
||||
dst->last_frame_depth_updated = gpuStats.numFlips;
|
||||
}
|
||||
@@ -503,7 +503,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer
|
||||
if (vfbFormatChanged) {
|
||||
textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED);
|
||||
if (vfb->drawnFormat != vfb->format) {
|
||||
ReinterpretFramebufferFrom(vfb, vfb->drawnFormat);
|
||||
ReinterpretFramebuffer(vfb, vfb->drawnFormat, vfb->format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,11 +517,15 @@ void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat oldFormat) {
|
||||
void FramebufferManagerCommon::ReinterpretFramebuffer(VirtualFramebuffer *vfb, GEBufferFormat oldFormat, GEBufferFormat newFormat) {
|
||||
if (!useBufferedRendering_ || !vfb->fbo) {
|
||||
return;
|
||||
}
|
||||
|
||||
_assert_(newFormat != oldFormat);
|
||||
// The caller is responsible for updating the format.
|
||||
_assert_(newFormat == vfb->format);
|
||||
|
||||
ShaderLanguage lang = draw_->GetShaderLanguageDesc().shaderLanguage;
|
||||
|
||||
bool doReinterpret = PSP_CoreParameter().compat.flags().ReinterpretFramebuffers &&
|
||||
@@ -536,19 +540,19 @@ void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vf
|
||||
// Fixes #13717.
|
||||
if (!PSP_CoreParameter().compat.flags().ReinterpretFramebuffers) {
|
||||
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "FakeReinterpret");
|
||||
currentRenderVfb_ = vfb;
|
||||
// Need to dirty anything that has command buffer dynamic state, in case we started a new pass above.
|
||||
// Should find a way to feed that information back, maybe... Or simply correct the issue in the rendermanager.
|
||||
gstate_c.Dirty(DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE);
|
||||
|
||||
if (currentRenderVfb_ != vfb) {
|
||||
// In case ReinterpretFramebuffer was called from the texture manager.
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "After FakeReinterpret");
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GEBufferFormat newFormat = vfb->format;
|
||||
|
||||
_assert_(newFormat != oldFormat);
|
||||
|
||||
// We only reinterpret between 16 - bit formats, for now.
|
||||
if (!IsGeBufferFormat16BitColor(oldFormat) || !IsGeBufferFormat16BitColor(newFormat)) {
|
||||
// 16->32 and 32->16 will require some more specialized shaders.
|
||||
@@ -626,13 +630,16 @@ void FramebufferManagerCommon::ReinterpretFramebufferFrom(VirtualFramebuffer *vf
|
||||
|
||||
// Unbind.
|
||||
draw_->BindTexture(0, nullptr);
|
||||
RebindFramebuffer("After reinterpret");
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
textureCache_->ForgetLastTexture();
|
||||
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE);
|
||||
|
||||
if (currentRenderVfb_ != vfb) {
|
||||
// In case ReinterpretFramebuffer was called from the texture manager.
|
||||
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "After reinterpret");
|
||||
}
|
||||
delete[] vsCode;
|
||||
delete[] fsCode;
|
||||
}
|
||||
@@ -664,8 +671,9 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vfb->drawnFormat != vfb->format) {
|
||||
ReinterpretFramebufferFrom(vfb, vfb->drawnFormat);
|
||||
ReinterpretFramebuffer(vfb, vfb->drawnFormat, vfb->format);
|
||||
}
|
||||
|
||||
if (useBufferedRendering_) {
|
||||
@@ -832,10 +840,8 @@ bool FramebufferManagerCommon::BindFramebufferAsColorTexture(int stage, VirtualF
|
||||
|
||||
// currentRenderVfb_ will always be set when this is called, except from the GE debugger.
|
||||
// Let's just not bother with the copy in that case.
|
||||
bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0;
|
||||
if (GPUStepping::IsStepping()) {
|
||||
skipCopy = true;
|
||||
}
|
||||
bool skipCopy = !(flags & BINDFBCOLOR_MAY_COPY) || GPUStepping::IsStepping();
|
||||
|
||||
// Currently rendering to this framebuffer. Need to make a copy.
|
||||
if (!skipCopy && framebuffer == currentRenderVfb_) {
|
||||
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
|
||||
@@ -863,7 +869,6 @@ bool FramebufferManagerCommon::BindFramebufferAsColorTexture(int stage, VirtualF
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags) {
|
||||
@@ -989,6 +994,8 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu
|
||||
|
||||
// PresentationCommon sets all kinds of state, we can't rely on anything.
|
||||
gstate_c.Dirty(DIRTY_ALL);
|
||||
|
||||
currentRenderVfb_ = nullptr;
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb) {
|
||||
@@ -1740,10 +1747,10 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
|
||||
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp, "Blit_IntraBufferBlockTransfer");
|
||||
RebindFramebuffer("rebind after intra block transfer");
|
||||
SetColorUpdated(dstBuffer, skipDrawReason);
|
||||
return true;
|
||||
return true; // Skip the memory copy.
|
||||
} else {
|
||||
// Ignore, nothing to do. Tales of Phantasia X does this by accident.
|
||||
return true;
|
||||
return true; // Skip the memory copy.
|
||||
}
|
||||
} else {
|
||||
WARN_LOG_N_TIMES(dstnotsrc, 100, G3D, "Inter-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)",
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
// TODO: We now have the tools in thin3d to nearly eliminate the backend-specific framebuffer managers.
|
||||
// Here's a list of functionality to unify into FramebufferManagerCommon:
|
||||
// * DrawActiveTexture
|
||||
// * BlitFramebuffer
|
||||
// * StencilBuffer*.cpp
|
||||
//
|
||||
// Also, in TextureCache we should be able to unify texture-based depal.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
@@ -131,7 +139,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU
|
||||
enum BindFramebufferColorFlags {
|
||||
BINDFBCOLOR_SKIP_COPY = 0,
|
||||
BINDFBCOLOR_MAY_COPY = 1,
|
||||
BINDFBCOLOR_MAY_COPY_WITH_UV = 3,
|
||||
BINDFBCOLOR_MAY_COPY_WITH_UV = 3, // includes BINDFBCOLOR_MAY_COPY
|
||||
BINDFBCOLOR_APPLY_TEX_OFFSET = 4,
|
||||
// Used when rendering to a temporary surface (e.g. not the current render target.)
|
||||
BINDFBCOLOR_FORCE_SELF = 8,
|
||||
@@ -322,7 +330,7 @@ public:
|
||||
const std::vector<VirtualFramebuffer *> &Framebuffers() {
|
||||
return vfbs_;
|
||||
}
|
||||
void ReinterpretFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old);
|
||||
void ReinterpretFramebuffer(VirtualFramebuffer *vfb, GEBufferFormat oldFormat, GEBufferFormat newFormat);
|
||||
|
||||
protected:
|
||||
virtual void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
@@ -356,7 +364,7 @@ protected:
|
||||
void DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb);
|
||||
void FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp);
|
||||
VirtualFramebuffer *FindDownloadTempBuffer(VirtualFramebuffer *vfb);
|
||||
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0;
|
||||
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {}
|
||||
|
||||
VirtualFramebuffer *CreateRAMFramebuffer(uint32_t fbAddress, int width, int height, int stride, GEBufferFormat format);
|
||||
|
||||
|
||||
@@ -958,10 +958,9 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate)
|
||||
FramebufferMatchInfo fbInfo = candidate.match;
|
||||
|
||||
if (candidate.match.reinterpret) {
|
||||
// TODO: Kinda ugly, maybe switch direction of the call?
|
||||
GEBufferFormat oldFormat = candidate.fb->format;
|
||||
candidate.fb->format = candidate.match.reinterpretTo;
|
||||
framebufferManager_->ReinterpretFramebufferFrom(candidate.fb, oldFormat);
|
||||
framebufferManager_->ReinterpretFramebuffer(candidate.fb, oldFormat, candidate.match.reinterpretTo);
|
||||
}
|
||||
|
||||
_dbg_assert_msg_(framebuffer != nullptr, "Framebuffer must not be null.");
|
||||
|
||||
@@ -277,10 +277,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) {
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerD3D11::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void FramebufferManagerD3D11::SimpleBlit(
|
||||
Draw::Framebuffer *dest, float destX1, float destY1, float destX2, float destY2,
|
||||
Draw::Framebuffer *src, float srcX1, float srcY1, float srcX2, float srcY2, bool linearFilter) {
|
||||
|
||||
@@ -54,8 +54,6 @@ protected:
|
||||
// Used by ReadFramebufferToMemory and later framebuffer block copies
|
||||
void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) override;
|
||||
|
||||
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
|
||||
private:
|
||||
void Bind2DShader() override;
|
||||
void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
|
||||
@@ -412,7 +412,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer,
|
||||
shaderApply.Shade();
|
||||
|
||||
context_->PSSetShaderResources(0, 1, &nullTexture); // Make D3D11 validation happy. Really of no consequence since we rebind anyway.
|
||||
framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer");
|
||||
framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer");
|
||||
draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
@@ -422,8 +422,8 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer,
|
||||
gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL);
|
||||
} else {
|
||||
gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650);
|
||||
framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer");
|
||||
framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
|
||||
framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer");
|
||||
framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
|
||||
}
|
||||
|
||||
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
|
||||
@@ -259,10 +259,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
|
||||
return offscreen;
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) {
|
||||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if we recently switched from non-buffered.
|
||||
|
||||
@@ -65,8 +65,6 @@ protected:
|
||||
// Used by ReadFramebufferToMemory and later framebuffer block copies
|
||||
void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) override;
|
||||
|
||||
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
|
||||
private:
|
||||
void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) override;
|
||||
void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
|
||||
@@ -2721,6 +2721,8 @@ bool GPUCommon::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_->NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
|
||||
// TODO: What? Why would a game copy between the mirrors? This check seems entirely
|
||||
// superfluous.
|
||||
// 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) {
|
||||
|
||||
@@ -803,6 +803,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
}
|
||||
|
||||
PROFILE_THIS_SCOPE("updatestate");
|
||||
|
||||
if (textureNeedsApply) {
|
||||
textureCache_->ApplyTexture();
|
||||
textureCache_->GetVulkanHandles(imageView, sampler);
|
||||
@@ -860,8 +861,6 @@ void DrawEngineVulkan::DoFlush() {
|
||||
UpdateUBOs(frame);
|
||||
|
||||
VkDescriptorSet ds = GetOrCreateDescriptorSet(imageView, sampler, baseBuf, lightBuf, boneBuf, tess);
|
||||
{
|
||||
PROFILE_THIS_SCOPE("renderman_q");
|
||||
|
||||
const uint32_t dynamicUBOOffsets[3] = {
|
||||
baseUBOOffset, lightUBOOffset, boneUBOOffset,
|
||||
@@ -870,13 +869,13 @@ void DrawEngineVulkan::DoFlush() {
|
||||
int stride = dec_->GetDecVtxFmt().stride;
|
||||
|
||||
if (useElements) {
|
||||
if (!ibuf)
|
||||
if (!ibuf) {
|
||||
ibOffset = (uint32_t)frame->pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &ibuf);
|
||||
}
|
||||
renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16);
|
||||
} else {
|
||||
renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PROFILE_THIS_SCOPE("soft");
|
||||
// Decode to "decoded"
|
||||
|
||||
@@ -234,18 +234,6 @@ void FramebufferManagerVulkan::Bind2DShader() {
|
||||
cur2DPipeline_ = vulkan2D_->GetPipeline(rp, vsBasicTex_, fsBasicTex_);
|
||||
}
|
||||
|
||||
int FramebufferManagerVulkan::GetLineWidth() {
|
||||
if (g_Config.iInternalResolution == 0) {
|
||||
return std::max(1, (int)(renderWidth_ / 480));
|
||||
} else {
|
||||
return g_Config.iInternalResolution;
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerVulkan::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) {
|
||||
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
|
||||
// This can happen if they recently switched from non-buffered.
|
||||
|
||||
@@ -52,8 +52,6 @@ public:
|
||||
void DeviceLost() override;
|
||||
void DeviceRestore(Draw::DrawContext *draw) override;
|
||||
|
||||
int GetLineWidth();
|
||||
|
||||
bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override;
|
||||
|
||||
// If within a render pass, this will just issue a regular clear. If beginning a new render pass,
|
||||
@@ -65,7 +63,6 @@ protected:
|
||||
|
||||
// Used by ReadFramebufferToMemory and later framebuffer block copies
|
||||
void BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp, const char *tag) override;
|
||||
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
|
||||
|
||||
private:
|
||||
void InitDeviceObjects();
|
||||
|
||||
+12
-5
@@ -819,15 +819,16 @@ NPEZ00198 = true
|
||||
# This setting will go away in the near future, hopefully we can enable it
|
||||
# for all or most games.
|
||||
[ReinterpretFramebuffers]
|
||||
# Outrun 2006: Coast to Coast - issue #11358
|
||||
# Outrun 2006: Coast to Coast - issue #11358 (car reflections)
|
||||
ULES00262 = true
|
||||
ULUS10064 = true
|
||||
ULKS46087 = true
|
||||
|
||||
# Colin McRae's DiRT 2?
|
||||
# ULUS10471 = true
|
||||
# ULJM05533 = true
|
||||
# NPJH50006 = true
|
||||
# Colin McRae's DiRT 2 - issue #13012 (car lighting)
|
||||
ULUS10471 = true
|
||||
ULJM05533 = true
|
||||
NPJH50006 = true
|
||||
ULES01301 = true
|
||||
|
||||
# Ultimate Ghosts & Goblins
|
||||
ULJM05147 = true
|
||||
@@ -845,6 +846,12 @@ ULES00262 = true
|
||||
ULUS10064 = true
|
||||
ULKS46087 = true
|
||||
|
||||
# Colin McRae's DiRT 2 - issue #13012 (car lighting)
|
||||
ULUS10471 = true
|
||||
ULJM05533 = true
|
||||
NPJH50006 = true
|
||||
ULES01301 = true
|
||||
|
||||
[DoublePrecisionSinCos]
|
||||
# Hitman Reborn Battle Arena 2 (#12900)
|
||||
ULJS00218 = true
|
||||
|
||||
Reference in new issue
Block a user