From 746e7d5ff8f3479055111060023d53bcc9a7f3f8 Mon Sep 17 00:00:00 2001 From: Ced2911 Date: Wed, 4 Sep 2013 11:19:36 +0200 Subject: [PATCH] sync with gles --- GPU/Directx9/DisplayListInterpreter.cpp | 71 +++++++++++++++++-------- GPU/Directx9/Framebuffer.cpp | 40 +++++++------- GPU/Directx9/IndexGenerator.cpp | 2 +- GPU/Directx9/IndexGenerator.h | 4 +- GPU/Directx9/Spline.cpp | 53 +++++++++++------- GPU/Directx9/TextureCache.cpp | 43 ++++++--------- GPU/Directx9/TextureScaler.cpp | 2 +- GPU/Directx9/TransformPipeline.cpp | 36 +++++++------ GPU/Directx9/TransformPipeline.h | 11 ++-- GPU/Directx9/helper/fbo.cpp | 2 +- 10 files changed, 150 insertions(+), 114 deletions(-) diff --git a/GPU/Directx9/DisplayListInterpreter.cpp b/GPU/Directx9/DisplayListInterpreter.cpp index 2f9755c3d5..97039acf61 100644 --- a/GPU/Directx9/DisplayListInterpreter.cpp +++ b/GPU/Directx9/DisplayListInterpreter.cpp @@ -115,7 +115,6 @@ static const CommandTableEntry commandTable[] = { {GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE}, {GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE}, {GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE}, {GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, {GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, {GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE}, @@ -139,6 +138,7 @@ static const CommandTableEntry commandTable[] = { {GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE}, // Uniform changes + {GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE}, {GE_CMD_COLORREF, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE}, {GE_CMD_TEXENVCOLOR, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE}, @@ -425,7 +425,7 @@ void DIRECTX9_GPU::InitClearInternal() { glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); */ - pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.f, 0); + pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 0.f, 0); } dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); } @@ -602,10 +602,16 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { // when it's time to draw. As most PSP games set state redundantly ALL THE TIME, this is a huge optimization. u32 count = data & 0xFFFF; - u32 prim = data >> 16; + GEPrimitiveType prim = static_cast(data >> 16); // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. - if ((prim == GE_PRIM_LINE_STRIP || prim == GE_PRIM_LINES) && (gstate.antiAliasEnable & 1)) + + // Discard AA lines in DOA + if ((prim == GE_PRIM_LINE_STRIP) && gstate.isAntiAliasEnabled()) + break; + + // Discard AA lines in Summon Night 5 + if ((prim == GE_PRIM_LINES) && gstate.isAntiAliasEnabled() && gstate.isSkinningEnabled()) break; // This also make skipping drawing very effective. @@ -620,7 +626,7 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { } if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); + ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); break; } @@ -630,7 +636,7 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { void *inds = 0; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr); + ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); break; } inds = Memory::GetPointer(gstate_c.indexAddr); @@ -660,9 +666,29 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { // The arrow and other rotary items in Puzbob are bezier patches, strangely enough. case GE_CMD_BEZIER: { + void *control_points = Memory::GetPointer(gstate_c.vertexAddr); + void *indices = NULL; + if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { + if (!Memory::IsValidAddress(gstate_c.indexAddr)) { + ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); + break; + } + indices = Memory::GetPointer(gstate_c.indexAddr); + } + + if (gstate.getPatchPrimitiveType() != GE_PATCHPRIM_TRIANGLES) { + ERROR_LOG_REPORT(G3D, "Unsupported patch primitive %x", gstate.getPatchPrimitiveType()); + break; + } + + // TODO: Get rid of this old horror... int bz_ucount = data & 0xFF; int bz_vcount = (data >> 8) & 0xFF; transformDraw_.DrawBezier(bz_ucount, bz_vcount); + + // And instead use this. + // GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); + // transformDraw_.SubmitBezier(control_points, indices, sp_ucount, sp_vcount, patchPrim, gstate.vertType); } break; @@ -672,14 +698,14 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { void *indices = NULL; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { if (!Memory::IsValidAddress(gstate_c.indexAddr)) { - ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr); + ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr); break; } indices = Memory::GetPointer(gstate_c.indexAddr); } if (gstate.getPatchPrimitiveType() != GE_PATCHPRIM_TRIANGLES) { - ERROR_LOG(G3D, "Unsupported patch primitive %x", gstate.patchprimitive&3); + ERROR_LOG_REPORT(G3D, "Unsupported patch primitive %x", gstate.getPatchPrimitiveType()); break; } @@ -687,7 +713,7 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { int sp_vcount = (data >> 8) & 0xFF; int sp_utype = (data >> 16) & 0x3; int sp_vtype = (data >> 18) & 0x3; - int patchPrim = gstate.patchprimitive & 3; + GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); transformDraw_.SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, gstate.vertType); } break; @@ -1064,11 +1090,11 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) { shaderManager_->DirtyUniform(DIRTY_COLORMASK); break; -#ifndef USING_GLES2 case GE_CMD_ALPHATEST: +#ifndef USING_GLES2 if (((data >> 16) & 0xFF) != 0xFF && (data & 7) > 1) WARN_LOG_REPORT_ONCE(alphatestmask, HLE, "Unsupported alphatest mask: %02x", (data >> 16) & 0xFF); - break; + // Intentional fallthrough. #endif case GE_CMD_COLORREF: if (diff) @@ -1257,22 +1283,22 @@ void DIRECTX9_GPU::DoBlockTransfer() { // // etc.... - u32 srcBasePtr = (gstate.transfersrc & 0xFFFFF0) | ((gstate.transfersrcw & 0xFF0000) << 8); - u32 srcStride = gstate.transfersrcw & 0x3F8; + u32 srcBasePtr = gstate.getTransferSrcAddress(); + u32 srcStride = gstate.getTransferSrcStride(); - u32 dstBasePtr = (gstate.transferdst & 0xFFFFF0) | ((gstate.transferdstw & 0xFF0000) << 8); - u32 dstStride = gstate.transferdstw & 0x3F8; + u32 dstBasePtr = gstate.getTransferDstAddress(); + u32 dstStride = gstate.getTransferDstStride(); - int srcX = gstate.transfersrcpos & 0x3FF; - int srcY = (gstate.transfersrcpos >> 10) & 0x3FF; + int srcX = gstate.getTransferSrcX(); + int srcY = gstate.getTransferSrcY(); - int dstX = gstate.transferdstpos & 0x3FF; - int dstY = (gstate.transferdstpos >> 10) & 0x3FF; + int dstX = gstate.getTransferDstX(); + int dstY = gstate.getTransferDstY(); - int width = (gstate.transfersize & 0x3FF) + 1; - int height = ((gstate.transfersize >> 10) & 0x3FF) + 1; + int width = gstate.getTransferWidth(); + int height = gstate.getTransferHeight(); - int bpp = (gstate.transferstart & 1) ? 4 : 2; + int bpp = gstate.getTransferBpp(); DEBUG_LOG(G3D, "Block transfer: %08x/%x -> %08x/%x, %ix%ix%i (%i,%i)->(%i,%i)", srcBasePtr, srcStride, dstBasePtr, dstStride, width, height, bpp, srcX, srcY, dstX, dstY); @@ -1287,7 +1313,6 @@ void DIRECTX9_GPU::DoBlockTransfer() { textureCache_.Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT); - // A few games use this INSTEAD of actually drawing the video image to the screen, they just blast it to // the backbuffer. Detect this and have the framebuffermanager draw the pixels. diff --git a/GPU/Directx9/Framebuffer.cpp b/GPU/Directx9/Framebuffer.cpp index f80624e966..8e94170da1 100644 --- a/GPU/Directx9/Framebuffer.cpp +++ b/GPU/Directx9/Framebuffer.cpp @@ -129,7 +129,7 @@ ramDisplayFramebufPtr_(0), pD3Ddevice->CreateTexture(512, 272, 1, 0, D3DFMT(D3DFMT_A8R8G8B8), NULL, &drawPixelsTex_, NULL); - useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE ? 1 : 0; + useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; } FramebufferManager::~FramebufferManager() { @@ -255,7 +255,6 @@ static void ConvertMatrices(Matrix4x4 & in) { void FramebufferManager::DrawActiveTexture(float x, float y, float w, float h, bool flip, float uscale, float vscale) { float u2 = uscale; // Since we're flipping, 0 is down. That's where the scale goes. - float v1 = flip ? 1.0f : 1.0f - vscale; float v2 = flip ? 1.0f - vscale : 1.0f; @@ -311,38 +310,42 @@ VirtualFramebuffer *FramebufferManager::GetDisplayFBO() { } // Heuristics to figure out the size of FBO to create. -void GuessDrawingSize(int &drawing_width, int &drawing_height) { +void DrawingSize(int &drawing_width, int &drawing_height) { int default_width = 480; int default_height = 272; int viewport_width = (int) gstate.getViewportX1(); int viewport_height = (int) gstate.getViewportY1(); - int region_width = (gstate.getRegionX2() + 1) ; - int region_height = (gstate.getRegionY2() + 1) ; + int region_width = gstate.getRegionX2() + 1; + int region_height = gstate.getRegionY2() + 1; + int scissor_width = gstate.getScissorX2() + 1; + int scissor_height = gstate.getScissorY2() + 1; int fb_width = gstate.fbwidth & 0x3C0; - DEBUG_LOG(HLE,"viewport : %ix%i, region : %ix%i, stride: %i", viewport_width,viewport_height, region_width, region_height, fb_width); + DEBUG_LOG(HLE,"viewport : %ix%i, region : %ix%i , scissor: %ix%i, stride: %i, %i", viewport_width,viewport_height, region_width, region_height, scissor_width, scissor_height, fb_width, gstate.isModeThrough()); - // In case viewport return as 0x0 like FF Type-0 + // Viewport may return 0x0 for example FF Type-0 and we set it to 480x272 if (viewport_width <= 1 && viewport_height <=1) { - drawing_width = default_width; - drawing_height = default_height; + viewport_width = default_width; + viewport_height = default_height; } - if (fb_width < 512) { - if (fb_width != viewport_width) { + if (fb_width > 0 && fb_width < 512) { + // Correct scissor size has to be used to render like character shadow in Mortal Kombat . + if (fb_width == scissor_width && region_width != scissor_width) { + drawing_width = scissor_width; + drawing_height = scissor_height; + } else { drawing_width = viewport_width; drawing_height = viewport_height; + } } else { + // Correct region size has to be used when fb_width equals to region_width for exmaple GTA/Midnight Club/MSG Peace Maker . + if (fb_width == region_width && region_width != scissor_width) { drawing_width = region_width; drawing_height = region_height; - } } else { - if (fb_width != region_width) { drawing_width = default_width; drawing_height = default_height; - } else { - drawing_width = region_width; - drawing_height = region_height; } } } @@ -369,7 +372,6 @@ void FramebufferManager::DestroyFramebuf(VirtualFramebuffer *v) { void FramebufferManager::SetRenderFrameBuffer() { if (!gstate_c.framebufChanged && currentRenderVfb_) { - currentRenderVfb_->last_frame_used = gpuStats.numFlips; currentRenderVfb_->dirtyAfterDisplay = true; if (!gstate_c.skipDrawReason) @@ -392,10 +394,10 @@ void FramebufferManager::SetRenderFrameBuffer() { // As there are no clear "framebuffer width" and "framebuffer height" registers, // we need to infer the size of the current framebuffer somehow. Let's try the viewport. - GEBufferFormat fmt = static_cast(gstate.framebufpixformat & 3); + GEBufferFormat fmt = gstate.FrameBufFormat(); int drawing_width, drawing_height; - GuessDrawingSize(drawing_width, drawing_height); + DrawingSize(drawing_width, drawing_height); int buffer_width = drawing_width; int buffer_height = drawing_height; diff --git a/GPU/Directx9/IndexGenerator.cpp b/GPU/Directx9/IndexGenerator.cpp index 36cba2db65..ee26f1feb4 100644 --- a/GPU/Directx9/IndexGenerator.cpp +++ b/GPU/Directx9/IndexGenerator.cpp @@ -31,7 +31,7 @@ static const u8 indexedPrimitiveType[7] = { }; void IndexGenerator::Reset() { - prim_ = -1; + prim_ = GE_PRIM_INVALID; count_ = 0; index_ = 0; seenPrims_ = 0; diff --git a/GPU/Directx9/IndexGenerator.h b/GPU/Directx9/IndexGenerator.h index 832bc01a75..2817991f8c 100644 --- a/GPU/Directx9/IndexGenerator.h +++ b/GPU/Directx9/IndexGenerator.h @@ -29,7 +29,7 @@ public: void Reset(); static bool PrimCompatible(int prim1, int prim2); bool PrimCompatible(int prim); - int Prim() const { return prim_; } + GEPrimitiveType Prim() const { return prim_; } void AddPrim(int prim, int vertexCount); void TranslatePrim(int prim, int numInds, const u8 *inds, int indexOffset); @@ -93,7 +93,7 @@ private: int index_; int count_; int pureCount_; - int prim_; + GEPrimitiveType prim_; int seenPrims_; }; diff --git a/GPU/Directx9/Spline.cpp b/GPU/Directx9/Spline.cpp index 83c1614072..5b2d72320a 100644 --- a/GPU/Directx9/Spline.cpp +++ b/GPU/Directx9/Spline.cpp @@ -33,12 +33,12 @@ void TransformDrawEngine::DrawBezier(int ucount, int vcount) { int c = 0; for (int y = 0; y < 3; y++) { for (int x = 0; x < 3; x++) { - indices[c++] = y * 4 + x; - indices[c++] = y * 4 + x + 1; - indices[c++] = (y + 1) * 4 + x + 1; - indices[c++] = (y + 1) * 4 + x + 1; - indices[c++] = (y + 1) * 4 + x; - indices[c++] = y * 4 + x; + indices[c++] = y * 3 + x; + indices[c++] = y * 3 + x + 1; + indices[c++] = (y + 1) * 3 + x + 1; + indices[c++] = (y + 1) * 3 + x + 1; + indices[c++] = (y + 1) * 3 + x; + indices[c++] = y * 3 + x; } } @@ -57,7 +57,7 @@ void TransformDrawEngine::DrawBezier(int ucount, int vcount) { } } - if (!(gstate.vertType & GE_VTYPE_TC_MASK)) { + if (!gstate.getTexCoordMask()) { VertexDecoder *dec = GetVertexDecoder(gstate.vertType); dec->SetVertexType(gstate.vertType); u32 newVertType = dec->InjectUVs(decoded2, Memory::GetPointer(gstate_c.vertexAddr), customUV, 16); @@ -77,10 +77,13 @@ void TransformDrawEngine::DrawBezier(int ucount, int vcount) { #define END_OPEN_V 8 // We decode all vertices into a common format for easy interpolation and stuff. -// Not fast but this spline stuff is rarely used for time critical things, strangely enough. +// Not fast but can be optimized later. struct HWSplinePatch { u8 *points[16]; int type; + + // We need to generate both UVs and normals later... + // float u0, v0, u1, v1; }; void CopyTriangle(u8 *&dest, u8 *v1, u8 *v2, u8 * v3, int vertexSize) { @@ -92,8 +95,7 @@ void CopyTriangle(u8 *&dest, u8 *v1, u8 *v2, u8 * v3, int vertexSize) { dest += vertexSize; } -void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type) -{ +void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type) { Flush(); if (prim_type != GE_PATCHPRIM_TRIANGLES) { @@ -102,12 +104,11 @@ void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int } // We're not actually going to decode, only reshuffle. - VertexDecoder vdecoder; - vdecoder.SetVertexType(vertex_type); + VertexDecoder *vdecoder = GetVertexDecoder(vertex_type); - int undecodedVertexSize = vdecoder.VertexSize(); + int undecodedVertexSize = vdecoder->VertexSize(); - const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt(); + const DecVtxFormat& vtxfmt = vdecoder->GetDecVtxFmt(); u16 index_lower_bound = 0; u16 index_upper_bound = count_u * count_v - 1; @@ -163,12 +164,10 @@ void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int u8 *v2 = patch.points[point_index+4]; u8 *v3 = patch.points[point_index+5]; - // TODO: Insert UVs where applicable. Actually subdivide. - CopyTriangle(dest, v0, v1, v2, undecodedVertexSize); - CopyTriangle(dest, v2, v1, v0, undecodedVertexSize); - CopyTriangle(dest, v2, v1, v3, undecodedVertexSize); - CopyTriangle(dest, v3, v1, v2, undecodedVertexSize); - count += 12; + // TODO: Insert UVs and normals if not present. + CopyTriangle(dest, v0, v2, v1, undecodedVertexSize); + CopyTriangle(dest, v1, v2, v3, undecodedVertexSize); + count += 6; } } } @@ -177,5 +176,19 @@ void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int u32 vertTypeWithoutIndex = vertex_type & ~GE_VTYPE_IDX_MASK; SubmitPrim(decoded2, 0, GE_PRIM_TRIANGLES, count, vertTypeWithoutIndex, GE_VTYPE_IDX_NONE, 0); + Flush(); +} + +// TODO +void TransformDrawEngine::SubmitBezier(void* control_points, void* indices, int count_u, int count_v, GEPatchPrimType prim_type, u32 vertex_type) { + if (prim_type != GE_PATCHPRIM_TRIANGLES) { + // Only triangles supported! + return; + } + + // We're not actually going to decode, only reshuffle. + VertexDecoder vdecoder; + vdecoder.SetVertexType(vertex_type); + Flush(); } \ No newline at end of file diff --git a/GPU/Directx9/TextureCache.cpp b/GPU/Directx9/TextureCache.cpp index adadc2bb85..634021bc22 100644 --- a/GPU/Directx9/TextureCache.cpp +++ b/GPU/Directx9/TextureCache.cpp @@ -256,13 +256,6 @@ void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffe } } -static u32 GetClutIndex(u32 index) { - const u32 clutBase = gstate.getClutIndexStartPos(); - const u32 clutMask = gstate.getClutIndexMask(); - const u8 clutShift = gstate.getClutIndexShift(); - return ((index >> clutShift) & clutMask) | clutBase; -} - void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u32 level) { const u32 rowWidth = (bytesPerPixel > 0) ? (bufw * bytesPerPixel) : (bufw / 2); const u32 pitch = rowWidth / 4; @@ -348,7 +341,7 @@ inline void DeIndexTexture(ClutT *dest, const IndexT *indexed, int length, const } } else { for (int i = 0; i < length; ++i) { - *dest++ = clut[GetClutIndex(*indexed++)]; + *dest++ = clut[gstate.transformClutIndex(*indexed++)]; } } } @@ -373,8 +366,8 @@ inline void DeIndexTexture4(ClutT *dest, const u8 *indexed, int length, const Cl } else { for (int i = 0; i < length; i += 2) { u8 index = *indexed++; - dest[i + 0] = clut[GetClutIndex((index >> 0) & 0xf)]; - dest[i + 1] = clut[GetClutIndex((index >> 4) & 0xf)]; + dest[i + 0] = clut[gstate.transformClutIndex((index >> 0) & 0xf)]; + dest[i + 1] = clut[gstate.transformClutIndex((index >> 4) & 0xf)]; } } } @@ -426,7 +419,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, u3 tmpTexBuf16.resize(std::max(bufw, w) * h); tmpTexBufRearrange.resize(std::max(bufw, w) * h); const u16 *clut = GetCurrentClut(); - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { switch (bytesPerIndex) { case 1: DeIndexTexture(tmpTexBuf16.data(), texaddr, length, clut); @@ -466,7 +459,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, u3 tmpTexBuf32.resize(std::max(bufw, w) * h); tmpTexBufRearrange.resize(std::max(bufw, w) * h); const u32 *clut = GetCurrentClut(); - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { switch (bytesPerIndex) { case 1: DeIndexTexture(tmpTexBuf32.data(), texaddr, length, clut); @@ -564,8 +557,8 @@ static const u32 MagFilt[2] = { void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { int minFilt = gstate.texfilter & 0x7; int magFilt = (gstate.texfilter>>8) & 1; - bool sClamp = gstate.texwrap & 1; - bool tClamp = (gstate.texwrap>>8) & 1; + bool sClamp = gstate.isTexCoordClampedS(); + bool tClamp = gstate.isTexCoordClampedT(); // Always force !! force = true; @@ -797,7 +790,7 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int } void TextureCache::StartFrame() { - lastBoundTexture = NULL; + lastBoundTexture = INVALID_TEX; if(clearCacheNextFrame_) { Clear(true); clearCacheNextFrame_ = false; @@ -912,8 +905,8 @@ inline bool TextureCache::TexCacheEntry::Matches(u16 dim2, u8 format2, int maxLe } void TextureCache::LoadClut() { - u32 clutAddr = ((gstate.clutaddr & 0xFFFFFF) | ((gstate.clutaddrupper << 8) & 0x0F000000)); - clutTotalBytes_ = (gstate.loadclut & 0x3f) * 32; + u32 clutAddr = gstate.getClutAddress(); + clutTotalBytes_ = gstate.getClutLoadBytes(); if (Memory::IsValidAddress(clutAddr)) { Memory::MemcpyUnchecked(clutBufRaw_, clutAddr, clutTotalBytes_); } else { @@ -1070,7 +1063,7 @@ void TextureCache::SetTexture() { TexCacheEntry *entry = NULL; gstate_c.flipTexture = false; gstate_c.skipDrawReason &= ~SKIPDRAW_BAD_FB_TEXTURE; - bool useBufferedRendering = g_Config.iRenderingMode != 0 ? 1 : 0; + bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; bool replaceImages = false; if (iter != cache.end()) { @@ -1290,8 +1283,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c int h = gstate.getTextureHeight(level); const u8 *texptr = Memory::GetPointer(texaddr); - switch (format) - { + switch (format) { case GE_TFMT_CLUT4: { dstFmt = getClutDestFormat(clutformat); @@ -1311,7 +1303,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c tmpTexBufRearrange.resize(std::max(bufw, w) * h); const u16 *clut = GetCurrentClut() + clutSharingOffset; texByteAlign = 2; - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { if (clutAlphaLinear_ && mipmapShareClut) { DeIndexTexture4Optimal(tmpTexBuf16.data(), texaddr, bufw * h, clutAlphaLinearColor_); } else { @@ -1335,7 +1327,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c tmpTexBuf32.resize(std::max(bufw, w) * h); tmpTexBufRearrange.resize(std::max(bufw, w) * h); const u32 *clut = GetCurrentClut() + clutSharingOffset; - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { DeIndexTexture4(tmpTexBuf32.data(), texaddr, bufw * h, clut); finalBuf = tmpTexBuf32.data(); } else { @@ -1392,7 +1384,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c dstFmt = D3DFMT_R5G6B5; texByteAlign = 2; - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { int len = std::max(bufw, w) * h; tmpTexBuf16.resize(len); tmpTexBufRearrange.resize(len); @@ -1410,7 +1402,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c if (bufw < 4) bufw = 4; dstFmt = D3DFMT_A8R8G8B8; - if (!(gstate.texmode & 1)) { + if (!gstate.isTextureSwizzled()) { // Special case: if we don't need to deal with packing, we don't need to copy. //if (w == bufw) { // finalBuf = Memory::GetPointer(texaddr); @@ -1446,9 +1438,8 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c blockIndex++; } } - w = (w + 3) & ~3; finalBuf = tmpTexBuf32.data(); - //TextureConvertColors(finalBuf, finalBuf, dstFmt, bufw * h); + w = (w + 3) & ~3; } break; diff --git a/GPU/Directx9/TextureScaler.cpp b/GPU/Directx9/TextureScaler.cpp index 4fd492ca53..d3959bf821 100644 --- a/GPU/Directx9/TextureScaler.cpp +++ b/GPU/Directx9/TextureScaler.cpp @@ -526,7 +526,7 @@ TextureScaler::TextureScaler() { bool TextureScaler::IsEmptyOrFlat(u32* data, int pixels, u32 fmt) { int pixelsPerWord = (fmt == D3DFMT_A8R8G8B8) ? 1 : 2; - int ref = data[0]; + u32 ref = data[0]; for(int i=0; i= gstate_c.lightangle[l]) @@ -666,38 +667,39 @@ void TransformDrawEngine::SoftwareTransformAndDraw( // Perform texture coordinate generation after the transform and lighting - one style of UV depends on lights. switch (gstate.getUVGenMode()) { - case 0: // UV mapping + case GE_TEXMAP_TEXTURE_COORDS: // UV mapping + case GE_TEXMAP_UNKNOWN: // Seen in Riviera. Unsure of meaning, but this works. // Texture scale/offset is only performed in this mode. uv[0] = uscale * (ruv[0]*gstate_c.uv.uScale + gstate_c.uv.uOff); uv[1] = vscale * (ruv[1]*gstate_c.uv.vScale + gstate_c.uv.vOff); uv[2] = 1.0f; break; - case 1: + case GE_TEXMAP_TEXTURE_MATRIX: { // Projection mapping Vec3f source; switch (gstate.getUVProjMode()) { - case 0: // Use model space XYZ as source + case GE_PROJMAP_POSITION: // Use model space XYZ as source source = pos; break; - case 1: // Use unscaled UV as source + case GE_PROJMAP_UV: // Use unscaled UV as source source = Vec3f(ruv[0], ruv[1], 0.0f); break; - case 2: // Use normalized normal as source + case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized normal as source if (reader.hasNormal()) { source = Vec3f(norm).Normalized(); } else { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); - source = Vec3f::AssignToAll(0.0f); + source = Vec3f(0.0f, 0.0f, 1.0f); } break; - case 3: // Use non-normalized normal as source! + case GE_PROJMAP_NORMAL: // Use non-normalized normal as source! if (reader.hasNormal()) { source = Vec3f(norm); } else { ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?"); - source = Vec3f::AssignToAll(0.0f); + source = Vec3f(0.0f, 0.0f, 1.0f); } break; } @@ -709,7 +711,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( uv[2] = uvw[2]; } break; - case 2: + case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use two light sources to generate U and V. { Vec3f lightpos0 = Vec3f(gstate_c.lightpos[gstate.getUVLS0()]).Normalized(); @@ -866,7 +868,7 @@ int TransformDrawEngine::EstimatePerVertexCost() { if (gstate.isLightChanEnabled(i)) cost += 10; } - if (gstate.getUVGenMode() != 0) { + if (gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_COORDS) { cost += 20; } if (dec_ && dec_->morphcount > 1) { @@ -876,7 +878,7 @@ int TransformDrawEngine::EstimatePerVertexCost() { return cost; } -void TransformDrawEngine::SubmitPrim(void *verts, void *inds, int prim, int vertexCount, u32 vertType, int forceIndexType, int *bytesRead) { +void TransformDrawEngine::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int forceIndexType, int *bytesRead) { if (vertexCount == 0) return; // we ignore zero-sized draw calls. @@ -1091,7 +1093,7 @@ void TransformDrawEngine::DoFlush() { // This is not done on every drawcall, we should collect vertex data // until critical state changes. That's when we draw (flush). - int prim = prevPrim_; + GEPrimitiveType prim = prevPrim_; ApplyDrawState(prim); LinkedShader *program = shaderManager_->ApplyShader(prim); @@ -1205,7 +1207,7 @@ void TransformDrawEngine::DoFlush() { vb_ = vai->vbo; ib_ = vai->ebo; vertexCount = vai->numVerts; - prim = vai->prim; + prim = static_cast(vai->prim); break; } @@ -1222,7 +1224,7 @@ void TransformDrawEngine::DoFlush() { ib_ = vai->ebo; vertexCount = vai->numVerts; - prim = vai->prim; + prim = static_cast(vai->prim); break; } @@ -1290,5 +1292,5 @@ rotateVBO: indexGen.Reset(); collectedVerts = 0; numDrawCalls = 0; - prevPrim_ = -1; + prevPrim_ = GE_PRIM_INVALID; } diff --git a/GPU/Directx9/TransformPipeline.h b/GPU/Directx9/TransformPipeline.h index 08c897ab60..f847db4363 100644 --- a/GPU/Directx9/TransformPipeline.h +++ b/GPU/Directx9/TransformPipeline.h @@ -54,7 +54,7 @@ public: vbo = 0; ebo = 0; numDCs = 0; - prim = -1; + prim = GE_PRIM_INVALID; numDraws = 0; numFrames = 0; lastFrame = gpuStats.numFlips; @@ -95,9 +95,12 @@ class TransformDrawEngine { public: TransformDrawEngine(); virtual ~TransformDrawEngine(); - void SubmitPrim(void *verts, void *inds, int prim, int vertexCount, u32 vertexType, int forceIndexType, int *bytesRead); + void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertexType, int forceIndexType, int *bytesRead); + void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type); + void SubmitBezier(void* control_points, void* indices, int count_u, int count_v, GEPatchPrimType prim_type, u32 vertex_type); + + // legacy void DrawBezier(int ucount, int vcount); - void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type); void DecodeVerts(); void SetShaderManager(ShaderManager *shaderManager) { @@ -156,7 +159,7 @@ private: // Vertex collector state IndexGenerator indexGen; int collectedVerts; - int prevPrim_; + GEPrimitiveType prevPrim_; // Cached vertex decoders std::map decoderMap_; diff --git a/GPU/Directx9/helper/fbo.cpp b/GPU/Directx9/helper/fbo.cpp index dd222aa872..33d8e5c099 100644 --- a/GPU/Directx9/helper/fbo.cpp +++ b/GPU/Directx9/helper/fbo.cpp @@ -70,7 +70,7 @@ void * fbo_get_rtt(FBO *fbo) { void fbo_unbind() { if (current_fbo != NULL) { - D3DVECTOR4 White = {1.0f, 1.0f, 1.0f, 1.0f}; + D3DVECTOR4 White = {0.0f, 0.0f, 0.0f, 0.0f}; pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS|D3DRESOLVE_CLEARRENDERTARGET|D3DRESOLVE_CLEARDEPTHSTENCIL, NULL, current_fbo->tex, NULL, 0, 0, &White, 0.0f, 0, NULL ); /*