sync with gles

This commit is contained in:
Ced2911 2013-09-04 11:19:36 +02:00
parent b152a49d3b
commit 746e7d5ff8
10 changed files with 150 additions and 114 deletions

View file

@ -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<GEPrimitiveType>(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.

View file

@ -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<GEBufferFormat>(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;

View file

@ -31,7 +31,7 @@ static const u8 indexedPrimitiveType[7] = {
};
void IndexGenerator::Reset() {
prim_ = -1;
prim_ = GE_PRIM_INVALID;
count_ = 0;
index_ = 0;
seenPrims_ = 0;

View file

@ -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_;
};

View file

@ -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();
}

View file

@ -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<u16>();
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
switch (bytesPerIndex) {
case 1:
DeIndexTexture<u8>(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<u32>();
if (!(gstate.texmode & 1)) {
if (!gstate.isTextureSwizzled()) {
switch (bytesPerIndex) {
case 1:
DeIndexTexture<u8>(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<u16>() + 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<u32>() + 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;

View file

@ -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<pixels/pixelsPerWord; ++i) {
if(data[i]!=ref) return false;
}

View file

@ -69,7 +69,7 @@ inline float clamp(float in, float min, float max) {
TransformDrawEngine::TransformDrawEngine()
: collectedVerts(0),
prevPrim_(-1),
prevPrim_(GE_PRIM_INVALID),
dec_(0),
lastVType_(-1),
shaderManager_(0),
@ -134,7 +134,7 @@ private:
};
Lighter::Lighter() {
doShadeMapping_ = (gstate.texmapmode & 0x3) == 2;
doShadeMapping_ = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP;
materialEmissive.GetFromRGB(gstate.materialemissive);
materialEmissive.a = 0.0f;
globalAmbient.GetFromRGB(gstate.ambientcolor);
@ -225,6 +225,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
lightScale = clamp(1.0f / (gstate_c.lightatt[l][0] + gstate_c.lightatt[l][1]*distanceToLight + gstate_c.lightatt[l][2]*distanceToLight*distanceToLight), 0.0f, 1.0f);
break;
case GE_LIGHTTYPE_SPOT:
case GE_LIGHTTYPE_UNKNOWN:
lightDir = gstate_c.lightdir[l];
angle = Dot(toLight.Normalized(), lightDir.Normalized());
if (angle >= 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<GEPrimitiveType>(vai->prim);
break;
}
@ -1222,7 +1224,7 @@ void TransformDrawEngine::DoFlush() {
ib_ = vai->ebo;
vertexCount = vai->numVerts;
prim = vai->prim;
prim = static_cast<GEPrimitiveType>(vai->prim);
break;
}
@ -1290,5 +1292,5 @@ rotateVBO:
indexGen.Reset();
collectedVerts = 0;
numDrawCalls = 0;
prevPrim_ = -1;
prevPrim_ = GE_PRIM_INVALID;
}

View file

@ -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<u32, VertexDecoder *> decoderMap_;

View file

@ -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 );
/*