Video software:

Changed the EFB color order from RGBA to ABGR to emulate it correctly on little-endian platforms. Added some enumerations to clear up what components are which colors. Fixed the TEV alpha input LUT which would have caused problems if anything was doing alpha comparisons.
Changed box filter for EFB copies from 3x3 to 2x2 because that is probably correct. Also makes the math nicer.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6696 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
donkopunchstania 2010-12-31 06:45:18 +00:00
parent bc3b43d1bd
commit 8a711eadac
11 changed files with 280 additions and 266 deletions

View File

@ -23,6 +23,7 @@
#include "EfbCopy.h"
#include "Rasterizer.h"
#include "PixelEngine.h"
#include "Tev.h"
#include "../../../Core/VideoCommon/Src/TextureDecoder.h"
@ -55,7 +56,7 @@ void LoadBPReg(u32 value)
void BPWritten(int address, int newvalue)
{
switch (address)
{
{
case BPMEM_SCISSORTL:
case BPMEM_SCISSORBR:
case BPMEM_SCISSOROFFSET:
@ -124,8 +125,8 @@ void BPWritten(int address, int newvalue)
ColReg& reg = bpmem.tevregs[regNum].low;
bool konst = reg.type;
Rasterizer::SetTevReg(regNum, 3, konst, reg.b); // A
Rasterizer::SetTevReg(regNum, 0, konst, reg.a); // R
Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.b); // A
Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.a); // R
break;
}
@ -139,8 +140,8 @@ void BPWritten(int address, int newvalue)
ColReg& reg = bpmem.tevregs[regNum].high;
bool konst = reg.type;
Rasterizer::SetTevReg(regNum, 1, konst, reg.b); // G
Rasterizer::SetTevReg(regNum, 2, konst, reg.a); // B
Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.b); // G
Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.a); // B
break;
}

View File

@ -143,11 +143,11 @@ void DumpEfb(const char* filename)
for (int y = 0; y < EFB_HEIGHT; y++)
for (int x = 0; x < EFB_WIDTH; x++) {
EfbInterface::GetColor(x, y, sample);
// rgba to bgra
*(writePtr++) = sample[2];
// ABGR to BGRA
*(writePtr++) = sample[1];
*(writePtr++) = sample[0];
*(writePtr++) = sample[2];
*(writePtr++) = sample[3];
*(writePtr++) = sample[0];
}
(void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data);

View File

@ -58,7 +58,7 @@ namespace EfbCopy
void ClearEfb()
{
u32 clearColor = (bpmem.clearcolorAR & 0xff) | Common::swap16(bpmem.clearcolorGB) << 8 | (bpmem.clearcolorAR & 0xff00) << 16;
u32 clearColor = (bpmem.clearcolorAR & 0xff) << 24 | bpmem.clearcolorGB << 8 | (bpmem.clearcolorAR & 0xff00) >> 8;
int left = bpmem.copyTexSrcXY.x;
int top = bpmem.copyTexSrcXY.y;

View File

@ -53,8 +53,8 @@ namespace EfbInterface
{
u32 a32 = a;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff03ffff;
val |= (a32 << 16) & 0xfc0000;
u32 val = *dst & 0xffffffc0;
val |= (a32 >> 2) & 0x0000003f;
*dst = val;
}
break;
@ -73,7 +73,7 @@ namespace EfbInterface
u32 src = *(u32*)rgb;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@ -81,10 +81,10 @@ namespace EfbInterface
{
u32 src = *(u32*)rgb;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xfffc0000;
val |= (src >> 2) & 0x3f;
val |= (src >> 4) & 0xfc0;
val |= (src >> 6) & 0x3f000;
u32 val = *dst & 0xff00003f;
val |= (src >> 4) & 0x00000fc0; // blue
val |= (src >> 6) & 0x0003f000; // green
val |= (src >> 8) & 0x00fc0000; // red
*dst = val;
}
break;
@ -94,7 +94,7 @@ namespace EfbInterface
u32 src = *(u32*)rgb;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@ -113,7 +113,7 @@ namespace EfbInterface
u32 src = *(u32*)color;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@ -122,10 +122,10 @@ namespace EfbInterface
u32 src = *(u32*)color;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= (src >> 2) & 0x3f;
val |= (src >> 4) & 0xfc0;
val |= (src >> 6) & 0x3f000;
val |= (src >> 8) & 0xfc0000;
val |= (src >> 2) & 0x0000003f; // alpha
val |= (src >> 4) & 0x00000fc0; // blue
val |= (src >> 6) & 0x0003f000; // green
val |= (src >> 8) & 0x00fc0000; // red
*dst = val;
}
break;
@ -135,7 +135,7 @@ namespace EfbInterface
u32 src = *(u32*)color;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@ -153,17 +153,17 @@ namespace EfbInterface
{
u32 src = *(u32*)&efb[offset];
u32 *dst = (u32*)color;
u32 val = 0xff000000 | (src & 0x00ffffff);
u32 val = 0xff | ((src & 0x00ffffff) << 8);
*dst = val;
}
break;
case PIXELFMT_RGBA6_Z24:
{
u32 src = *(u32*)&efb[offset];
color[0] = Convert6To8(src & 0x3f);
color[1] = Convert6To8((src >> 6) & 0x3f);
color[2] = Convert6To8((src >> 12) & 0x3f);
color[3] = Convert6To8((src >> 18) & 0x3f);
color[ALP_C] = Convert6To8(src & 0x3f);
color[BLU_C] = Convert6To8((src >> 6) & 0x3f);
color[GRN_C] = Convert6To8((src >> 12) & 0x3f);
color[RED_C] = Convert6To8((src >> 18) & 0x3f);
}
break;
case PIXELFMT_RGB565_Z16:
@ -171,7 +171,7 @@ namespace EfbInterface
INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
u32 src = *(u32*)&efb[offset];
u32 *dst = (u32*)color;
u32 val = 0xff000000 | (src & 0x00ffffff);
u32 val = 0xff | ((src & 0x00ffffff) << 8);
*dst = val;
}
break;
@ -247,25 +247,25 @@ namespace EfbInterface
return 0xffffffff - *(u32*)dstClr;
case 4: // srcalpha
{
u8 alpha = srcClr[3];
u8 alpha = srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 5: // invsrcalpha
{
u8 alpha = 0xff - srcClr[3];
u8 alpha = 0xff - srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 6: // dstalpha
{
u8 alpha = dstClr[3];
u8 alpha = dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 7: // invdstalpha
{
u8 alpha = 0xff - dstClr[3];
u8 alpha = 0xff - dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
@ -287,25 +287,25 @@ namespace EfbInterface
return 0xffffffff - *(u32*)srcClr;
case 4: // srcalpha
{
u8 alpha = srcClr[3];
u8 alpha = srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 5: // invsrcalpha
{
u8 alpha = 0xff - srcClr[3];
u8 alpha = 0xff - srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 6: // dstalpha
{
u8 alpha = dstClr[3] & 0xff;
u8 alpha = dstClr[ALP_C] & 0xff;
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 7: // invdstalpha
{
u8 alpha = 0xff - dstClr[3];
u8 alpha = 0xff - dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
@ -421,7 +421,7 @@ namespace EfbInterface
dstClrPtr = color;
if (bpmem.dstalpha.enable)
dstClrPtr[3] = bpmem.dstalpha.alpha;
dstClrPtr[ALP_C] = bpmem.dstalpha.alpha;
if (bpmem.blendmode.colorupdate)
{
@ -431,7 +431,7 @@ namespace EfbInterface
SetPixelColorOnly(offset, dstClrPtr);
}
else if (bpmem.blendmode.alphaupdate)
SetPixelAlphaOnly(offset, dstClrPtr[3]);
SetPixelAlphaOnly(offset, dstClrPtr[ALP_C]);
// branchless bounding box update
PixelEngine::pereg.boxLeft = PixelEngine::pereg.boxLeft>x?x:PixelEngine::pereg.boxLeft;
@ -451,7 +451,7 @@ namespace EfbInterface
SetPixelColorOnly(offset, color);
}
else if (bpmem.blendmode.alphaupdate)
SetPixelAlphaOnly(offset, color[3]);
SetPixelAlphaOnly(offset, color[ALP_C]);
}
void SetDepth(u16 x, u16 y, u32 depth)
@ -486,13 +486,13 @@ namespace EfbInterface
u32 textureAddress = 0;
u32 efbOffset = 0;
for (u16 y = 0; y < EFB_HEIGHT; y++)
for (u16 y = 0; y < EFB_HEIGHT; y++)
{
for (u16 x = 0; x < EFB_WIDTH; x++)
{
GetPixelColor(efbOffset, colorPtr);
efbOffset += 3;
texturePtr[textureAddress++] = color;
efbOffset += 3;
texturePtr[textureAddress++] = Common::swap32(color); // ABGR->RGBA
}
}
}

View File

@ -24,7 +24,9 @@ namespace EfbInterface
{
const int DEPTH_BUFFER_START = EFB_WIDTH * EFB_HEIGHT * 3;
// color order is RGBA
enum { ALP_C, BLU_C, GRN_C, RED_C };
// color order is ABGR in order to emulate RGBA on little-endian hardware
// does full blending of an incoming pixel
void BlendTev(u16 x, u16 y, u8 *color);
@ -44,7 +46,7 @@ namespace EfbInterface
u8* GetPixelPointer(u16 x, u16 y, bool depth);
void UpdateColorTexture();
extern u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4]; // rgba format
extern u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4]; // RGBA format
}
#endif

View File

@ -79,7 +79,7 @@ namespace HwRasterizer
void DrawColorVertex(OutputVertexData *v)
{
glColor3ub(v->color[0][0], v->color[0][1], v->color[0][2]);
glColor3ub(v->color[0][OutputVertexData::RED_C], v->color[0][OutputVertexData::GRN_C], v->color[0][OutputVertexData::BLU_C]);
glVertex3f(v->screenPosition.x / efbHalfWidth - 1.0f, 1.0f - v->screenPosition.y / efbHalfHeight, v->screenPosition.z);
}

View File

@ -49,7 +49,10 @@ struct InputVertexData
struct OutputVertexData
{
Vec3 mvPosition;
// components in color channels
enum { RED_C, GRN_C, BLU_C, ALP_C };
Vec3 mvPosition;
Vec4 projectedPosition;
Vec3 screenPosition;
Vec3 normal[3];

View File

@ -47,31 +47,31 @@ void Tev::Init()
for (int i = 0; i < 4; i++)
Zero16[i] = 0;
m_ColorInputLUT[0][0] = &Reg[0][RED_C]; m_ColorInputLUT[0][1] = &Reg[0][GRN_C]; m_ColorInputLUT[0][2] = &Reg[0][BLU_C]; // prev.rgb
m_ColorInputLUT[1][0] = &Reg[0][ALP_C]; m_ColorInputLUT[1][1] = &Reg[0][ALP_C]; m_ColorInputLUT[1][2] = &Reg[0][ALP_C]; // prev.aaa
m_ColorInputLUT[2][0] = &Reg[1][RED_C]; m_ColorInputLUT[2][1] = &Reg[1][GRN_C]; m_ColorInputLUT[2][2] = &Reg[1][BLU_C]; // c0.rgb
m_ColorInputLUT[3][0] = &Reg[1][ALP_C]; m_ColorInputLUT[3][1] = &Reg[1][ALP_C]; m_ColorInputLUT[3][2] = &Reg[1][ALP_C]; // c0.aaa
m_ColorInputLUT[4][0] = &Reg[2][RED_C]; m_ColorInputLUT[4][1] = &Reg[2][GRN_C]; m_ColorInputLUT[4][2] = &Reg[2][BLU_C]; // c1.rgb
m_ColorInputLUT[5][0] = &Reg[2][ALP_C]; m_ColorInputLUT[5][1] = &Reg[2][ALP_C]; m_ColorInputLUT[5][2] = &Reg[2][ALP_C]; // c1.aaa
m_ColorInputLUT[6][0] = &Reg[3][RED_C]; m_ColorInputLUT[6][1] = &Reg[3][GRN_C]; m_ColorInputLUT[6][2] = &Reg[3][BLU_C]; // c2.rgb
m_ColorInputLUT[7][0] = &Reg[3][ALP_C]; m_ColorInputLUT[7][1] = &Reg[3][ALP_C]; m_ColorInputLUT[7][2] = &Reg[3][ALP_C]; // c2.aaa
m_ColorInputLUT[8][0] = &TexColor[RED_C]; m_ColorInputLUT[8][1] = &TexColor[GRN_C]; m_ColorInputLUT[8][2] = &TexColor[BLU_C]; // tex.rgb
m_ColorInputLUT[9][0] = &TexColor[ALP_C]; m_ColorInputLUT[9][1] = &TexColor[ALP_C]; m_ColorInputLUT[9][2] = &TexColor[ALP_C]; // tex.aaa
m_ColorInputLUT[10][0] = &RasColor[RED_C]; m_ColorInputLUT[10][1] = &RasColor[GRN_C]; m_ColorInputLUT[10][2] = &RasColor[BLU_C]; // ras.rgb
m_ColorInputLUT[11][0] = &RasColor[ALP_C]; m_ColorInputLUT[11][1] = &RasColor[ALP_C]; m_ColorInputLUT[11][2] = &RasColor[ALP_C]; // ras.rgb
m_ColorInputLUT[12][0] = &FixedConstants[8]; m_ColorInputLUT[12][1] = &FixedConstants[8]; m_ColorInputLUT[12][2] = &FixedConstants[8]; // one
m_ColorInputLUT[13][0] = &FixedConstants[4]; m_ColorInputLUT[13][1] = &FixedConstants[4]; m_ColorInputLUT[13][2] = &FixedConstants[4]; // half
m_ColorInputLUT[14][0] = &StageKonst[0]; m_ColorInputLUT[14][1] = &StageKonst[1]; m_ColorInputLUT[14][2] = &StageKonst[2]; // konst
m_ColorInputLUT[15][0] = &FixedConstants[0]; m_ColorInputLUT[15][1] = &FixedConstants[0]; m_ColorInputLUT[15][2] = &FixedConstants[0]; // zero
m_ColorInputLUT[0][RED_INP] = &Reg[0][RED_C]; m_ColorInputLUT[0][GRN_INP] = &Reg[0][GRN_C]; m_ColorInputLUT[0][BLU_INP] = &Reg[0][BLU_C]; // prev.rgb
m_ColorInputLUT[1][RED_INP] = &Reg[0][ALP_C]; m_ColorInputLUT[1][GRN_INP] = &Reg[0][ALP_C]; m_ColorInputLUT[1][BLU_INP] = &Reg[0][ALP_C]; // prev.aaa
m_ColorInputLUT[2][RED_INP] = &Reg[1][RED_C]; m_ColorInputLUT[2][GRN_INP] = &Reg[1][GRN_C]; m_ColorInputLUT[2][BLU_INP] = &Reg[1][BLU_C]; // c0.rgb
m_ColorInputLUT[3][RED_INP] = &Reg[1][ALP_C]; m_ColorInputLUT[3][GRN_INP] = &Reg[1][ALP_C]; m_ColorInputLUT[3][BLU_INP] = &Reg[1][ALP_C]; // c0.aaa
m_ColorInputLUT[4][RED_INP] = &Reg[2][RED_C]; m_ColorInputLUT[4][GRN_INP] = &Reg[2][GRN_C]; m_ColorInputLUT[4][BLU_INP] = &Reg[2][BLU_C]; // c1.rgb
m_ColorInputLUT[5][RED_INP] = &Reg[2][ALP_C]; m_ColorInputLUT[5][GRN_INP] = &Reg[2][ALP_C]; m_ColorInputLUT[5][BLU_INP] = &Reg[2][ALP_C]; // c1.aaa
m_ColorInputLUT[6][RED_INP] = &Reg[3][RED_C]; m_ColorInputLUT[6][GRN_INP] = &Reg[3][GRN_C]; m_ColorInputLUT[6][BLU_INP] = &Reg[3][BLU_C]; // c2.rgb
m_ColorInputLUT[7][RED_INP] = &Reg[3][ALP_C]; m_ColorInputLUT[7][GRN_INP] = &Reg[3][ALP_C]; m_ColorInputLUT[7][BLU_INP] = &Reg[3][ALP_C]; // c2.aaa
m_ColorInputLUT[8][RED_INP] = &TexColor[RED_C]; m_ColorInputLUT[8][GRN_INP] = &TexColor[GRN_C]; m_ColorInputLUT[8][BLU_INP] = &TexColor[BLU_C]; // tex.rgb
m_ColorInputLUT[9][RED_INP] = &TexColor[ALP_C]; m_ColorInputLUT[9][GRN_INP] = &TexColor[ALP_C]; m_ColorInputLUT[9][BLU_INP] = &TexColor[ALP_C]; // tex.aaa
m_ColorInputLUT[10][RED_INP] = &RasColor[RED_C]; m_ColorInputLUT[10][GRN_INP] = &RasColor[GRN_C]; m_ColorInputLUT[10][BLU_INP] = &RasColor[BLU_C]; // ras.rgb
m_ColorInputLUT[11][RED_INP] = &RasColor[ALP_C]; m_ColorInputLUT[11][GRN_INP] = &RasColor[ALP_C]; m_ColorInputLUT[11][BLU_INP] = &RasColor[ALP_C]; // ras.rgb
m_ColorInputLUT[12][RED_INP] = &FixedConstants[8]; m_ColorInputLUT[12][GRN_INP] = &FixedConstants[8]; m_ColorInputLUT[12][BLU_INP] = &FixedConstants[8]; // one
m_ColorInputLUT[13][RED_INP] = &FixedConstants[4]; m_ColorInputLUT[13][GRN_INP] = &FixedConstants[4]; m_ColorInputLUT[13][BLU_INP] = &FixedConstants[4]; // half
m_ColorInputLUT[14][RED_INP] = &StageKonst[RED_C]; m_ColorInputLUT[14][GRN_INP] = &StageKonst[GRN_C]; m_ColorInputLUT[14][BLU_INP] = &StageKonst[BLU_C]; // konst
m_ColorInputLUT[15][RED_INP] = &FixedConstants[0]; m_ColorInputLUT[15][GRN_INP] = &FixedConstants[0]; m_ColorInputLUT[15][BLU_INP] = &FixedConstants[0]; // zero
m_AlphaInputLUT[0] = &Reg[0][ALP_C]; // prev.a
m_AlphaInputLUT[1] = &Reg[1][ALP_C]; // c0.a
m_AlphaInputLUT[2] = &Reg[2][ALP_C]; // c1.a
m_AlphaInputLUT[3] = &Reg[3][ALP_C]; // c2.a
m_AlphaInputLUT[4] = &TexColor[ALP_C]; // tex.a
m_AlphaInputLUT[5] = &RasColor[ALP_C]; // ras.a
m_AlphaInputLUT[6] = &StageKonst[ALP_C]; // konst.a
m_AlphaInputLUT[7] = &Zero16[ALP_C]; // zero
m_AlphaInputLUT[0] = Reg[0]; // prev
m_AlphaInputLUT[1] = Reg[1]; // c0
m_AlphaInputLUT[2] = Reg[2]; // c1
m_AlphaInputLUT[3] = Reg[3]; // c2
m_AlphaInputLUT[4] = TexColor; // tex
m_AlphaInputLUT[5] = RasColor; // ras
m_AlphaInputLUT[6] = StageKonst; // konst
m_AlphaInputLUT[7] = Zero16; // zero
for (int comp = 0; comp < 4; comp++)
{
@ -140,21 +140,21 @@ inline void Tev::SetRasColor(int colorChan, int swaptable)
case 0: // Color0
{
u8 *color = Color[0];
RasColor[0] = color[bpmem.tevksel[swaptable].swap1];
RasColor[1] = color[bpmem.tevksel[swaptable].swap2];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2];
swaptable++;
RasColor[2] = color[bpmem.tevksel[swaptable].swap1];
RasColor[3] = color[bpmem.tevksel[swaptable].swap2];
RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
}
break;
case 1: // Color1
{
u8 *color = Color[1];
RasColor[0] = color[bpmem.tevksel[swaptable].swap1];
RasColor[1] = color[bpmem.tevksel[swaptable].swap2];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2];
swaptable++;
RasColor[2] = color[bpmem.tevksel[swaptable].swap1];
RasColor[3] = color[bpmem.tevksel[swaptable].swap2];
RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
}
break;
case 5: // alpha bump
@ -199,7 +199,7 @@ void Tev::DrawColorRegular(TevStageCombiner::ColorCombiner &cc)
result = result << m_ScaleLShiftLUT[cc.shift];
result = result >> m_ScaleRShiftLUT[cc.shift];
Reg[cc.dest][RED_C + i] = result;
Reg[cc.dest][BLU_C + i] = result;
}
}
@ -215,74 +215,74 @@ void Tev::DrawColorCompare(TevStageCombiner::ColorCombiner &cc)
switch(cmp) {
case TEVCMP_R8_GT:
{
a = *m_ColorInputLUT[cc.a][RED_C] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_C] & 0xff;
a = *m_ColorInputLUT[cc.a][RED_INP] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_INP] & 0xff;
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_R8_EQ:
{
a = *m_ColorInputLUT[cc.a][RED_C] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_C] & 0xff;
a = *m_ColorInputLUT[cc.a][RED_INP] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_INP] & 0xff;
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_GR16_GT:
{
a = ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][GRN_INP] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_INP] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_GR16_EQ:
{
a = ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_BGR24_GT:
{
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_BGR24_EQ:
{
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
}
}
break;
@ -293,7 +293,7 @@ void Tev::DrawColorCompare(TevStageCombiner::ColorCombiner &cc)
InputReg.b = *m_ColorInputLUT[cc.b][i];
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((InputReg.a > InputReg.b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((InputReg.a > InputReg.b) ? InputReg.c : 0);
}
break;
case TEVCMP_RGB8_EQ:
@ -303,7 +303,7 @@ void Tev::DrawColorCompare(TevStageCombiner::ColorCombiner &cc)
InputReg.b = *m_ColorInputLUT[cc.b][i];
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((InputReg.a == InputReg.b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((InputReg.a == InputReg.b) ? InputReg.c : 0);
}
break;
}
@ -313,10 +313,10 @@ void Tev::DrawAlphaRegular(TevStageCombiner::AlphaCombiner &ac)
{
InputRegType InputReg;
InputReg.a = *m_AlphaInputLUT[ac.a];
InputReg.b = *m_AlphaInputLUT[ac.b];
InputReg.c = *m_AlphaInputLUT[ac.c];
InputReg.d = *m_AlphaInputLUT[ac.d];
InputReg.a = m_AlphaInputLUT[ac.a][ALP_C];
InputReg.b = m_AlphaInputLUT[ac.b][ALP_C];
InputReg.c = m_AlphaInputLUT[ac.c][ALP_C];
InputReg.d = m_AlphaInputLUT[ac.d][ALP_C];
u16 c = InputReg.c + (InputReg.c >> 7);
@ -479,13 +479,13 @@ void Tev::Indirect(unsigned int stageNum, s32 s, s32 t)
AlphaBump = 0;
break;
case ITBA_S:
AlphaBump = indmap[ALP_C];
AlphaBump = indmap[TextureSampler::ALP_SMP];
break;
case ITBA_T:
AlphaBump = indmap[BLU_C];
AlphaBump = indmap[TextureSampler::BLU_SMP];
break;
case ITBA_U:
AlphaBump = indmap[GRN_C];
AlphaBump = indmap[TextureSampler::GRN_SMP];
break;
}
@ -499,27 +499,27 @@ void Tev::Indirect(unsigned int stageNum, s32 s, s32 t)
// format
switch(indirect.fmt) {
case ITF_8:
indcoord[0] = indmap[ALP_C] + bias[0];
indcoord[1] = indmap[BLU_C] + bias[1];
indcoord[2] = indmap[GRN_C] + bias[2];
indcoord[0] = indmap[TextureSampler::ALP_SMP] + bias[0];
indcoord[1] = indmap[TextureSampler::BLU_SMP] + bias[1];
indcoord[2] = indmap[TextureSampler::GRN_SMP] + bias[2];
AlphaBump = AlphaBump & 0xf8;
break;
case ITF_5:
indcoord[0] = (indmap[ALP_C] & 0x1f) + bias[0];
indcoord[1] = (indmap[BLU_C] & 0x1f) + bias[1];
indcoord[2] = (indmap[GRN_C] & 0x1f) + bias[2];
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x1f) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x1f) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x1f) + bias[2];
AlphaBump = AlphaBump & 0xe0;
break;
case ITF_4:
indcoord[0] = (indmap[ALP_C] & 0x0f) + bias[0];
indcoord[1] = (indmap[BLU_C] & 0x0f) + bias[1];
indcoord[2] = (indmap[GRN_C] & 0x0f) + bias[2];
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x0f) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x0f) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x0f) + bias[2];
AlphaBump = AlphaBump & 0xf0;
break;
case ITF_3:
indcoord[0] = (indmap[ALP_C] & 0x07) + bias[0];
indcoord[1] = (indmap[BLU_C] & 0x07) + bias[1];
indcoord[2] = (indmap[GRN_C] & 0x07) + bias[2];
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x07) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x07) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x07) + bias[2];
AlphaBump = AlphaBump & 0xf8;
break;
default:
@ -601,7 +601,10 @@ void Tev::Draw()
#if ALLOW_TEV_DUMPS
if (g_Config.bDumpTevStages)
{
u8 stage[4] = {(u8)IndirectTex[stageNum][3], (u8)IndirectTex[stageNum][2], (u8)IndirectTex[stageNum][1], 255};
u8 stage[4] = { IndirectTex[stageNum][TextureSampler::ALP_SMP],
IndirectTex[stageNum][TextureSampler::BLU_SMP],
IndirectTex[stageNum][TextureSampler::GRN_SMP],
255};
DebugUtil::DrawTempBuffer(stage, INDIRECT + stageNum);
}
#endif
@ -626,7 +629,8 @@ void Tev::Draw()
// sample texture
if (order.getEnable(stageOdd))
{
u8 texel[4];
// RGBA
u8 texel[4];
TextureSampler::Sample(TexCoord.s, TexCoord.t, TextureLod[stageNum], TextureLinear[stageNum], texmap, texel);
@ -637,11 +641,11 @@ void Tev::Draw()
int swaptable = ac.tswap * 2;
TexColor[0] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[1] = texel[bpmem.tevksel[swaptable].swap2];
TexColor[RED_C] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[GRN_C] = texel[bpmem.tevksel[swaptable].swap2];
swaptable++;
TexColor[2] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[3] = texel[bpmem.tevksel[swaptable].swap2];
TexColor[BLU_C] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[ALP_C] = texel[bpmem.tevksel[swaptable].swap2];
}
// set konst for this stage
@ -687,14 +691,14 @@ void Tev::Draw()
#if ALLOW_TEV_DUMPS
if (g_Config.bDumpTevStages)
{
u8 stage[4] = {(u8)Reg[0][0], (u8)Reg[0][1], (u8)Reg[0][2], (u8)Reg[0][3]};
u8 stage[4] = {(u8)Reg[0][RED_C], (u8)Reg[0][GRN_C], (u8)Reg[0][BLU_C], (u8)Reg[0][ALP_C]};
DebugUtil::DrawTempBuffer(stage, DIRECT + stageNum);
}
#endif
}
// convert to 8 bits per component
u8 output[4] = {(u8)Reg[0][0], (u8)Reg[0][1], (u8)Reg[0][2], (u8)Reg[0][3]};
u8 output[4] = {(u8)Reg[0][ALP_C], (u8)Reg[0][BLU_C], (u8)Reg[0][GRN_C], (u8)Reg[0][RED_C]};
if (!AlphaTest(output[ALP_C]))
return;

View File

@ -35,26 +35,35 @@ class Tev
signed t : 24;
};
// color order: RGBA
s16 Reg[4][4];
// color order: ABGR
s16 Reg[4][4];
s16 KonstantColors[4][4];
s16 FixedConstants[9];
s16 TexColor[4];
s16 RasColor[4];
s16 StageKonst[4];
s16 Zero16[4];
u8 AlphaBump;
s16 FixedConstants[9];
u8 AlphaBump;
u8 IndirectTex[4][4];
TextureCoordinateType TexCoord;
s16 *m_ColorInputLUT[16][3];
s16 *m_AlphaInputLUT[8]; // values must point to RGBA color
s16 *m_AlphaInputLUT[8]; // values must point to ABGR color
s16 *m_KonstLUT[32][4];
u8 *m_RasColorLUT[8];
s16 m_BiasLUT[4];
u8 m_ScaleLShiftLUT[4];
u8 m_ScaleRShiftLUT[4];
// enumeration for color input LUT
enum
{
BLU_INP,
GRN_INP,
RED_INP
};
enum BufferBase
{
DIRECT = 0,
@ -73,7 +82,7 @@ class Tev
public:
s32 Position[3];
u8 Color[2][4];
u8 Color[2][4]; // must be RGBA for correct swap table ordering
TextureCoordinateType Uv[8];
s32 IndirectLod[4];
bool IndirectLinear[4];
@ -86,7 +95,7 @@ public:
void SetRegColor(int reg, int comp, bool konst, s16 color);
enum { RED_C, GRN_C, BLU_C, ALP_C };
enum { ALP_C, BLU_C, GRN_C, RED_C };
};
#endif

View File

@ -29,18 +29,18 @@ namespace TextureEncoder
inline void RGBA_to_RGBA8(u8 *src, u8 &r, u8 &g, u8 &b, u8 &a)
{
u32 srcColor = *(u32*)src;
r = Convert6To8(srcColor & 0x3f);
g = Convert6To8((srcColor >> 6) & 0x3f);
b = Convert6To8((srcColor >> 12)& 0x3f);
a = Convert6To8((srcColor >> 18)& 0x3f);
a = Convert6To8(srcColor & 0x3f);
b = Convert6To8((srcColor >> 6) & 0x3f);
g = Convert6To8((srcColor >> 12)& 0x3f);
r = Convert6To8((srcColor >> 18)& 0x3f);
}
inline void RGBA_to_RGB8(u8 *src, u8 &r, u8 &g, u8 &b)
{
u32 srcColor = *(u32*)src;
r = Convert6To8(srcColor & 0x3f);
g = Convert6To8((srcColor >> 6) & 0x3f);
b = Convert6To8((srcColor >> 12)& 0x3f);
b = Convert6To8((srcColor >> 6) & 0x3f);
g = Convert6To8((srcColor >> 12)& 0x3f);
r = Convert6To8((srcColor >> 18)& 0x3f);
}
inline u8 RGB8_to_I(u8 r, u8 g, u8 b)
@ -50,74 +50,71 @@ inline u8 RGB8_to_I(u8 r, u8 g, u8 b)
return val >> 8;
}
// box filter sampling averages 9 samples centered at the source texel
// box filter sampling averages 4 samples with the source texel being the top left of the box
// components are scaled to the range 0-255 after all samples are taken
inline void boxfilterRGBA_to_RGBA8(u8 *src, u8 &r, u8 &g, u8 &b, u8 &a)
{
u16 r16 = 0, g16 = 0, b16 = 0, a16 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
u32 srcColor = *(u32*)src;
r16 += srcColor & 0x3f;
g16 += (srcColor >> 6) & 0x3f;
b16 += (srcColor >> 12) & 0x3f;
a16 += (srcColor >> 18) & 0x3f;
src += 3;
a16 += srcColor & 0x3f;
b16 += (srcColor >> 6) & 0x3f;
g16 += (srcColor >> 12) & 0x3f;
r16 += (srcColor >> 18) & 0x3f;
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
r = (r16 << 6) / 142;
g = (g16 << 6) / 142;
b = (b16 << 6) / 142;
a = (a16 << 6) / 142;
r = r16 + (r16 >> 6);
g = g16 + (g16 >> 6);
b = b16 + (b16 >> 6);
a = a16 + (a16 >> 6);
}
inline void boxfilterRGBA_to_RGB8(u8 *src, u8 &r, u8 &g, u8 &b)
{
u16 r16 = 0, g16 = 0, b16 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
u32 srcColor = *(u32*)src;
r16 += srcColor & 0x3f;
g16 += (srcColor >> 6) & 0x3f;
b16 += (srcColor >> 12) & 0x3f;
src += 3;
b16 += (srcColor >> 6) & 0x3f;
g16 += (srcColor >> 12) & 0x3f;
r16 += (srcColor >> 18) & 0x3f;
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
r = (r16 << 6) / 142;
g = (g16 << 6) / 142;
b = (b16 << 6) / 142;
r = r16 + (r16 >> 6);
g = g16 + (g16 >> 6);
b = b16 + (b16 >> 6);
}
inline void boxfilterRGBA_to_x8(u8 *src, u8 &x8, int shift)
{
u16 x16 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
u32 srcColor = *(u32*)src;
x16 += (srcColor >> shift) & 0x3f;
src += 3;
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
x8 = (x16 << 6) / 142;
x8 = x16 + (x16 >> 6);
}
inline void boxfilterRGBA_to_xx8(u8 *src, u8 &x1, u8 &x2, int shift1, int shift2)
@ -125,61 +122,58 @@ inline void boxfilterRGBA_to_xx8(u8 *src, u8 &x1, u8 &x2, int shift1, int shift2
u16 x16_1 = 0;
u16 x16_2 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
u32 srcColor = *(u32*)src;
x16_1 += (srcColor >> shift1) & 0x3f;
x16_2 += (srcColor >> shift2) & 0x3f;
src += 3;
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
x1 = (x16_1 << 6) / 142;
x2 = (x16_2 << 6) / 142;
x1 = x16_1 + (x16_1 >> 6);
x2 = x16_2 + (x16_2 >> 6);
}
inline void boxfilterRGB_to_RGB8(u8 *src, u8 &r, u8 &g, u8 &b)
{
u16 r16 = 0, g16 = 0, b16 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
r16 += src[0];
b16 += src[0];
g16 += src[1];
b16 += src[2];
src += 3;
r16 += src[2];
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
r = r16 / 9;
g = g16 / 9;
b = b16 / 9;
r = r16 >> 2;
g = g16 >> 2;
b = b16 >> 2;
}
inline void boxfilterRGB_to_x8(u8 *src, u8 &x8, int comp)
{
u16 x16 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
x16 += src[comp];
src += 3;
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
x8 = x16 / 9;
x8 = x16 >> 2;
}
inline void boxfilterRGB_to_xx8(u8 *src, u8 &x1, u8 &x2, int comp1, int comp2)
@ -187,20 +181,19 @@ inline void boxfilterRGB_to_xx8(u8 *src, u8 &x1, u8 &x2, int comp1, int comp2)
u16 x16_1 = 0;
u16 x16_2 = 0;
// move to top left
src -= (1 + 640) * 3;
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
x16_1 += src[comp1];
x16_2 += src[comp2];
src += 3;
src += 3; // move to next pixel
}
src += (640 - 3) * 3;
src += (640 - 2) * 3; // move to next line
}
x1 = x16_1 / 9;
x2 = x16_2 / 9;
x1 = x16_1 >> 2;
x2 = x16_2 >> 2;
}
void SetBlockDimensions(int blkWidthLog2, int blkHeightLog2, u16 &sBlkCount, u16 &tBlkCount, u16 &sBlkSize, u16 &tBlkSize)
@ -333,8 +326,8 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
u32 srcColor = *(u32*)src;
src += readStride;
u16 val = ((srcColor << 10) & 0xf800) | ((srcColor >> 1) & 0x07e0) | ((srcColor >> 13) & 0x001e);
*(u16*)dst = Common::swap16(val);
u16 val = ((srcColor >> 8) & 0xf800) | ((srcColor >> 7) & 0x07e0) | ((srcColor >> 7) & 0x001e);
*(u16*)dst = Common::swap16(val);
dst+=2;
}
ENCODE_LOOP_SPANS
@ -348,12 +341,12 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
u32 srcColor = *(u32*)src;
src += readStride;
u16 a16 = (srcColor >> 9) & 0x7000;
u16 alpha = (srcColor << 9) & 0x7000;
u16 val;
if (a16 == 0x7000) // 5551
val = 0x8000 | ((srcColor << 9) & 0x7c00) | ((srcColor >> 2) & 0x03e0) | ((srcColor >> 13) & 0x001e);
if (alpha == 0x7000) // 555
val = 0x8000 | ((srcColor >> 9) & 0x7c00) | ((srcColor >> 8) & 0x03e0) | ((srcColor >> 7) & 0x001e);
else // 4443
val = a16 | ((srcColor << 6) & 0x0f00) | ((srcColor >> 4) & 0x00f0) | ((srcColor >> 14) & 0x000f);
val = alpha | ((srcColor >> 12) & 0x0f00) | ((srcColor >> 10) & 0x00f0) | ((srcColor >> 8) & 0x000f);
*(u16*)dst = Common::swap16(val);
dst+=2;
@ -381,11 +374,11 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
{
u32 srcColor = *(u32*)src;
src += readStride;
*dst = Convert6To8(srcColor & 0x3f) & 0xf0;
*dst = (srcColor >> 16) & 0xf0;
srcColor = *(u32*)src;
src += readStride;
*dst |= Convert6To8(srcColor & 0x3f) >> 4;
*dst |= (srcColor >> 20) & 0x0f;
dst++;
}
ENCODE_LOOP_SPANS
@ -398,7 +391,7 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
{
u32 srcColor = *(u32*)src;
src += readStride;
*dst++ = (Convert6To8((srcColor >> 18) & 0x3f) & 0xf0) | (Convert6To8(srcColor & 0x3f) >> 4);
*dst++ = ((srcColor << 2) & 0xf0) | ((srcColor >> 20) & 0x0f);
}
ENCODE_LOOP_SPANS
break;
@ -410,8 +403,8 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
{
u32 srcColor = *(u32*)src;
src += readStride;
*dst++ = Convert6To8((srcColor >> 18) & 0x3f);
*dst++ = Convert6To8(srcColor & 0x3f);
*dst++ = Convert6To8((srcColor >> 18) & 0x3f);
}
ENCODE_LOOP_SPANS
break;
@ -422,7 +415,7 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
u32 srcColor = *(u32*)src;
*dst++ = Convert6To8((srcColor >> 18) & 0x3f);
*dst++ = Convert6To8(srcColor & 0x3f);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -434,7 +427,7 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
u32 srcColor = *(u32*)src;
*dst++ = Convert6To8(srcColor & 0x3f);
*dst++ = Convert6To8((srcColor >> 18) & 0x3f);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -446,7 +439,7 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
u32 srcColor = *(u32*)src;
*dst++ = Convert6To8((srcColor >> 6) & 0x3f);
*dst++ = Convert6To8((srcColor >> 12) & 0x3f);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -458,7 +451,7 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
u32 srcColor = *(u32*)src;
*dst++ = Convert6To8((srcColor >> 12) & 0x3f);
*dst++ = Convert6To8((srcColor >> 6) & 0x3f);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -471,8 +464,8 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
{
u32 srcColor = *(u32*)src;
src += readStride;
*dst++ = Convert6To8((srcColor >> 6) & 0x3f);
*dst++ = Convert6To8(srcColor & 0x3f);
*dst++ = Convert6To8((srcColor >> 12) & 0x3f);
*dst++ = Convert6To8((srcColor >> 18) & 0x3f);
}
ENCODE_LOOP_SPANS
break;
@ -484,8 +477,8 @@ void EncodeRGBA6(u8 *dst, u8 *src, u32 format)
{
u32 srcColor = *(u32*)src;
src += readStride;
*dst++ = Convert6To8((srcColor >> 12) & 0x3f);
*dst++ = Convert6To8((srcColor >> 6) & 0x3f);
*dst++ = Convert6To8((srcColor >> 6) & 0x3f);
*dst++ = Convert6To8((srcColor >> 12) & 0x3f);
}
ENCODE_LOOP_SPANS
break;
@ -615,11 +608,11 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
sBlkSize /= 2;
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_x8(src, r, 0);
boxfilterRGBA_to_x8(src, r, 18);
src += readStride;
*dst = r & 0xf0;
boxfilterRGBA_to_x8(src, r, 0);
boxfilterRGBA_to_x8(src, r, 18);
src += readStride;
*dst |= r >> 4;
dst++;
@ -632,7 +625,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_xx8(src, r, a, 0, 18);
boxfilterRGBA_to_xx8(src, r, a, 18, 0);
src += readStride;
*dst++ = (a & 0xf0) | (r >> 4);
}
@ -644,7 +637,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_xx8(src, r, a, 0, 18);
boxfilterRGBA_to_xx8(src, r, a, 18, 0);
src += readStride;
*dst++ = a;
*dst++ = r;
@ -657,7 +650,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_x8(src, a, 18);
boxfilterRGBA_to_x8(src, a, 0);
*dst++ = a;
src += readStride;
}
@ -669,7 +662,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_x8(src, r, 0);
boxfilterRGBA_to_x8(src, r, 18);
*dst++ = r;
src += readStride;
}
@ -681,7 +674,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_x8(src, g, 6);
boxfilterRGBA_to_x8(src, g, 12);
*dst++ = g;
src += readStride;
}
@ -693,7 +686,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_x8(src, b, 12);
boxfilterRGBA_to_x8(src, b, 6);
*dst++ = b;
src += readStride;
}
@ -705,7 +698,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_xx8(src, r, g, 0, 6);
boxfilterRGBA_to_xx8(src, r, g, 18, 12);
src += readStride;
*dst++ = g;
*dst++ = r;
@ -718,7 +711,7 @@ void EncodeRGBA6halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGBA_to_xx8(src, g, b, 6, 12);
boxfilterRGBA_to_xx8(src, g, b, 12, 6);
src += readStride;
*dst++ = b;
*dst++ = g;
@ -747,10 +740,10 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
sBlkSize /= 2;
ENCODE_LOOP_BLOCKS
{
*dst = RGB8_to_I(src[0], src[1], src[2]) & 0xf0;
*dst = RGB8_to_I(src[2], src[1], src[0]) & 0xf0;
src += readStride;
*dst |= RGB8_to_I(src[0], src[1], src[2]) >> 4;
*dst |= RGB8_to_I(src[2], src[1], src[0]) >> 4;
src += readStride;
dst++;
}
@ -762,7 +755,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
*dst++ = RGB8_to_I(src[0], src[1], src[2]);
*dst++ = RGB8_to_I(src[2], src[1], src[0]);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -773,7 +766,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
*dst++ = 0xf0 | (RGB8_to_I(src[0], src[1], src[2]) >> 4);
*dst++ = 0xf0 | (RGB8_to_I(src[2], src[1], src[0]) >> 4);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -785,7 +778,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
*dst++ = 0xff;
*dst++ = RGB8_to_I(src[0], src[1], src[2]);
*dst++ = RGB8_to_I(src[2], src[1], src[0]);
src += readStride;
}
@ -797,7 +790,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
u16 val = ((src[0] << 8) & 0xf800) | ((src[1] << 3) & 0x07e0) | ((src[2] >> 3) & 0x001e);
u16 val = ((src[2] << 8) & 0xf800) | ((src[1] << 3) & 0x07e0) | ((src[0] >> 3) & 0x001e);
*(u16*)dst = Common::swap16(val);
src += readStride;
dst+=2;
@ -810,7 +803,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
u16 val = 0x8000 | ((src[0] << 7) & 0x7c00) | ((src[1] << 2) & 0x03e0) | ((src[2] >> 3) & 0x001e);
u16 val = 0x8000 | ((src[2] << 7) & 0x7c00) | ((src[1] << 2) & 0x03e0) | ((src[0] >> 3) & 0x001e);
*(u16*)dst = Common::swap16(val);
src += readStride;
dst+=2;
@ -824,9 +817,9 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
dst[0] = 0xff;
dst[1] = src[0];
dst[1] = src[2];
dst[32] = src[1];
dst[33] = src[2];
dst[33] = src[0];
src += readStride;
dst += 2;
}
@ -839,10 +832,10 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
sBlkSize /= 2;
ENCODE_LOOP_BLOCKS
{
*dst = src[0] & 0xf0;
*dst = src[2] & 0xf0;
src += readStride;
*dst |= src[0] >> 4;
*dst |= src[2] >> 4;
src += readStride;
dst++;
@ -855,7 +848,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
*dst++ = 0xf0 | (src[0] >> 4);
*dst++ = 0xf0 | (src[2] >> 4);
src += readStride;
}
ENCODE_LOOP_SPANS
@ -867,7 +860,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
*dst++ = 0xff;
*dst++ = src[0];
*dst++ = src[2];
src += readStride;
}
ENCODE_LOOP_SPANS
@ -888,7 +881,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
*dst++ = src[0];
*dst++ = src[2];
src += readStride;
}
ENCODE_LOOP_SPANS
@ -910,7 +903,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
*dst++ = src[2];
*dst++ = src[0];
src += readStride;
}
ENCODE_LOOP_SPANS
@ -922,7 +915,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
ENCODE_LOOP_BLOCKS
{
*dst++ = src[1];
*dst++ = src[0];
*dst++ = src[2];
src += readStride;
}
ENCODE_LOOP_SPANS
@ -933,7 +926,7 @@ void EncodeRGB8(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
*dst++ = src[2];
*dst++ = src[0];
*dst++ = src[1];
src += readStride;
}
@ -1061,11 +1054,11 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
sBlkSize /= 2;
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_x8(src, r, 0);
boxfilterRGB_to_x8(src, r, 2);
*dst = r & 0xf0;
src += readStride;
boxfilterRGB_to_x8(src, r, 0);
boxfilterRGB_to_x8(src, r, 2);
*dst |= r >> 4;
src += readStride;
@ -1079,7 +1072,7 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_x8(src, r, 0);
boxfilterRGB_to_x8(src, r, 2);
*dst++ = 0xf0 | (r >> 4);
src += readStride;
}
@ -1091,7 +1084,7 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_x8(src, r, 0);
boxfilterRGB_to_x8(src, r, 2);
*dst++ = 0xff;
*dst++ = r;
src += readStride;
@ -1114,7 +1107,7 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_x8(src, r, 0);
boxfilterRGB_to_x8(src, r, 2);
*dst++ = r;
src += readStride;
}
@ -1138,7 +1131,7 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_x8(src, b, 2);
boxfilterRGB_to_x8(src, b, 0);
*dst++ = b;
src += readStride;
}
@ -1150,7 +1143,7 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_xx8(src, r, g, 0, 1);
boxfilterRGB_to_xx8(src, r, g, 2, 1);
*dst++ = g;
*dst++ = r;
src += readStride;
@ -1163,7 +1156,7 @@ void EncodeRGB8halfscale(u8 *dst, u8 *src, u32 format)
SetSpans(sBlkSize, tBlkSize, tSpan, sBlkSpan, tBlkSpan, writeStride);
ENCODE_LOOP_BLOCKS
{
boxfilterRGB_to_xx8(src, g, b, 1, 2);
boxfilterRGB_to_xx8(src, g, b, 1, 0);
*dst++ = b;
*dst++ = g;
src += readStride;

View File

@ -26,6 +26,8 @@ namespace TextureSampler
void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8 *sample);
void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample);
enum { RED_SMP, GRN_SMP, BLU_SMP, ALP_SMP };
}