mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-10-07 02:43:32 +00:00
More explicit invalidation of any cached state in Thin3D. Fixes #13307
This commit is contained in:
parent
e8779fdc88
commit
506a86300d
@ -539,8 +539,7 @@ void PresentationCommon::UpdateUniforms(bool hasVideo) {
|
||||
}
|
||||
|
||||
void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1) {
|
||||
// Make sure Direct3D 11 clears state, since we set shaders outside Draw.
|
||||
draw_->BindPipeline(nullptr);
|
||||
draw_->InvalidateCachedState();
|
||||
|
||||
// TODO: If shader objects have been created by now, we might have received errors.
|
||||
// GLES can have the shader fail later, shader->failed / shader->error.
|
||||
@ -649,6 +648,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
|
||||
Draw::Framebuffer *postShaderFramebuffer = postShaderFramebuffers_[i];
|
||||
|
||||
draw_->BindFramebufferAsRenderTarget(postShaderFramebuffer, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "PostShader");
|
||||
|
||||
if (usePostShaderOutput) {
|
||||
draw_->BindFramebufferAsTexture(postShaderFramebuffers_[i - 1], 0, Draw::FB_COLOR_BIT, 0);
|
||||
} else {
|
||||
|
@ -119,7 +119,6 @@ GPU_D3D11::~GPU_D3D11() {
|
||||
shaderManagerD3D11_->ClearShaders();
|
||||
delete shaderManagerD3D11_;
|
||||
delete textureCacheD3D11_;
|
||||
draw_->BindPipeline(nullptr);
|
||||
stockD3D11.Destroy();
|
||||
}
|
||||
|
||||
@ -233,8 +232,8 @@ void GPU_D3D11::ReapplyGfxState() {
|
||||
}
|
||||
|
||||
void GPU_D3D11::EndHostFrame() {
|
||||
// Tell the DrawContext that it's time to reset everything.
|
||||
draw_->BindPipeline(nullptr);
|
||||
// Probably not really necessary.
|
||||
draw_->InvalidateCachedState();
|
||||
}
|
||||
|
||||
void GPU_D3D11::BeginFrame() {
|
||||
|
@ -389,7 +389,9 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra
|
||||
|
||||
Draw::Framebuffer *depalFBO = framebufferManagerD3D11_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888);
|
||||
shaderManager_->DirtyLastShader();
|
||||
draw_->BindPipeline(nullptr);
|
||||
|
||||
// Not sure why or if we need this here - we're not about to actually draw using draw_, just use its framebuffer binds.
|
||||
draw_->InvalidateCachedState();
|
||||
|
||||
float xoff = -0.5f / framebuffer->renderWidth;
|
||||
float yoff = 0.5f / framebuffer->renderHeight;
|
||||
|
@ -646,7 +646,11 @@ public:
|
||||
BindTextures(stage, 1, textures);
|
||||
} // from sampler 0 and upwards
|
||||
|
||||
// Call this with nullptr to signal that you're done with the stuff you've bound, like textures and samplers and stuff.
|
||||
// Clear state cached within thin3d. Must be called after directly calling API functions.
|
||||
// Note that framebuffer state (which framebuffer is bounds) may not be cached.
|
||||
// Must not actually perform any API calls itself since this can be called when no framebuffer is bound for rendering.
|
||||
virtual void InvalidateCachedState() = 0;
|
||||
|
||||
virtual void BindPipeline(Pipeline *pipeline) = 0;
|
||||
|
||||
virtual void Draw(int vertexCount, int offset) = 0;
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
|
||||
void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override;
|
||||
|
||||
void InvalidateCachedState() override;
|
||||
|
||||
void BindTextures(int start, int count, Texture **textures) override;
|
||||
void BindSamplerStates(int start, int count, SamplerState **states) override;
|
||||
void BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) override;
|
||||
@ -1019,19 +1021,20 @@ void D3D11DrawContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
|
||||
context_->Unmap(curPipeline_->dynamicUniforms, 0);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindPipeline(Pipeline *pipeline) {
|
||||
if (pipeline == nullptr) {
|
||||
// This is a signal to forget all our caching.
|
||||
curBlend_ = nullptr;
|
||||
curDepth_ = nullptr;
|
||||
curRaster_ = nullptr;
|
||||
curPS_ = nullptr;
|
||||
curVS_ = nullptr;
|
||||
curGS_ = nullptr;
|
||||
curInputLayout_ = nullptr;
|
||||
curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
}
|
||||
void D3D11DrawContext::InvalidateCachedState() {
|
||||
// This is a signal to forget all our state caching.
|
||||
curBlend_ = nullptr;
|
||||
curDepth_ = nullptr;
|
||||
curRaster_ = nullptr;
|
||||
curPS_ = nullptr;
|
||||
curVS_ = nullptr;
|
||||
curGS_ = nullptr;
|
||||
curInputLayout_ = nullptr;
|
||||
curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
curPipeline_ = nullptr;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BindPipeline(Pipeline *pipeline) {
|
||||
D3D11Pipeline *dPipeline = (D3D11Pipeline *)pipeline;
|
||||
if (curPipeline_ == dPipeline)
|
||||
return;
|
||||
|
@ -606,6 +606,8 @@ public:
|
||||
return stepId_;
|
||||
}
|
||||
|
||||
void InvalidateCachedState() override;
|
||||
|
||||
private:
|
||||
LPDIRECT3D9 d3d_;
|
||||
LPDIRECT3D9EX d3dEx_;
|
||||
@ -631,6 +633,10 @@ private:
|
||||
bool supportsINTZ = false;
|
||||
};
|
||||
|
||||
void D3D9Context::InvalidateCachedState() {
|
||||
curPipeline_ = nullptr;
|
||||
}
|
||||
|
||||
#define FB_DIV 1
|
||||
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')))
|
||||
|
||||
|
@ -481,9 +481,10 @@ public:
|
||||
return renderManager_.GetCurrentStepId();
|
||||
}
|
||||
|
||||
void InvalidateCachedState() override;
|
||||
|
||||
private:
|
||||
void ApplySamplers();
|
||||
void Unbind();
|
||||
|
||||
GLRenderManager renderManager_;
|
||||
|
||||
@ -612,14 +613,14 @@ void OpenGLContext::BeginFrame() {
|
||||
}
|
||||
|
||||
void OpenGLContext::EndFrame() {
|
||||
Unbind();
|
||||
|
||||
FrameData &frameData = frameData_[renderManager_.GetCurFrame()];
|
||||
renderManager_.EndPushBuffer(frameData.push); // upload the data!
|
||||
renderManager_.Finish();
|
||||
|
||||
InvalidateCachedState();
|
||||
}
|
||||
|
||||
void OpenGLContext::Unbind() {
|
||||
void OpenGLContext::InvalidateCachedState() {
|
||||
// Unbind stuff.
|
||||
for (auto &texture : boundTextures_) {
|
||||
texture = nullptr;
|
||||
@ -627,9 +628,6 @@ void OpenGLContext::Unbind() {
|
||||
for (auto &sampler : boundSamplers_) {
|
||||
sampler = nullptr;
|
||||
}
|
||||
for (int i = 0; i < ARRAY_SIZE(boundTextures_); i++) {
|
||||
renderManager_.BindTexture(i, nullptr);
|
||||
}
|
||||
curPipeline_ = nullptr;
|
||||
}
|
||||
|
||||
@ -1107,15 +1105,13 @@ bool OpenGLPipeline::LinkShaders() {
|
||||
|
||||
void OpenGLContext::BindPipeline(Pipeline *pipeline) {
|
||||
curPipeline_ = (OpenGLPipeline *)pipeline;
|
||||
if (curPipeline_) {
|
||||
curPipeline_->blend->Apply(&renderManager_);
|
||||
curPipeline_->depthStencil->Apply(&renderManager_, stencilRef_);
|
||||
curPipeline_->raster->Apply(&renderManager_);
|
||||
renderManager_.BindProgram(curPipeline_->program_);
|
||||
} else {
|
||||
// Wipe bound textures and samplers.
|
||||
Unbind();
|
||||
if (!curPipeline_) {
|
||||
return;
|
||||
}
|
||||
curPipeline_->blend->Apply(&renderManager_);
|
||||
curPipeline_->depthStencil->Apply(&renderManager_, stencilRef_);
|
||||
curPipeline_->raster->Apply(&renderManager_);
|
||||
renderManager_.BindProgram(curPipeline_->program_);
|
||||
}
|
||||
|
||||
void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
|
||||
|
@ -408,10 +408,6 @@ public:
|
||||
|
||||
void BindPipeline(Pipeline *pipeline) override {
|
||||
curPipeline_ = (VKPipeline *)pipeline;
|
||||
|
||||
if (!pipeline) {
|
||||
UnbindBoundState();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make VKBuffers proper buffers, and do a proper binding model. This is just silly.
|
||||
@ -497,8 +493,9 @@ public:
|
||||
return renderManager_.GetCurrentStepId();
|
||||
}
|
||||
|
||||
void InvalidateCachedState() override;
|
||||
|
||||
private:
|
||||
void UnbindBoundState();
|
||||
|
||||
VulkanTexture *GetNullTexture();
|
||||
VulkanContext *vulkan_ = nullptr;
|
||||
@ -923,10 +920,10 @@ void VKContext::EndFrame() {
|
||||
push_ = nullptr;
|
||||
|
||||
// Unbind stuff, to avoid accidentally relying on it across frames (and provide some protection against forgotten unbinds of deleted things).
|
||||
UnbindBoundState();
|
||||
InvalidateCachedState();
|
||||
}
|
||||
|
||||
void VKContext::UnbindBoundState() {
|
||||
void VKContext::InvalidateCachedState() {
|
||||
curPipeline_ = nullptr;
|
||||
|
||||
for (auto &view : boundImageView_) {
|
||||
|
Loading…
Reference in New Issue
Block a user