From 02a3ebcb8a14d5fe0d1a4d72210acadf754e86bc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 9 Sep 2014 01:03:08 -0700 Subject: [PATCH] d3d: Add vertex full alpha detection. --- GPU/Directx9/TransformPipelineDX9.cpp | 19 ++++++++++++++ GPU/Directx9/TransformPipelineDX9.h | 9 +++++-- GPU/Directx9/VertexDecoderDX9.cpp | 36 +++++++++++++++------------ 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/GPU/Directx9/TransformPipelineDX9.cpp b/GPU/Directx9/TransformPipelineDX9.cpp index 3d97f03b88..ebf3cc3986 100644 --- a/GPU/Directx9/TransformPipelineDX9.cpp +++ b/GPU/Directx9/TransformPipelineDX9.cpp @@ -1092,6 +1092,8 @@ void TransformDrawEngineDX9::DoFlush() { vai->numVerts = indexGen.VertexCount(); vai->prim = indexGen.Prim(); vai->maxIndex = indexGen.MaxIndex(); + vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0; + goto rotateVBO; } @@ -1167,6 +1169,7 @@ void TransformDrawEngineDX9::DoFlush() { gpuStats.numCachedDrawCalls++; useElements = vai->ebo ? true : false; gpuStats.numCachedVertsDrawn += vai->numVerts; + gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA; } vb_ = vai->vbo; ib_ = vai->ebo; @@ -1192,6 +1195,8 @@ void TransformDrawEngineDX9::DoFlush() { maxIndex = vai->maxIndex; prim = static_cast(vai->prim); + + gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA; break; } @@ -1221,6 +1226,12 @@ rotateVBO: } DEBUG_LOG(G3D, "Flush prim %i! %i verts in one go", prim, vertexCount); + bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; + if (gstate.isModeThrough()) { + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); + } else { + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); + } IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), dec_->VertexType()); @@ -1246,6 +1257,13 @@ rotateVBO: } } else { DecodeVerts(); + bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; + if (gstate.isModeThrough()) { + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); + } else { + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); + } + gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); prim = indexGen.Prim(); // Undo the strip optimization, not supported by the SW code yet. @@ -1264,6 +1282,7 @@ rotateVBO: numDrawCalls = 0; vertexCountInDrawCalls = 0; prevPrim_ = GE_PRIM_INVALID; + gstate_c.vertexFullAlpha = true; host->GPUNotifyDraw(); } diff --git a/GPU/Directx9/TransformPipelineDX9.h b/GPU/Directx9/TransformPipelineDX9.h index 05760e5e2a..5a83b8e137 100644 --- a/GPU/Directx9/TransformPipelineDX9.h +++ b/GPU/Directx9/TransformPipelineDX9.h @@ -44,6 +44,10 @@ class FramebufferManagerDX9; // DRAWN_ONCE -> death // DRAWN_RELIABLE -> death +enum { + VAI_FLAG_VERTEXFULLALPHA = 1, +}; + // Don't bother storing information about draws smaller than this. enum { @@ -64,8 +68,10 @@ public: lastFrame = gpuStats.numFlips; numVerts = 0; drawsUntilNextFullHash = 0; + flags = 0; } ~VertexArrayInfoDX9(); + enum Status { VAI_NEW, VAI_HASHING, @@ -80,7 +86,6 @@ public: LPDIRECT3DVERTEXBUFFER9 vbo; LPDIRECT3DINDEXBUFFER9 ebo; - // Precalculated parameter for drawRangeElements u16 numVerts; u16 maxIndex; @@ -92,9 +97,9 @@ public: int numFrames; int lastFrame; // So that we can forget. u16 drawsUntilNextFullHash; + u8 flags; }; - // Handles transform, lighting and drawing. class TransformDrawEngineDX9 { public: diff --git a/GPU/Directx9/VertexDecoderDX9.cpp b/GPU/Directx9/VertexDecoderDX9.cpp index 4db47dcb89..44e3f04eb5 100644 --- a/GPU/Directx9/VertexDecoderDX9.cpp +++ b/GPU/Directx9/VertexDecoderDX9.cpp @@ -231,6 +231,7 @@ void VertexDecoderDX9::Step_Color565() const c[1] = Convert6To8((cdata>>5) & 0x3f); c[2] = Convert5To8((cdata>>11) & 0x1f); c[3] = 255; + // Always full alpha. } void VertexDecoderDX9::Step_Color5551() const @@ -241,6 +242,7 @@ void VertexDecoderDX9::Step_Color5551() const c[1] = Convert5To8((cdata>>5) & 0x1f); c[2] = Convert5To8((cdata>>10) & 0x1f); c[3] = (cdata >> 15) ? 255 : 0; + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] != 0; } void VertexDecoderDX9::Step_Color4444() const @@ -251,6 +253,7 @@ void VertexDecoderDX9::Step_Color4444() const c[1] = Convert4To8((cdata >> (4)) & 0xF); c[2] = Convert4To8((cdata >> (8)) & 0xF); c[3] = Convert4To8((cdata >> (12)) & 0xF); + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] == 255; } void VertexDecoderDX9::Step_Color8888() const @@ -261,6 +264,7 @@ void VertexDecoderDX9::Step_Color8888() const c[1] = cdata[1]; c[2] = cdata[2]; c[3] = cdata[3]; + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] == 255; } void VertexDecoderDX9::Step_Color565Morph() const @@ -270,16 +274,16 @@ void VertexDecoderDX9::Step_Color565Morph() const { float w = gstate_c.morphWeights[n]; u16 cdata = (u16)(*(u16_le*)(ptr_ + onesize_*n + coloff)); - col[0] += w * (cdata & 0x1f) * (255.0f / 31.0f); col[1] += w * ((cdata>>5) & 0x3f) * (255.0f / 63.0f); col[2] += w * ((cdata>>11) & 0x1f) * (255.0f / 31.0f); } u8 *c = decoded_ + decFmt.c0off; - c[0] = (u8)col[0]; - c[1] = (u8)col[1]; - c[2] = (u8)col[2]; + for (int i = 0; i < 3; i++) { + c[i] = clamp_u8((int)col[i]); + } c[3] = 255; + // Always full alpha. } void VertexDecoderDX9::Step_Color5551Morph() const @@ -295,10 +299,10 @@ void VertexDecoderDX9::Step_Color5551Morph() const col[3] += w * ((cdata>>15) ? 255.0f : 0.0f); } u8 *c = decoded_ + decFmt.c0off; - c[0] = (u8)col[0]; - c[1] = (u8)col[1]; - c[2] = (u8)col[2]; - c[3] = (u8)col[3]; + for (int i = 0; i < 4; i++) { + c[i] = clamp_u8((int)col[i]); + } + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] == 255; } void VertexDecoderDX9::Step_Color4444Morph() const @@ -312,10 +316,10 @@ void VertexDecoderDX9::Step_Color4444Morph() const col[j] += w * ((cdata >> (j * 4)) & 0xF) * (255.0f / 15.0f); } u8 *c = decoded_ + decFmt.c0off; - c[0] = (u8)col[0]; - c[1] = (u8)col[1]; - c[2] = (u8)col[2]; - c[3] = (u8)col[3]; + for (int i = 0; i < 4; i++) { + c[i] = clamp_u8((int)col[i]); + } + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] == 255; } void VertexDecoderDX9::Step_Color8888Morph() const @@ -329,10 +333,10 @@ void VertexDecoderDX9::Step_Color8888Morph() const col[j] += w * cdata[j]; } u8 *c = decoded_ + decFmt.c0off; - c[0] = (u8)col[0]; - c[1] = (u8)col[1]; - c[2] = (u8)col[2]; - c[3] = (u8)col[3]; + for (int i = 0; i < 4; i++) { + c[i] = clamp_u8((int)col[i]); + } + gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] == 255; } void VertexDecoderDX9::Step_NormalS8() const