From 5987c355d3c4ef85f96f16593a918ce7cd72facc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 5 Aug 2022 15:40:31 +0200 Subject: [PATCH] D3D9: Fix a lot of stuff --- Common/GPU/D3D9/thin3d_d3d9.cpp | 36 +++++++++++++++---------------- GPU/Common/DepalettizeCommon.cpp | 2 -- GPU/Common/TextureCacheCommon.cpp | 1 - GPU/Directx9/StateMappingDX9.cpp | 26 +++++++++++++--------- GPU/Directx9/TextureCacheDX9.h | 2 +- 5 files changed, 35 insertions(+), 32 deletions(-) diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 27b933e988..8c3607b670 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -112,19 +112,6 @@ static const D3DSTENCILOP stencilOpToD3D9[] = { D3DSTENCILOP_DECR, }; -static const int primCountDivisor[] = { - 1, - 2, - 3, - 3, - 3, - 1, - 1, - 1, - 1, - 1, -}; - D3DFORMAT FormatToD3DFMT(DataFormat fmt) { switch (fmt) { case DataFormat::R8G8B8A8_UNORM: return D3DFMT_A8R8G8B8; @@ -278,7 +265,6 @@ public: D3D9ShaderModule *pshader; D3DPRIMITIVETYPE prim; - int primDivisor; AutoRef inputLayout; AutoRef depthStencil; AutoRef blend; @@ -731,7 +717,6 @@ Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc) { } } pipeline->prim = primToD3D9[(int)desc.prim]; - pipeline->primDivisor = primCountDivisor[(int)desc.prim]; pipeline->depthStencil = (D3D9DepthStencilState *)desc.depthStencil; pipeline->blend = (D3D9BlendState *)desc.blend; pipeline->raster = (D3D9RasterState *)desc.raster; @@ -988,12 +973,26 @@ void D3D9Context::ApplyDynamicState() { } } +static const int D3DPRIMITIVEVERTEXCOUNT[8][2] = { + {0, 0}, // invalid + {1, 0}, // 1 = D3DPT_POINTLIST, + {2, 0}, // 2 = D3DPT_LINELIST, + {2, 1}, // 3 = D3DPT_LINESTRIP, + {3, 0}, // 4 = D3DPT_TRIANGLELIST, + {1, 2}, // 5 = D3DPT_TRIANGLESTRIP, + {1, 2}, // 6 = D3DPT_TRIANGLEFAN, +}; + +inline int D3DPrimCount(D3DPRIMITIVETYPE prim, int size) { + return (size / D3DPRIMITIVEVERTEXCOUNT[prim][0]) - D3DPRIMITIVEVERTEXCOUNT[prim][1]; +} + void D3D9Context::Draw(int vertexCount, int offset) { device_->SetStreamSource(0, curVBuffers_[0]->vbuffer_, curVBufferOffsets_[0], curPipeline_->inputLayout->GetStride(0)); curPipeline_->inputLayout->Apply(device_); curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); ApplyDynamicState(); - device_->DrawPrimitive(curPipeline_->prim, offset, vertexCount / 3); + device_->DrawPrimitive(curPipeline_->prim, offset, D3DPrimCount(curPipeline_->prim, vertexCount)); } void D3D9Context::DrawIndexed(int vertexCount, int offset) { @@ -1002,14 +1001,15 @@ void D3D9Context::DrawIndexed(int vertexCount, int offset) { ApplyDynamicState(); device_->SetStreamSource(0, curVBuffers_[0]->vbuffer_, curVBufferOffsets_[0], curPipeline_->inputLayout->GetStride(0)); device_->SetIndices(curIBuffer_->ibuffer_); - device_->DrawIndexedPrimitive(curPipeline_->prim, 0, 0, vertexCount, offset, vertexCount / curPipeline_->primDivisor); + device_->DrawIndexedPrimitive(curPipeline_->prim, 0, 0, vertexCount, offset, D3DPrimCount(curPipeline_->prim, vertexCount)); } void D3D9Context::DrawUP(const void *vdata, int vertexCount) { curPipeline_->inputLayout->Apply(device_); curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); ApplyDynamicState(); - device_->DrawPrimitiveUP(curPipeline_->prim, vertexCount / 3, vdata, curPipeline_->inputLayout->GetStride(0)); + + device_->DrawPrimitiveUP(curPipeline_->prim, D3DPrimCount(curPipeline_->prim, vertexCount), vdata, curPipeline_->inputLayout->GetStride(0)); } static uint32_t SwapRB(uint32_t c) { diff --git a/GPU/Common/DepalettizeCommon.cpp b/GPU/Common/DepalettizeCommon.cpp index 8f565ea3e6..9da13d38ea 100644 --- a/GPU/Common/DepalettizeCommon.cpp +++ b/GPU/Common/DepalettizeCommon.cpp @@ -96,8 +96,6 @@ Draw::Texture *DepalShaderCache::GetClutTexture(GEPaletteFormat clutFormat, cons case GEPaletteFormat::GE_CMODE_32BIT_ABGR8888: desc.initData.push_back((const uint8_t *)rawClut); break; - - // TODO: The 16-bit CLUTs might be pre-reversed for OpenGL! :/ case GEPaletteFormat::GE_CMODE_16BIT_BGR5650: ConvertRGBA5551ToRGBA8888((u32 *)convTemp, (const u16 *)rawClut, texturePixels); desc.initData.push_back(convTemp); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 62f3f17c76..215589b934 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1849,7 +1849,6 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer uint32_t clutMode = gstate.clutformat & 0xFFFFFF; bool need_depalettize = IsClutFormat(texFormat); - bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS); bool depth = channel == NOTIFY_FB_DEPTH; bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer && !depth && !gstate_c.curTextureIs3D; diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 88d7f24342..47dfe6e86f 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -100,16 +100,23 @@ void DrawEngineDX9::ApplyDrawState(int prim) { return; } - if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { - textureCache_->SetTexture(); - gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); - } else if (gstate.getTextureAddress(0) == ((gstate.getFrameBufRawAddress() | 0x04000000) & 0x3FFFFFFF)) { - // This catches the case of clearing a texture. - gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); - } + // At this point, we know if the vertices are full alpha or not. + // TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? + if (!gstate.isModeClear()) { + textureCache_->ApplyTexture(); - // Start profiling here to skip SetTexture which is already accounted for - PROFILE_THIS_SCOPE("applydrawstate"); + if (fboTexNeedsBind_) { + // Note that this is positions, not UVs, that we need the copy from. + framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY); + // If we are rendering at a higher resolution, linear is probably best for the dest color. + device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + fboTexBound_ = true; + fboTexNeedsBind_ = false; + } + + // TODO: Test texture? + } bool useBufferedRendering = framebufferManager_->UseBufferedRendering(); @@ -290,7 +297,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) { void DrawEngineDX9::ApplyDrawStateLate() { // At this point, we know if the vertices are full alpha or not. // TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? - } } diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 308b46d4f9..925d28982a 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -54,7 +54,7 @@ protected: void BindAsClutTexture(Draw::Texture *tex) override; private: - void ApplySamplingParams(const SamplerCacheKey &key); + void ApplySamplingParams(const SamplerCacheKey &key) override; D3DFORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; static CheckAlphaResult CheckAlpha(const u32 *pixelData, u32 dstFmt, int w);