Merge branch 'master' into wii-network
This commit is contained in:
commit
c3dbbe011d
|
@ -213,7 +213,7 @@ void Write32(const u32 _Value, const u32 _Address)
|
|||
break;
|
||||
}
|
||||
|
||||
WII_IPC_HLE_Interface::Update();
|
||||
//WII_IPC_HLE_Interface::Update();
|
||||
CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,6 @@ void EnqueReplyCallback(u64 userdata, int)
|
|||
|
||||
void Init()
|
||||
{
|
||||
enque_reply = CoreTiming::RegisterEvent("IPCReply", EnqueReplyCallback);
|
||||
|
||||
_dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isn't empty on init");
|
||||
CWII_IPC_HLE_Device_es::m_ContentFile = "";
|
||||
|
@ -130,11 +129,15 @@ void Init()
|
|||
#endif
|
||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++;
|
||||
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++;
|
||||
|
||||
enque_reply = CoreTiming::RegisterEvent("IPCReply", EnqueReplyCallback);
|
||||
}
|
||||
|
||||
void Reset(bool _bHard)
|
||||
{
|
||||
|
||||
CoreTiming::RemoveAllEvents(enque_reply);
|
||||
|
||||
u32 i;
|
||||
for (i=0; i<IPC_MAX_FDS; i++)
|
||||
{
|
||||
|
|
|
@ -89,8 +89,10 @@ bool AVIDump::CreateFile()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!m_fileCount) {
|
||||
if (!SetCompressionOptions()) {
|
||||
if (!m_fileCount)
|
||||
{
|
||||
if (!SetCompressionOptions())
|
||||
{
|
||||
NOTICE_LOG(VIDEO, "SetCompressionOptions failed");
|
||||
Stop();
|
||||
return false;
|
||||
|
|
|
@ -646,7 +646,8 @@ union FogParam0
|
|||
u32 sign : 1;
|
||||
};
|
||||
|
||||
float GetA() {
|
||||
float GetA()
|
||||
{
|
||||
union { u32 i; float f; } dummy;
|
||||
dummy.i = ((u32)sign << 31) | ((u32)exponent << 23) | ((u32)mantissa << 12); // scale mantissa from 11 to 23 bits
|
||||
return dummy.f;
|
||||
|
@ -667,7 +668,8 @@ union FogParam3
|
|||
};
|
||||
|
||||
// amount to subtract from eyespacez after range adjustment
|
||||
float GetC() {
|
||||
float GetC()
|
||||
{
|
||||
union { u32 i; float f; } dummy;
|
||||
dummy.i = ((u32)c_sign << 31) | ((u32)c_exp << 23) | ((u32)c_mant << 12); // scale mantissa from 11 to 23 bits
|
||||
return dummy.f;
|
||||
|
@ -906,7 +908,8 @@ union UPE_Copy
|
|||
union BPU_PreloadTileInfo
|
||||
{
|
||||
u32 hex;
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
u32 count : 15;
|
||||
u32 type : 2;
|
||||
};
|
||||
|
|
|
@ -102,7 +102,9 @@ void BPWritten(const BPCmd& bp)
|
|||
if (!mapTexFound)
|
||||
{
|
||||
if (bp.address != BPMEM_TEV_COLOR_ENV && bp.address != BPMEM_TEV_ALPHA_ENV)
|
||||
{
|
||||
numWrites = 0;
|
||||
}
|
||||
else if (++numWrites >= 100) // seem that if 100 consecutive BP writes are called to either of these addresses in ZTP,
|
||||
{ // then it is safe to assume the map texture address is currently loaded into the BP memory
|
||||
mapTexAddress = bpmem.tex[0].texImage3[0].hex << 5;
|
||||
|
@ -193,15 +195,19 @@ void BPWritten(const BPCmd& bp)
|
|||
PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d",
|
||||
bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
|
||||
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
|
||||
|
||||
// Set LogicOp Blending Mode
|
||||
if (bp.changes & 2)
|
||||
SetLogicOpMode();
|
||||
|
||||
// Set Dithering Mode
|
||||
if (bp.changes & 4)
|
||||
SetDitherMode();
|
||||
|
||||
// Set Blending Mode
|
||||
if (bp.changes & 0xFF1)
|
||||
SetBlendMode();
|
||||
|
||||
// Set Color Mask
|
||||
if (bp.changes & 0x18)
|
||||
SetColorMask();
|
||||
|
@ -420,7 +426,8 @@ void BPWritten(const BPCmd& bp)
|
|||
if(g_bSkipCurrentFrame)
|
||||
break;
|
||||
|
||||
if (bp.address == BPMEM_CLEARBBOX1) {
|
||||
if (bp.address == BPMEM_CLEARBBOX1)
|
||||
{
|
||||
int right = bp.newvalue >> 10;
|
||||
int left = bp.newvalue & 0x3ff;
|
||||
|
||||
|
@ -428,7 +435,9 @@ void BPWritten(const BPCmd& bp)
|
|||
PixelEngine::bbox[0] = left;
|
||||
PixelEngine::bbox[1] = right;
|
||||
PixelEngine::bbox_active = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int bottom = bp.newvalue >> 10;
|
||||
int top = bp.newvalue & 0x3ff;
|
||||
|
||||
|
@ -446,7 +455,8 @@ void BPWritten(const BPCmd& bp)
|
|||
|
||||
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
|
||||
OnPixelFormatChange();
|
||||
if(bp.changes & 7) {
|
||||
if(bp.changes & 7)
|
||||
{
|
||||
SetBlendMode(); // dual source could be activated by changing to PIXELFMT_RGBA6_Z24
|
||||
g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel
|
||||
}
|
||||
|
|
|
@ -88,7 +88,9 @@ union TVtxDesc
|
|||
u32 Tex7Coord : 2;
|
||||
u32 :31;
|
||||
};
|
||||
struct {
|
||||
|
||||
struct
|
||||
{
|
||||
u32 Hex0, Hex1;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -166,22 +166,30 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
|||
|
||||
case FIFO_RW_DISTANCE_LO:
|
||||
if (IsOnThread())
|
||||
{
|
||||
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
|
||||
_rReturnValue = ReadLow (fifo.CPWritePointer - fifo.SafeCPReadPointer);
|
||||
else
|
||||
_rReturnValue = ReadLow (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
|
||||
}
|
||||
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
|
||||
return;
|
||||
case FIFO_RW_DISTANCE_HI:
|
||||
if (IsOnThread())
|
||||
{
|
||||
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
|
||||
_rReturnValue = ReadHigh (fifo.CPWritePointer - fifo.SafeCPReadPointer);
|
||||
else
|
||||
_rReturnValue = ReadHigh (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
|
||||
}
|
||||
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
|
||||
return;
|
||||
case FIFO_WRITE_POINTER_LO:
|
||||
|
@ -437,7 +445,9 @@ void STACKALIGN GatherPipeBursted()
|
|||
if (!m_CPCtrlReg.GPLinkEnable)
|
||||
{
|
||||
if (!IsOnThread())
|
||||
{
|
||||
RunGpu();
|
||||
}
|
||||
else
|
||||
{
|
||||
// In multibuffer mode is not allowed write in the same FIFO attached to the GPU.
|
||||
|
@ -571,9 +581,11 @@ void SetCpStatus(bool isCPUThread)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandProcessor::UpdateInterrupts(userdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessFifoToLoWatermark()
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@ void FreeLookInput( UINT iMsg, WPARAM wParam )
|
|||
static bool mouseMoveEnabled = false;
|
||||
static float lastMouse[2];
|
||||
POINT point;
|
||||
|
||||
switch(iMsg)
|
||||
{
|
||||
case WM_USER_KEYDOWN:
|
||||
|
@ -99,14 +100,16 @@ void FreeLookInput( UINT iMsg, WPARAM wParam )
|
|||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (mouseLookEnabled) {
|
||||
if (mouseLookEnabled)
|
||||
{
|
||||
GetCursorPos(&point);
|
||||
VertexShaderManager::RotateView((point.x - lastMouse[0]) / 200.0f, (point.y - lastMouse[1]) / 200.0f);
|
||||
lastMouse[0] = (float)point.x;
|
||||
lastMouse[1] = (float)point.y;
|
||||
}
|
||||
|
||||
if (mouseMoveEnabled) {
|
||||
if (mouseMoveEnabled)
|
||||
{
|
||||
GetCursorPos(&point);
|
||||
VertexShaderManager::TranslateView((point.x - lastMouse[0]) / 50.0f, (point.y - lastMouse[1]) / 50.0f);
|
||||
lastMouse[0] = (float)point.x;
|
||||
|
|
|
@ -151,7 +151,8 @@ void RunGpuLoop()
|
|||
// check if we are able to run this buffer
|
||||
while (GpuRunningState && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
|
||||
{
|
||||
if (!GpuRunningState) break;
|
||||
if (!GpuRunningState)
|
||||
break;
|
||||
|
||||
fifo.isGpuReadingData = true;
|
||||
CommandProcessor::isPossibleWaitingSetDrawDone = fifo.bFF_GPLinkEnable ? true : false;
|
||||
|
@ -161,8 +162,10 @@ void RunGpuLoop()
|
|||
u32 readPtr = fifo.CPReadPointer;
|
||||
u8 *uData = Memory::GetPointer(readPtr);
|
||||
|
||||
if (readPtr == fifo.CPEnd) readPtr = fifo.CPBase;
|
||||
else readPtr += 32;
|
||||
if (readPtr == fifo.CPEnd)
|
||||
readPtr = fifo.CPBase;
|
||||
else
|
||||
readPtr += 32;
|
||||
|
||||
_assert_msg_(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0 ,
|
||||
"Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce instability in the game. Please report it.", fifo.CPReadWriteDistance - 32);
|
||||
|
@ -236,8 +239,10 @@ void RunGpu()
|
|||
|
||||
//DEBUG_LOG(COMMANDPROCESSOR, "Fifo wraps to base");
|
||||
|
||||
if (fifo.CPReadPointer == fifo.CPEnd) fifo.CPReadPointer = fifo.CPBase;
|
||||
else fifo.CPReadPointer += 32;
|
||||
if (fifo.CPReadPointer == fifo.CPEnd)
|
||||
fifo.CPReadPointer = fifo.CPBase;
|
||||
else
|
||||
fifo.CPReadPointer += 32;
|
||||
|
||||
fifo.CPReadWriteDistance -= 32;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ FramebufferManagerBase::~FramebufferManagerBase()
|
|||
|
||||
const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||
{
|
||||
if (!g_ActiveConfig.bUseXFB) return NULL;
|
||||
if (!g_ActiveConfig.bUseXFB)
|
||||
return NULL;
|
||||
|
||||
if (g_ActiveConfig.bUseRealXFB)
|
||||
return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||
|
@ -237,8 +238,10 @@ int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x, unsigned int backbuffe
|
|||
return x * (int)backbuffer_width / (int)FramebufferManagerBase::LastXfbWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
return x * (int)Renderer::GetTargetRectangle().GetWidth() / (int)FramebufferManagerBase::LastXfbWidth();
|
||||
}
|
||||
}
|
||||
|
||||
int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuffer_height)
|
||||
{
|
||||
|
@ -251,5 +254,7 @@ int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y, unsigned int backbuff
|
|||
return y * (int)backbuffer_height / (int)FramebufferManagerBase::LastXfbHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
return y * (int)Renderer::GetTargetRectangle().GetHeight() / (int)FramebufferManagerBase::LastXfbHeight();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,8 @@ template <bool pr> void IndexGenerator::AddList(u32 const numVerts)
|
|||
|
||||
template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
|
||||
{
|
||||
if(pr) {
|
||||
if(pr)
|
||||
{
|
||||
for (u32 i = 0; i < numVerts; ++i)
|
||||
{
|
||||
*Tptr++ = index + i;
|
||||
|
@ -100,7 +101,9 @@ template <bool pr> void IndexGenerator::AddStrip(u32 const numVerts)
|
|||
*Tptr++ = s_primitive_restart;
|
||||
numT += numVerts - 2;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
bool wind = false;
|
||||
for (u32 i = 2; i < numVerts; ++i)
|
||||
{
|
||||
|
@ -137,8 +140,10 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
|
|||
{
|
||||
u32 i = 2;
|
||||
|
||||
if(pr) {
|
||||
for(; i<=numVerts-3; i+=3) {
|
||||
if(pr)
|
||||
{
|
||||
for(; i<=numVerts-3; i+=3)
|
||||
{
|
||||
*Tptr++ = index + i - 1;
|
||||
*Tptr++ = index + i + 0;
|
||||
*Tptr++ = index;
|
||||
|
@ -148,7 +153,8 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
|
|||
numT += 3;
|
||||
}
|
||||
|
||||
for(; i<=numVerts-2; i+=2) {
|
||||
for(; i<=numVerts-2; i+=2)
|
||||
{
|
||||
*Tptr++ = index + i - 1;
|
||||
*Tptr++ = index + i + 0;
|
||||
*Tptr++ = index;
|
||||
|
@ -186,18 +192,22 @@ template <bool pr> void IndexGenerator::AddQuads(u32 numVerts)
|
|||
auto const numQuads = numVerts / 4;
|
||||
for (u32 i = 0; i != numQuads; ++i)
|
||||
{
|
||||
if(pr) {
|
||||
if(pr)
|
||||
{
|
||||
*Tptr++ = index + i * 4 + 1;
|
||||
*Tptr++ = index + i * 4 + 2;
|
||||
*Tptr++ = index + i * 4 + 0;
|
||||
*Tptr++ = index + i * 4 + 3;
|
||||
*Tptr++ = s_primitive_restart;
|
||||
numT += 2;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTriangle<pr>(index + i * 4, index + i * 4 + 1, index + i * 4 + 2);
|
||||
WriteTriangle<pr>(index + i * 4, index + i * 4 + 2, index + i * 4 + 3);
|
||||
}
|
||||
}
|
||||
|
||||
// three vertices remaining, so render a triangle
|
||||
u32 remainingVerts = numVerts - numQuads*4;
|
||||
if(remainingVerts == 3)
|
||||
|
@ -205,8 +215,10 @@ template <bool pr> void IndexGenerator::AddQuads(u32 numVerts)
|
|||
WriteTriangle<pr>(index+numVerts-3, index+numVerts-2, index+numVerts-1);
|
||||
}
|
||||
else if(remainingVerts)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "AddQuads: unknown count of vertices found");
|
||||
}
|
||||
}
|
||||
|
||||
// Lines
|
||||
void IndexGenerator::AddLineList(u32 numVerts)
|
||||
|
|
|
@ -27,12 +27,17 @@ int GetLightingShaderId(u32* out)
|
|||
char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char* lightsName, int coloralpha)
|
||||
{
|
||||
const char* swizzle = "xyzw";
|
||||
if (coloralpha == 1 ) swizzle = "xyz";
|
||||
else if (coloralpha == 2 ) swizzle = "w";
|
||||
|
||||
if (!(chan.attnfunc & 1)) {
|
||||
// atten disabled
|
||||
switch (chan.diffusefunc) {
|
||||
if (coloralpha == 1 )
|
||||
swizzle = "xyz";
|
||||
else if (coloralpha == 2 )
|
||||
swizzle = "w";
|
||||
|
||||
if (!(chan.attnfunc & 1))
|
||||
{
|
||||
// attenuation disabled
|
||||
switch (chan.diffusefunc)
|
||||
{
|
||||
case LIGHTDIF_NONE:
|
||||
WRITE(p, "lacc.%s += %s[%d].%s;\n", swizzle, lightsName, index * 5, swizzle);
|
||||
break;
|
||||
|
@ -45,8 +50,8 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char
|
|||
default: _assert_(0);
|
||||
}
|
||||
}
|
||||
else { // spec and spot
|
||||
|
||||
else // spec and spot
|
||||
{
|
||||
if (chan.attnfunc == 3)
|
||||
{ // spot
|
||||
WRITE(p, "ldir = %s[%d + 3].xyz - pos.xyz;\n", lightsName, index * 5);
|
||||
|
@ -98,7 +103,8 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
|
|||
|
||||
WRITE(p, "{\n");
|
||||
|
||||
if (color.matsource) {// from vertex
|
||||
if (color.matsource) // from vertex
|
||||
{
|
||||
if (components & (VB_HAS_COL0 << j))
|
||||
WRITE(p, "mat = %s%d;\n", inColorName, j);
|
||||
else if (components & VB_HAS_COL0)
|
||||
|
@ -107,10 +113,14 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
|
|||
WRITE(p, "mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
|
||||
}
|
||||
else // from color
|
||||
{
|
||||
WRITE(p, "mat = %s[%d];\n", materialsName, j+2);
|
||||
}
|
||||
|
||||
if (color.enablelighting) {
|
||||
if (color.ambsource) { // from vertex
|
||||
if (color.enablelighting)
|
||||
{
|
||||
if (color.ambsource) // from vertex
|
||||
{
|
||||
if (components & (VB_HAS_COL0<<j) )
|
||||
WRITE(p, "lacc = %s%d;\n", inColorName, j);
|
||||
else if (components & VB_HAS_COL0 )
|
||||
|
@ -119,16 +129,20 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
|
|||
WRITE(p, "lacc = float4(0.0f, 0.0f, 0.0f, 0.0f);\n");
|
||||
}
|
||||
else // from color
|
||||
{
|
||||
WRITE(p, "lacc = %s[%d];\n", materialsName, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "lacc = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
|
||||
}
|
||||
|
||||
// check if alpha is different
|
||||
if (alpha.matsource != color.matsource) {
|
||||
if (alpha.matsource) {// from vertex
|
||||
if (alpha.matsource != color.matsource)
|
||||
{
|
||||
if (alpha.matsource) // from vertex
|
||||
{
|
||||
if (components & (VB_HAS_COL0<<j))
|
||||
WRITE(p, "mat.w = %s%d.w;\n", inColorName, j);
|
||||
else if (components & VB_HAS_COL0)
|
||||
|
@ -136,12 +150,15 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
|
|||
else WRITE(p, "mat.w = 1.0f;\n");
|
||||
}
|
||||
else // from color
|
||||
{
|
||||
WRITE(p, "mat.w = %s[%d].w;\n", materialsName, j+2);
|
||||
}
|
||||
}
|
||||
|
||||
if (alpha.enablelighting)
|
||||
{
|
||||
if (alpha.ambsource) {// from vertex
|
||||
if (alpha.ambsource) // from vertex
|
||||
{
|
||||
if (components & (VB_HAS_COL0<<j) )
|
||||
WRITE(p, "lacc.w = %s%d.w;\n", inColorName, j);
|
||||
else if (components & VB_HAS_COL0 )
|
||||
|
@ -150,8 +167,10 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName,
|
|||
WRITE(p, "lacc.w = 0.0f;\n");
|
||||
}
|
||||
else // from color
|
||||
{
|
||||
WRITE(p, "lacc.w = %s[%d].w;\n", materialsName, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "lacc.w = 1.0f;\n");
|
||||
|
|
|
@ -230,9 +230,13 @@ void VideoBackendHardware::DoState(PointerWrap& p)
|
|||
{
|
||||
bool software = false;
|
||||
p.Do(software);
|
||||
|
||||
if (p.GetMode() == PointerWrap::MODE_READ && software == true)
|
||||
{
|
||||
// change mode to abort load of incompatible save state.
|
||||
p.SetMode(PointerWrap::MODE_VERIFY);
|
||||
}
|
||||
|
||||
VideoCommon_DoState(p);
|
||||
p.DoMarker("VideoCommon");
|
||||
|
||||
|
@ -255,7 +259,8 @@ void VideoBackendHardware::DoState(PointerWrap& p)
|
|||
}
|
||||
}
|
||||
|
||||
void VideoBackendHardware::CheckInvalidState() {
|
||||
void VideoBackendHardware::CheckInvalidState()
|
||||
{
|
||||
if (m_invalid)
|
||||
{
|
||||
m_invalid = false;
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#include "Common.h"
|
||||
|
||||
// m_components
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
VB_HAS_POSMTXIDX =(1<<1),
|
||||
VB_HAS_TEXMTXIDX0=(1<<2),
|
||||
VB_HAS_TEXMTXIDX1=(1<<3),
|
||||
|
|
|
@ -19,7 +19,8 @@ namespace OSD
|
|||
struct MESSAGE
|
||||
{
|
||||
MESSAGE() {}
|
||||
MESSAGE(const char* p, u32 dw) {
|
||||
MESSAGE(const char* p, u32 dw)
|
||||
{
|
||||
strncpy(str, p, 255);
|
||||
str[255] = '\0';
|
||||
dwTimeStamp = dw;
|
||||
|
@ -45,8 +46,10 @@ public:
|
|||
{
|
||||
m_functionptr(m_data);
|
||||
}
|
||||
|
||||
CallbackType Type() { return m_type; }
|
||||
};
|
||||
|
||||
std::vector<OSDCALLBACK> m_callbacks;
|
||||
static std::list<MESSAGE> s_listMsgs;
|
||||
|
||||
|
@ -57,7 +60,8 @@ void AddMessage(const char* pstr, u32 ms)
|
|||
|
||||
void DrawMessages()
|
||||
{
|
||||
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages) return;
|
||||
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages)
|
||||
return;
|
||||
|
||||
if (s_listMsgs.size() > 0)
|
||||
{
|
||||
|
@ -71,7 +75,8 @@ void DrawMessages()
|
|||
if (time_left < 1024)
|
||||
{
|
||||
alpha = time_left >> 2;
|
||||
if (time_left < 0) alpha = 0;
|
||||
if (time_left < 0)
|
||||
alpha = 0;
|
||||
}
|
||||
|
||||
alpha <<= 24;
|
||||
|
@ -91,9 +96,12 @@ void DrawMessages()
|
|||
void ClearMessages()
|
||||
{
|
||||
std::list<MESSAGE>::iterator it = s_listMsgs.begin();
|
||||
|
||||
while (it != s_listMsgs.end())
|
||||
{
|
||||
it = s_listMsgs.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// On-Screen Display Callbacks
|
||||
void AddCallback(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData)
|
||||
|
@ -104,8 +112,10 @@ void AddCallback(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData)
|
|||
void DoCallbacks(CallbackType OnType)
|
||||
{
|
||||
for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
|
||||
{
|
||||
if (it->Type() == OnType)
|
||||
it->Call();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -61,7 +61,8 @@ static void StageHash(u32 stage, u32* out)
|
|||
out[3] |= bpmem.tevorders[stage/2].getEnable(stage&1);
|
||||
if (bpmem.tevorders[stage/2].getEnable(stage&1))
|
||||
{
|
||||
if (bHasIndStage) needstexcoord = true;
|
||||
if (bHasIndStage)
|
||||
needstexcoord = true;
|
||||
|
||||
out[0] |= bpmem.combiners[stage].alphaC.tswap;
|
||||
out[3] |= bpmem.tevksel[bpmem.combiners[stage].alphaC.tswap*2].swap1 << 1; // 2
|
||||
|
@ -98,20 +99,27 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
|
|||
bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
|
||||
uid->values[0] |= enablePL << 10; // 1
|
||||
|
||||
if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
|
||||
if (!enablePL)
|
||||
{
|
||||
uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
|
||||
}
|
||||
|
||||
AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult();
|
||||
uid->values[0] |= alphaPreTest << 15; // 2
|
||||
|
||||
// numtexgens should be <= 8
|
||||
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i)
|
||||
{
|
||||
uid->values[0] |= xfregs.texMtxInfo[i].projection << (17+i); // 1
|
||||
}
|
||||
|
||||
uid->values[1] = bpmem.genMode.numindstages; // 3
|
||||
u32 indirectStagesUsed = 0;
|
||||
for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i)
|
||||
{
|
||||
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
||||
indirectStagesUsed |= (1 << bpmem.tevind[i].bt);
|
||||
}
|
||||
|
||||
assert(indirectStagesUsed == (indirectStagesUsed & 0xF));
|
||||
|
||||
|
@ -255,7 +263,7 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::
|
|||
//
|
||||
// color for this stage (alpha, color) is given by bpmem.tevorders[0].colorchan0
|
||||
// konstant for this stage (alpha, color) is given by bpmem.tevksel
|
||||
// inputs are given by bpmem.combiners[0].colorC.a/b/c/d << could be current chan color
|
||||
// inputs are given by bpmem.combiners[0].colorC.a/b/c/d << could be current channel color
|
||||
// according to GXTevColorArg table above
|
||||
// output is given by .outreg
|
||||
// tevtemp is set according to swapmodetables and
|
||||
|
@ -407,7 +415,7 @@ static const char *tevAInputTable[] = // CA
|
|||
"rastemp", // RASA,
|
||||
"konsttemp", // KONST, (hw1 had quarter)
|
||||
"float4(0.0f, 0.0f, 0.0f, 0.0f)", // ZERO
|
||||
///aded extra values to map clamped values
|
||||
///added extra values to map clamped values
|
||||
"cprev", // APREV,
|
||||
"cc0", // A0,
|
||||
"cc1", // A1,
|
||||
|
@ -827,7 +835,9 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
|
|||
}
|
||||
|
||||
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
|
||||
{
|
||||
WRITE(p, "\tocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteFog(p);
|
||||
|
@ -959,10 +969,14 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
|
|||
WRITE(p, "float2 indtevtrans%d = " I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "float2 indtevtrans%d = float2(0.0f, 0.0f);\n", n);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "float2 indtevtrans%d = float2(0.0f, 0.0f);\n", n);
|
||||
}
|
||||
|
||||
// ---------
|
||||
// Wrapping
|
||||
|
@ -1022,7 +1036,9 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
|
|||
SampleTexture(p, "textemp", "tevcoord", texswap, texmap, ApiType);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "textemp = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
|
||||
}
|
||||
|
||||
|
||||
if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST || cc.d == TEVCOLORARG_KONST
|
||||
|
@ -1275,7 +1291,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
|
|||
// or after texturing and alpha test. PC GPUs have no way to support this
|
||||
// feature properly as of 2012: depth buffer and depth test are not
|
||||
// programmable and the depth test is always done after texturing.
|
||||
// Most importantly, PC GPUs do not allow writing to the z buffer without
|
||||
// Most importantly, PC GPUs do not allow writing to the z-buffer without
|
||||
// writing a color value (unless color writing is disabled altogether).
|
||||
// We implement "depth test before texturing" by discarding the fragment
|
||||
// when the alpha test fail. This is not a correct implementation because
|
||||
|
|
|
@ -62,23 +62,30 @@ public:
|
|||
_PIXELSHADERUID(const _PIXELSHADERUID& r)
|
||||
{
|
||||
num_values = r.num_values;
|
||||
if (safe) memcpy(values, r.values, PIXELSHADERUID_MAX_VALUES_SAFE);
|
||||
else memcpy(values, r.values, r.GetNumValues() * sizeof(values[0]));
|
||||
|
||||
if (safe)
|
||||
memcpy(values, r.values, PIXELSHADERUID_MAX_VALUES_SAFE);
|
||||
else
|
||||
memcpy(values, r.values, r.GetNumValues() * sizeof(values[0]));
|
||||
}
|
||||
|
||||
int GetNumValues() const
|
||||
{
|
||||
if (safe) return (sizeof(values) / sizeof(u32));
|
||||
else return num_values;
|
||||
if (safe)
|
||||
return (sizeof(values) / sizeof(u32));
|
||||
else
|
||||
return num_values;
|
||||
}
|
||||
|
||||
bool operator <(const _PIXELSHADERUID& _Right) const
|
||||
{
|
||||
int N = GetNumValues();
|
||||
|
||||
if (N < _Right.GetNumValues())
|
||||
return true;
|
||||
else if (N > _Right.GetNumValues())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
if (values[i] < _Right.values[i])
|
||||
|
@ -86,22 +93,27 @@ public:
|
|||
else if (values[i] > _Right.values[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator ==(const _PIXELSHADERUID& _Right) const
|
||||
{
|
||||
int N = GetNumValues();
|
||||
|
||||
if (N != _Right.GetNumValues())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
if (values[i] != _Right.values[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef _PIXELSHADERUID<false> PIXELSHADERUID;
|
||||
typedef _PIXELSHADERUID<true> PIXELSHADERUIDSAFE;
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ void PixelShaderManager::SetConstants()
|
|||
{
|
||||
if (g_ActiveConfig.backend_info.APIType == API_OPENGL && !g_ActiveConfig.backend_info.bSupportsGLSLUBO)
|
||||
Dirty();
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (s_nColorsChanged[i])
|
||||
|
@ -158,8 +159,10 @@ void PixelShaderManager::SetConstants()
|
|||
SetPSConstant4fv(C_INDTEXSCALE, f);
|
||||
}
|
||||
|
||||
if (s_nIndTexScaleChanged & 0x0c) {
|
||||
for (u32 i = 2; i < 4; ++i) {
|
||||
if (s_nIndTexScaleChanged & 0x0c)
|
||||
{
|
||||
for (u32 i = 2; i < 4; ++i)
|
||||
{
|
||||
f[2 * i] = bpmem.texscale[1].getScaleS(i & 1);
|
||||
f[2 * i + 1] = bpmem.texscale[1].getScaleT(i & 1);
|
||||
PRIM_LOG("tex indscale%d: %f %f\n", i, f[2 * i], f[2 * i + 1]);
|
||||
|
@ -243,7 +246,9 @@ void PixelShaderManager::SetConstants()
|
|||
SetPSConstant4f(C_FOG + 2, ScreenSpaceCenter, (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd)), bpmem.fogRange.K[4].HI / 256.0f,0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPSConstant4f(C_FOG + 2, 0.0f, 1.0f, 1.0f, 0.0f); // Need to update these values for older hardware that fails to divide by zero in shaders.
|
||||
}
|
||||
|
||||
s_bFogRangeAdjustChanged = false;
|
||||
}
|
||||
|
@ -279,9 +284,11 @@ void PixelShaderManager::SetConstants()
|
|||
SetPSConstant4f(C_PLIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPSConstant4fv(C_PLIGHTS+5*i+j+1, xfmemptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nLightsChanged[0] = nLightsChanged[1] = -1;
|
||||
}
|
||||
|
@ -347,17 +354,22 @@ void PixelShaderManager::SetPSTextureDims(int texid)
|
|||
void PixelShaderManager::SetColorChanged(int type, int num, bool high)
|
||||
{
|
||||
float *pf = &lastRGBAfull[type][num][0];
|
||||
if (!high) {
|
||||
|
||||
if (!high)
|
||||
{
|
||||
int r = bpmem.tevregs[num].low.a;
|
||||
int a = bpmem.tevregs[num].low.b;
|
||||
pf[0] = (float)r * (1.0f / 255.0f);
|
||||
pf[3] = (float)a * (1.0f / 255.0f);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int b = bpmem.tevregs[num].high.a;
|
||||
int g = bpmem.tevregs[num].high.b;
|
||||
pf[1] = (float)g * (1.0f / 255.0f);
|
||||
pf[2] = (float)b * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
s_nColorsChanged[type] |= 1 << num;
|
||||
PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,8 @@ char *Statistics::ToString(char *ptr)
|
|||
}
|
||||
|
||||
// Is this really needed?
|
||||
char *Statistics::ToStringProj(char *ptr) {
|
||||
char *Statistics::ToStringProj(char *ptr)
|
||||
{
|
||||
char *p = ptr;
|
||||
p+=sprintf(p,"Projection #: X for Raw 6=0 (X for Raw 6!=0)\n\n");
|
||||
p+=sprintf(p,"Projection 0: %f (%f) Raw 0: %f\n", stats.gproj_0, stats.g2proj_0, stats.proj_0);
|
||||
|
|
|
@ -42,9 +42,12 @@ TextureCache::TextureCache()
|
|||
temp_size = 2048 * 2048 * 4;
|
||||
if (!temp)
|
||||
temp = (u8*)AllocateAlignedMemory(temp_size, 16);
|
||||
|
||||
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
||||
|
||||
if(g_ActiveConfig.bHiresTextures && !g_ActiveConfig.bDumpTextures)
|
||||
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
|
||||
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
|
||||
}
|
||||
|
||||
|
@ -125,9 +128,11 @@ void TextureCache::Cleanup()
|
|||
textures.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
||||
{
|
||||
|
@ -143,9 +148,11 @@ void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
|||
textures.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache::MakeRangeDynamic(u32 start_address, u32 size)
|
||||
{
|
||||
|
@ -201,9 +208,11 @@ void TextureCache::ClearRenderTargets()
|
|||
textures.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels)
|
||||
{
|
||||
|
@ -547,17 +556,20 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
|
|||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||
{
|
||||
// Emulation methods:
|
||||
//
|
||||
// - EFB to RAM:
|
||||
// Encodes the requested EFB data at its native resolution to the emulated RAM using shaders.
|
||||
// Load() decodes the data from there again (using TextureDecoder) if the EFB copy is being used as a texture again.
|
||||
// Advantage: CPU can read data from the EFB copy and we don't lose any important updates to the texture
|
||||
// Disadvantage: Encoding+decoding steps often are redundant because only some games read or modify EFB copies before using them as textures.
|
||||
//
|
||||
// - EFB to texture:
|
||||
// Copies the requested EFB data to a texture object in VRAM, performing any color conversion using shaders.
|
||||
// Advantage: Works for many games, since in most cases EFB copies aren't read or modified at all before being used as a texture again.
|
||||
// Since we don't do any further encoding or decoding here, this method is much faster.
|
||||
// It also allows enhancing the visual quality by doing scaled EFB copies.
|
||||
// - hybrid EFB copies:
|
||||
//
|
||||
// - Hybrid EFB copies:
|
||||
// 1a) Whenever this function gets called, encode the requested EFB data to RAM (like EFB to RAM)
|
||||
// 1b) Set type to TCET_EC_DYNAMIC for all texture cache entries in the destination address range.
|
||||
// If EFB copy caching is enabled, further checks will (try to) prevent redundant EFB copies.
|
||||
|
|
|
@ -124,7 +124,8 @@ private:
|
|||
static TexCache textures;
|
||||
|
||||
// Backup configuration values
|
||||
static struct BackupConfig {
|
||||
static struct BackupConfig
|
||||
{
|
||||
int s_colorsamples;
|
||||
bool s_copy_efb_to_texture;
|
||||
bool s_copy_efb_scaled;
|
||||
|
|
|
@ -26,7 +26,8 @@ namespace TextureConversionShader
|
|||
|
||||
u16 GetEncodedSampleCount(u32 format)
|
||||
{
|
||||
switch (format) {
|
||||
switch (format)
|
||||
{
|
||||
case GX_TF_I4: return 8;
|
||||
case GX_TF_I8: return 4;
|
||||
case GX_TF_IA4: return 4;
|
||||
|
|
|
@ -214,7 +214,7 @@ void VertexLoader::CompileVertexTranslator()
|
|||
|
||||
#ifdef USE_JIT
|
||||
if (m_compiledCode)
|
||||
PanicAlert("Trying to recompile a vtx translator");
|
||||
PanicAlert("Trying to recompile a vertex translator");
|
||||
|
||||
m_compiledCode = GetCodePtr();
|
||||
ABI_EmitPrologue(4);
|
||||
|
@ -224,14 +224,17 @@ void VertexLoader::CompileVertexTranslator()
|
|||
|
||||
// Reset component counters if present in vertex format only.
|
||||
if (m_VtxDesc.Tex0Coord || m_VtxDesc.Tex1Coord || m_VtxDesc.Tex2Coord || m_VtxDesc.Tex3Coord ||
|
||||
m_VtxDesc.Tex4Coord || m_VtxDesc.Tex5Coord || m_VtxDesc.Tex6Coord || m_VtxDesc.Tex7Coord) {
|
||||
m_VtxDesc.Tex4Coord || m_VtxDesc.Tex5Coord || m_VtxDesc.Tex6Coord || m_VtxDesc.Tex7Coord)
|
||||
{
|
||||
WriteSetVariable(32, &tcIndex, Imm32(0));
|
||||
}
|
||||
if (m_VtxDesc.Color0 || m_VtxDesc.Color1) {
|
||||
if (m_VtxDesc.Color0 || m_VtxDesc.Color1)
|
||||
{
|
||||
WriteSetVariable(32, &colIndex, Imm32(0));
|
||||
}
|
||||
if (m_VtxDesc.Tex0MatIdx || m_VtxDesc.Tex1MatIdx || m_VtxDesc.Tex2MatIdx || m_VtxDesc.Tex3MatIdx ||
|
||||
m_VtxDesc.Tex4MatIdx || m_VtxDesc.Tex5MatIdx || m_VtxDesc.Tex6MatIdx || m_VtxDesc.Tex7MatIdx) {
|
||||
m_VtxDesc.Tex4MatIdx || m_VtxDesc.Tex5MatIdx || m_VtxDesc.Tex6MatIdx || m_VtxDesc.Tex7MatIdx)
|
||||
{
|
||||
WriteSetVariable(32, &s_texmtxwrite, Imm32(0));
|
||||
WriteSetVariable(32, &s_texmtxread, Imm32(0));
|
||||
}
|
||||
|
@ -258,14 +261,16 @@ void VertexLoader::CompileVertexTranslator()
|
|||
int nat_offset = 0;
|
||||
PortableVertexDeclaration vtx_decl;
|
||||
memset(&vtx_decl, 0, sizeof(vtx_decl));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vtx_decl.texcoord_offset[i] = -1;
|
||||
}
|
||||
|
||||
// m_VBVertexStride for texmtx and posmtx is computed later when writing.
|
||||
|
||||
// Position Matrix Index
|
||||
if (m_VtxDesc.PosMatIdx) {
|
||||
if (m_VtxDesc.PosMatIdx)
|
||||
{
|
||||
WriteCall(PosMtx_ReadDirect_UByte);
|
||||
m_NativeFmt->m_components |= VB_HAS_POSMTXIDX;
|
||||
m_VertexSize += 1;
|
||||
|
@ -281,11 +286,14 @@ void VertexLoader::CompileVertexTranslator()
|
|||
if (m_VtxDesc.Tex7MatIdx) {m_VertexSize += 1; m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); }
|
||||
|
||||
// Write vertex position loader
|
||||
if(g_ActiveConfig.bUseBBox) {
|
||||
if(g_ActiveConfig.bUseBBox)
|
||||
{
|
||||
WriteCall(UpdateBoundingBoxPrepare);
|
||||
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
|
||||
WriteCall(UpdateBoundingBox);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
|
||||
}
|
||||
m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements);
|
||||
|
@ -317,7 +325,9 @@ void VertexLoader::CompileVertexTranslator()
|
|||
vtx_decl.normal_gl_size = 3;
|
||||
vtx_decl.normal_offset[0] = nat_offset;
|
||||
nat_offset += 12;
|
||||
if (vtx_attr.NormalElements) {
|
||||
|
||||
if (vtx_attr.NormalElements)
|
||||
{
|
||||
vtx_decl.normal_offset[1] = nat_offset;
|
||||
nat_offset += 12;
|
||||
vtx_decl.normal_offset[2] = nat_offset;
|
||||
|
@ -334,7 +344,8 @@ void VertexLoader::CompileVertexTranslator()
|
|||
vtx_decl.color_gl_type = VAR_UNSIGNED_BYTE;
|
||||
vtx_decl.color_offset[0] = -1;
|
||||
vtx_decl.color_offset[1] = -1;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_NativeFmt->m_components |= VB_HAS_COL0 << i;
|
||||
switch (col[i])
|
||||
{
|
||||
|
@ -382,21 +393,26 @@ void VertexLoader::CompileVertexTranslator()
|
|||
break;
|
||||
}
|
||||
// Common for the three bottom cases
|
||||
if (col[i] != NOT_PRESENT) {
|
||||
if (col[i] != NOT_PRESENT)
|
||||
{
|
||||
vtx_decl.color_offset[i] = nat_offset;
|
||||
nat_offset += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Texture matrix indices (remove if corresponding texture coordinate isn't enabled)
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vtx_decl.texcoord_offset[i] = -1;
|
||||
const int format = m_VtxAttr.texCoord[i].Format;
|
||||
const int elements = m_VtxAttr.texCoord[i].Elements;
|
||||
|
||||
if (tc[i] == NOT_PRESENT) {
|
||||
if (tc[i] == NOT_PRESENT)
|
||||
{
|
||||
m_NativeFmt->m_components &= ~(VB_HAS_UV0 << i);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_assert_msg_(VIDEO, DIRECT <= tc[i] && tc[i] <= INDEX16, "Invalid texture coordinates!\n(tc[i] = %d)", tc[i]);
|
||||
_assert_msg_(VIDEO, FORMAT_UBYTE <= format && format <= FORMAT_FLOAT, "Invalid texture coordinates format!\n(format = %d)", format);
|
||||
_assert_msg_(VIDEO, 0 <= elements && elements <= 1, "Invalid number of texture coordinates elements!\n(elements = %d)", elements);
|
||||
|
@ -406,8 +422,10 @@ void VertexLoader::CompileVertexTranslator()
|
|||
m_VertexSize += VertexLoader_TextCoord::GetSize(tc[i], format, elements);
|
||||
}
|
||||
|
||||
if (m_NativeFmt->m_components & (VB_HAS_TEXMTXIDX0 << i)) {
|
||||
if (tc[i] != NOT_PRESENT) {
|
||||
if (m_NativeFmt->m_components & (VB_HAS_TEXMTXIDX0 << i))
|
||||
{
|
||||
if (tc[i] != NOT_PRESENT)
|
||||
{
|
||||
// if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index
|
||||
vtx_decl.texcoord_offset[i] = nat_offset;
|
||||
vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
|
||||
|
@ -415,7 +433,8 @@ void VertexLoader::CompileVertexTranslator()
|
|||
nat_offset += 12;
|
||||
WriteCall(m_VtxAttr.texCoord[i].Elements ? TexMtx_Write_Float : TexMtx_Write_Float2);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
m_NativeFmt->m_components |= VB_HAS_UV0 << i; // have to include since using now
|
||||
vtx_decl.texcoord_offset[i] = nat_offset;
|
||||
vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
|
||||
|
@ -424,8 +443,10 @@ void VertexLoader::CompileVertexTranslator()
|
|||
WriteCall(TexMtx_Write_Float4);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tc[i] != NOT_PRESENT) {
|
||||
else
|
||||
{
|
||||
if (tc[i] != NOT_PRESENT)
|
||||
{
|
||||
vtx_decl.texcoord_offset[i] = nat_offset;
|
||||
vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
|
||||
vtx_decl.texcoord_size[i] = vtx_attr.texCoord[i].Elements ? 2 : 1;
|
||||
|
@ -433,28 +454,35 @@ void VertexLoader::CompileVertexTranslator()
|
|||
}
|
||||
}
|
||||
|
||||
if (tc[i] == NOT_PRESENT) {
|
||||
if (tc[i] == NOT_PRESENT)
|
||||
{
|
||||
// if there's more tex coords later, have to write a dummy call
|
||||
int j = i + 1;
|
||||
for (; j < 8; ++j) {
|
||||
if (tc[j] != NOT_PRESENT) {
|
||||
for (; j < 8; ++j)
|
||||
{
|
||||
if (tc[j] != NOT_PRESENT)
|
||||
{
|
||||
WriteCall(VertexLoader_TextCoord::GetDummyFunction()); // important to get indices right!
|
||||
break;
|
||||
}
|
||||
}
|
||||
// tricky!
|
||||
if (j == 8 && !((m_NativeFmt->m_components & VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL << (i + 1)))) {
|
||||
if (j == 8 && !((m_NativeFmt->m_components & VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL << (i + 1))))
|
||||
{
|
||||
// no more tex coords and tex matrices, so exit loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_VtxDesc.PosMatIdx) {
|
||||
if (m_VtxDesc.PosMatIdx)
|
||||
{
|
||||
WriteCall(PosMtx_Write);
|
||||
vtx_decl.posmtx_offset = nat_offset;
|
||||
nat_offset += 4;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
vtx_decl.posmtx_offset = -1;
|
||||
}
|
||||
|
||||
|
@ -574,7 +602,8 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const coun
|
|||
void VertexLoader::ConvertVertices ( int count )
|
||||
{
|
||||
#ifdef USE_JIT
|
||||
if (count > 0) {
|
||||
if (count > 0)
|
||||
{
|
||||
loop_counter = count;
|
||||
((void (*)())(void*)m_compiledCode)();
|
||||
}
|
||||
|
@ -678,10 +707,13 @@ void VertexLoader::AppendToString(std::string *dest) const
|
|||
dest->append(StringFromFormat("%ib skin: %i P: %i %s-%s ",
|
||||
m_VertexSize, m_VtxDesc.PosMatIdx,
|
||||
m_VtxAttr.PosElements ? 3 : 2, posMode[m_VtxDesc.Position], posFormats[m_VtxAttr.PosFormat]));
|
||||
if (m_VtxDesc.Normal) {
|
||||
|
||||
if (m_VtxDesc.Normal)
|
||||
{
|
||||
dest->append(StringFromFormat("Nrm: %i %s-%s ",
|
||||
m_VtxAttr.NormalElements, posMode[m_VtxDesc.Normal], posFormats[m_VtxAttr.NormalFormat]));
|
||||
}
|
||||
|
||||
u32 color_mode[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
|
|
|
@ -24,8 +24,12 @@ class VertexLoaderUID
|
|||
u32 vid[5];
|
||||
size_t hash;
|
||||
public:
|
||||
VertexLoaderUID() {}
|
||||
void InitFromCurrentState(int vtx_attr_group) {
|
||||
VertexLoaderUID()
|
||||
{
|
||||
}
|
||||
|
||||
void InitFromCurrentState(int vtx_attr_group)
|
||||
{
|
||||
vid[0] = g_VtxDesc.Hex & 0xFFFFFFFF;
|
||||
vid[1] = g_VtxDesc.Hex >> 32;
|
||||
vid[2] = g_VtxAttr[vtx_attr_group].g0.Hex & ~VAT_0_FRACBITS;
|
||||
|
@ -33,32 +37,47 @@ public:
|
|||
vid[4] = g_VtxAttr[vtx_attr_group].g2.Hex & ~VAT_2_FRACBITS;
|
||||
hash = CalculateHash();
|
||||
}
|
||||
bool operator < (const VertexLoaderUID &other) const {
|
||||
|
||||
bool operator < (const VertexLoaderUID &other) const
|
||||
{
|
||||
// This is complex because of speed.
|
||||
if (vid[0] < other.vid[0])
|
||||
return true;
|
||||
else if (vid[0] > other.vid[0])
|
||||
return false;
|
||||
for (int i = 1; i < 5; ++i) {
|
||||
|
||||
for (int i = 1; i < 5; ++i)
|
||||
{
|
||||
if (vid[i] < other.vid[i])
|
||||
return true;
|
||||
else if (vid[i] > other.vid[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool operator == (const VertexLoaderUID& rh) const {
|
||||
|
||||
bool operator == (const VertexLoaderUID& rh) const
|
||||
{
|
||||
return hash == rh.hash && std::equal(vid, vid + sizeof(vid) / sizeof(vid[0]), rh.vid);
|
||||
}
|
||||
size_t GetHash() const {
|
||||
|
||||
size_t GetHash() const
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t CalculateHash() {
|
||||
|
||||
size_t CalculateHash()
|
||||
{
|
||||
size_t h = -1;
|
||||
for (unsigned int i = 0; i < sizeof(vid) / sizeof(vid[0]); ++i) {
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(vid) / sizeof(vid[0]); ++i)
|
||||
{
|
||||
h = h * 137 + vid[i];
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -57,11 +57,14 @@ void Shutdown()
|
|||
g_VertexLoaderMap.clear();
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct entry {
|
||||
namespace
|
||||
{
|
||||
struct entry
|
||||
{
|
||||
std::string text;
|
||||
u64 num_verts;
|
||||
bool operator < (const entry &other) const {
|
||||
bool operator < (const entry &other) const
|
||||
{
|
||||
return num_verts > other.num_verts;
|
||||
}
|
||||
};
|
||||
|
@ -82,7 +85,8 @@ void AppendListToString(std::string *dest)
|
|||
}
|
||||
sort(entries.begin(), entries.end());
|
||||
dest->reserve(dest->size() + total_size);
|
||||
for (std::vector<entry>::const_iterator iter = entries.begin(); iter != entries.end(); ++iter) {
|
||||
for (std::vector<entry>::const_iterator iter = entries.begin(); iter != entries.end(); ++iter)
|
||||
{
|
||||
dest->append(iter->text);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,8 @@ void LOADERDECL Color_ReadDirect_24b_888()
|
|||
DataSkip(3);
|
||||
}
|
||||
|
||||
void LOADERDECL Color_ReadDirect_32b_888x(){
|
||||
void LOADERDECL Color_ReadDirect_32b_888x()
|
||||
{
|
||||
_SetCol(_Read24(DataGetPosition()));
|
||||
DataSkip(4);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,9 @@ __forceinline float FracAdjust(T val)
|
|||
|
||||
template <>
|
||||
__forceinline float FracAdjust(float val)
|
||||
{ return val; }
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
__forceinline void ReadIndirect(const T* data)
|
||||
|
|
|
@ -68,7 +68,9 @@ float PosScale(T val)
|
|||
|
||||
template <>
|
||||
float PosScale(float val)
|
||||
{ return val; }
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void LOADERDECL Pos_ReadDirect()
|
||||
|
@ -166,11 +168,13 @@ static int tableReadPositionVertexSize[4][8][2] = {
|
|||
};
|
||||
|
||||
|
||||
void VertexLoader_Position::Init(void) {
|
||||
void VertexLoader_Position::Init(void)
|
||||
{
|
||||
|
||||
#if _M_SSE >= 0x301
|
||||
|
||||
if (cpu_info.bSSSE3) {
|
||||
if (cpu_info.bSSSE3)
|
||||
{
|
||||
tableReadPosition[2][4][0] = Pos_ReadIndex_Float_SSSE3<u8, false>;
|
||||
tableReadPosition[2][4][1] = Pos_ReadIndex_Float_SSSE3<u8, true>;
|
||||
tableReadPosition[3][4][0] = Pos_ReadIndex_Float_SSSE3<u16, false>;
|
||||
|
@ -181,10 +185,12 @@ void VertexLoader_Position::Init(void) {
|
|||
|
||||
}
|
||||
|
||||
unsigned int VertexLoader_Position::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements) {
|
||||
unsigned int VertexLoader_Position::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements)
|
||||
{
|
||||
return tableReadPositionVertexSize[_type][_format][_elements];
|
||||
}
|
||||
|
||||
TPipelineFunction VertexLoader_Position::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements) {
|
||||
TPipelineFunction VertexLoader_Position::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements)
|
||||
{
|
||||
return tableReadPosition[_type][_format][_elements];
|
||||
}
|
||||
|
|
|
@ -48,7 +48,9 @@ float TCScale(T val)
|
|||
|
||||
template <>
|
||||
float TCScale(float val)
|
||||
{ return val; }
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void LOADERDECL TexCoord_ReadDirect()
|
||||
|
@ -166,7 +168,8 @@ static int tableReadTexCoordVertexSize[4][8][2] = {
|
|||
},
|
||||
};
|
||||
|
||||
void VertexLoader_TextCoord::Init(void) {
|
||||
void VertexLoader_TextCoord::Init(void)
|
||||
{
|
||||
|
||||
#if _M_SSE >= 0x301
|
||||
|
||||
|
@ -190,14 +193,17 @@ void VertexLoader_TextCoord::Init(void) {
|
|||
|
||||
}
|
||||
|
||||
unsigned int VertexLoader_TextCoord::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements) {
|
||||
unsigned int VertexLoader_TextCoord::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements)
|
||||
{
|
||||
return tableReadTexCoordVertexSize[_type][_format][_elements];
|
||||
}
|
||||
|
||||
TPipelineFunction VertexLoader_TextCoord::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements) {
|
||||
TPipelineFunction VertexLoader_TextCoord::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements)
|
||||
{
|
||||
return tableReadTexCoord[_type][_format][_elements];
|
||||
}
|
||||
|
||||
TPipelineFunction VertexLoader_TextCoord::GetDummyFunction() {
|
||||
TPipelineFunction VertexLoader_TextCoord::GetDummyFunction()
|
||||
{
|
||||
return TexCoord_Read_Dummy;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ VertexManager::VertexManager()
|
|||
}
|
||||
|
||||
VertexManager::~VertexManager()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
void VertexManager::ResetBuffer()
|
||||
{
|
||||
|
@ -75,7 +76,8 @@ bool VertexManager::IsFlushed() const
|
|||
u32 VertexManager::GetRemainingIndices(int primitive)
|
||||
{
|
||||
|
||||
if(g_Config.backend_info.bSupportsPrimitiveRestart) {
|
||||
if(g_Config.backend_info.bSupportsPrimitiveRestart)
|
||||
{
|
||||
switch (primitive)
|
||||
{
|
||||
case GX_DRAW_QUADS:
|
||||
|
@ -98,7 +100,9 @@ u32 VertexManager::GetRemainingIndices(int primitive)
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (primitive)
|
||||
{
|
||||
case GX_DRAW_QUADS:
|
||||
|
@ -216,9 +220,11 @@ void VertexManager::Flush()
|
|||
PixelShaderManager::SetTexDims(i, tentry->nativeW, tentry->nativeH, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Error loading texture");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set global constants
|
||||
VertexShaderManager::SetConstants();
|
||||
|
|
|
@ -28,7 +28,8 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
|
|||
|
||||
uid->values[2] |= (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) << 31;
|
||||
u32 *pcurvalue = &uid->values[3];
|
||||
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) {
|
||||
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
|
||||
{
|
||||
TexMtxInfo tinfo = xfregs.texMtxInfo[i];
|
||||
if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP)
|
||||
tinfo.hex &= 0x7ff;
|
||||
|
@ -36,12 +37,14 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
|
|||
tinfo.projection = 0;
|
||||
|
||||
u32 val = ((tinfo.hex >> 1) & 0x1ffff);
|
||||
if (xfregs.dualTexTrans.enabled && tinfo.texgentype == XF_TEXGEN_REGULAR) {
|
||||
if (xfregs.dualTexTrans.enabled && tinfo.texgentype == XF_TEXGEN_REGULAR)
|
||||
{
|
||||
// rewrite normalization and post index
|
||||
val |= ((u32)xfregs.postMtxInfo[i].index << 17) | ((u32)xfregs.postMtxInfo[i].normalize << 23);
|
||||
}
|
||||
|
||||
switch (i & 3) {
|
||||
switch (i & 3)
|
||||
{
|
||||
case 0: pcurvalue[0] |= val; break;
|
||||
case 1: pcurvalue[0] |= val << 24; pcurvalue[1] = val >> 8; ++pcurvalue; break;
|
||||
case 2: pcurvalue[0] |= val << 16; pcurvalue[1] = val >> 16; ++pcurvalue; break;
|
||||
|
@ -60,12 +63,16 @@ void GetSafeVertexShaderId(VERTEXSHADERUIDSAFE *uid, u32 components)
|
|||
*ptr++ = xfregs.numChan.hex;
|
||||
*ptr++ = xfregs.dualTexTrans.hex;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
*ptr++ = xfregs.color[i].hex;
|
||||
*ptr++ = xfregs.alpha[i].hex;
|
||||
}
|
||||
|
||||
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
|
||||
for (unsigned int i = 0; i < 8; ++i) {
|
||||
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
{
|
||||
*ptr++ = xfregs.texMtxInfo[i].hex;
|
||||
*ptr++ = xfregs.postMtxInfo[i].hex;
|
||||
}
|
||||
|
@ -131,13 +138,18 @@ char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE ApiType)
|
|||
WRITE(p, " %s float4 colors_0 %s COLOR0;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":");
|
||||
WRITE(p, " %s float4 colors_1 %s COLOR1;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":");
|
||||
|
||||
if (xfregs.numTexGen.numTexGens < 7) {
|
||||
if (xfregs.numTexGen.numTexGens < 7)
|
||||
{
|
||||
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
|
||||
WRITE(p, " %s float3 tex%d %s TEXCOORD%d;\n", optCentroid, i, ApiType == API_OPENGL ? ";//" : ":", i);
|
||||
|
||||
WRITE(p, " %s float4 clipPos %s TEXCOORD%d;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens);
|
||||
|
||||
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
|
||||
WRITE(p, " %s float4 Normal %s TEXCOORD%d;\n", optCentroid, ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens + 1);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// clip position is in w of first 4 texcoords
|
||||
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
|
||||
{
|
||||
|
@ -212,7 +224,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
if (components & VB_HAS_COL1)
|
||||
WRITE(p, "ATTRIN float4 color1; // ATTR%d,\n", SHADER_COLOR1_ATTRIB);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
|
||||
if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
|
||||
WRITE(p, "ATTRIN float%d tex%d; // ATTR%d,\n", hastexmtx ? 3 : 2, i, SHADER_TEXTURE0_ATTRIB + i);
|
||||
|
@ -253,28 +266,36 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
// inputs
|
||||
if (components & VB_HAS_NRM0)
|
||||
WRITE(p, " float3 rawnorm0 : NORMAL0,\n");
|
||||
if (components & VB_HAS_NRM1) {
|
||||
if (components & VB_HAS_NRM1)
|
||||
{
|
||||
if (is_d3d)
|
||||
WRITE(p, " float3 rawnorm1 : NORMAL1,\n");
|
||||
else
|
||||
WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB);
|
||||
}
|
||||
if (components & VB_HAS_NRM2) {
|
||||
if (components & VB_HAS_NRM2)
|
||||
{
|
||||
if (is_d3d)
|
||||
WRITE(p, " float3 rawnorm2 : NORMAL2,\n");
|
||||
else
|
||||
WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB);
|
||||
}
|
||||
if (components & VB_HAS_COL0)
|
||||
{
|
||||
WRITE(p, " float4 color0 : COLOR0,\n");
|
||||
}
|
||||
if (components & VB_HAS_COL1)
|
||||
{
|
||||
WRITE(p, " float4 color1 : COLOR1,\n");
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
}
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i));
|
||||
if ((components & (VB_HAS_UV0<<i)) || hastexmtx)
|
||||
WRITE(p, " float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i);
|
||||
}
|
||||
if (components & VB_HAS_POSMTXIDX) {
|
||||
if (components & VB_HAS_POSMTXIDX)
|
||||
{
|
||||
if (is_d3d)
|
||||
WRITE(p, " float4 blend_indices : BLENDINDICES,\n");
|
||||
else
|
||||
|
@ -364,18 +385,22 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
|
||||
// transform texcoords
|
||||
WRITE(p, "float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n");
|
||||
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) {
|
||||
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
|
||||
{
|
||||
TexMtxInfo& texinfo = xfregs.texMtxInfo[i];
|
||||
|
||||
WRITE(p, "{\n");
|
||||
WRITE(p, "coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n");
|
||||
switch (texinfo.sourcerow) {
|
||||
|
||||
switch (texinfo.sourcerow)
|
||||
{
|
||||
case XF_SRCGEOM_INROW:
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "coord = rawpos;\n"); // pos.w is 1
|
||||
break;
|
||||
case XF_SRCNORMAL_INROW:
|
||||
if (components & VB_HAS_NRM0) {
|
||||
if (components & VB_HAS_NRM0)
|
||||
{
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "coord = float4(rawnorm0.xyz, 1.0f);\n");
|
||||
}
|
||||
|
@ -384,13 +409,15 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
_assert_( texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 || texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1 );
|
||||
break;
|
||||
case XF_SRCBINORMAL_T_INROW:
|
||||
if (components & VB_HAS_NRM1) {
|
||||
if (components & VB_HAS_NRM1)
|
||||
{
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "coord = float4(rawnorm1.xyz, 1.0f);\n");
|
||||
}
|
||||
break;
|
||||
case XF_SRCBINORMAL_B_INROW:
|
||||
if (components & VB_HAS_NRM2) {
|
||||
if (components & VB_HAS_NRM2)
|
||||
{
|
||||
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
|
||||
WRITE(p, "coord = float4(rawnorm2.xyz, 1.0f);\n");
|
||||
}
|
||||
|
@ -403,10 +430,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
}
|
||||
|
||||
// first transformation
|
||||
switch (texinfo.texgentype) {
|
||||
switch (texinfo.texgentype)
|
||||
{
|
||||
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
|
||||
|
||||
if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) {
|
||||
if (components & (VB_HAS_NRM1|VB_HAS_NRM2))
|
||||
{
|
||||
// transform the light dir into tangent space
|
||||
WRITE(p, "ldir = normalize(" I_LIGHTS"[5*%d + 3].xyz - pos.xyz);\n", texinfo.embosslightshift);
|
||||
WRITE(p, "o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift);
|
||||
|
@ -433,11 +462,11 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
WRITE(p, "int tmp = int(tex%d.z);\n", i);
|
||||
if (texinfo.projection == XF_TEXPROJ_STQ)
|
||||
WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), dot(coord, " I_TRANSFORMMATRICES"[tmp+2]));\n", i);
|
||||
else {
|
||||
else
|
||||
WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), 1);\n", i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (texinfo.projection == XF_TEXPROJ_STQ)
|
||||
WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]));\n", i, 3*i, 3*i+1, 3*i+2);
|
||||
else
|
||||
|
@ -446,7 +475,9 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
break;
|
||||
}
|
||||
|
||||
if (xfregs.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?
|
||||
// CHECKME: does this only work for regular tex gen types?
|
||||
if (xfregs.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR)
|
||||
{
|
||||
const PostMtxInfo& postInfo = xfregs.postMtxInfo[i];
|
||||
|
||||
int postidx = postInfo.index;
|
||||
|
@ -455,7 +486,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
"float4 P2 = " I_POSTTRANSFORMMATRICES"[%d];\n",
|
||||
postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f);
|
||||
|
||||
if (texGenSpecialCase) {
|
||||
if (texGenSpecialCase)
|
||||
{
|
||||
// no normalization
|
||||
// q of input is 1
|
||||
// q of output is unknown
|
||||
|
@ -477,9 +509,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
}
|
||||
|
||||
// clipPos/w needs to be done in pixel shader, not here
|
||||
if (xfregs.numTexGen.numTexGens < 7) {
|
||||
if (xfregs.numTexGen.numTexGens < 7)
|
||||
{
|
||||
WRITE(p, "o.clipPos = float4(pos.x,pos.y,o.pos.z,o.pos.w);\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "o.tex0.w = pos.x;\n");
|
||||
WRITE(p, "o.tex1.w = pos.y;\n");
|
||||
WRITE(p, "o.tex2.w = o.pos.z;\n");
|
||||
|
@ -488,9 +523,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
|
||||
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
|
||||
{
|
||||
if (xfregs.numTexGen.numTexGens < 7) {
|
||||
if (xfregs.numTexGen.numTexGens < 7)
|
||||
{
|
||||
WRITE(p, "o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "o.tex4.w = _norm0.x;\n");
|
||||
WRITE(p, "o.tex5.w = _norm0.y;\n");
|
||||
WRITE(p, "o.tex6.w = _norm0.z;\n");
|
||||
|
@ -499,6 +537,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
else
|
||||
WRITE(p, "o.tex7.w = pos.z;\n");
|
||||
}
|
||||
|
||||
if (components & VB_HAS_COL0)
|
||||
WRITE(p, "o.colors_0 = color0;\n");
|
||||
|
||||
|
@ -550,16 +589,23 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
// Will look better when we bind uniforms in GLSL 1.3
|
||||
// clipPos/w needs to be done in pixel shader, not here
|
||||
|
||||
if (xfregs.numTexGen.numTexGens < 7) {
|
||||
if (xfregs.numTexGen.numTexGens < 7)
|
||||
{
|
||||
for (unsigned int i = 0; i < 8; ++i)
|
||||
{
|
||||
if(i < xfregs.numTexGen.numTexGens)
|
||||
WRITE(p, " uv%d_2.xyz = o.tex%d;\n", i, i);
|
||||
else
|
||||
WRITE(p, " uv%d_2.xyz = float3(0.0f, 0.0f, 0.0f);\n", i);
|
||||
}
|
||||
|
||||
WRITE(p, " clipPos_2 = o.clipPos;\n");
|
||||
|
||||
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
|
||||
WRITE(p, " Normal_2 = o.Normal;\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// clip position is in w of first 4 texcoords
|
||||
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
|
||||
{
|
||||
|
@ -578,7 +624,9 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
|
|||
WRITE(p, "}\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE(p, "return o;\n}\n");
|
||||
}
|
||||
|
||||
if (text[sizeof(text) - 1] != 0x7C)
|
||||
PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
return true;
|
||||
else if (values[0] > _Right.values[0])
|
||||
return false;
|
||||
|
||||
int N = GetNumValues();
|
||||
for (int i = 1; i < N; ++i)
|
||||
{
|
||||
|
@ -96,6 +97,7 @@ public:
|
|||
else if (values[i] > _Right.values[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -103,12 +105,14 @@ public:
|
|||
{
|
||||
if (values[0] != _Right.values[0])
|
||||
return false;
|
||||
|
||||
int N = GetNumValues();
|
||||
for (int i = 1; i < N; ++i)
|
||||
{
|
||||
if (values[i] != _Right.values[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -86,15 +86,18 @@ float PHackValue(std::string sValue)
|
|||
c[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
c[i] = (cStr[i] == ',') ? '.' : *(cStr+i);
|
||||
if (c[i] == '.')
|
||||
fp = true;
|
||||
}
|
||||
|
||||
cStr = c;
|
||||
sTof.str(cStr);
|
||||
sTof >> f;
|
||||
|
||||
if (!fp) f /= 0xF4240;
|
||||
if (!fp)
|
||||
f /= 0xF4240;
|
||||
|
||||
delete [] c;
|
||||
return f;
|
||||
|
@ -183,6 +186,7 @@ void VertexShaderManager::SetConstants()
|
|||
{
|
||||
if (g_ActiveConfig.backend_info.APIType == API_OPENGL && !g_ActiveConfig.backend_info.bSupportsGLSLUBO)
|
||||
Dirty();
|
||||
|
||||
if (nTransformMatricesChanged[0] >= 0)
|
||||
{
|
||||
int startn = nTransformMatricesChanged[0] / 4;
|
||||
|
@ -191,6 +195,7 @@ void VertexShaderManager::SetConstants()
|
|||
SetMultiVSConstant4fv(C_TRANSFORMMATRICES + startn, endn - startn, pstart);
|
||||
nTransformMatricesChanged[0] = nTransformMatricesChanged[1] = -1;
|
||||
}
|
||||
|
||||
if (nNormalMatricesChanged[0] >= 0)
|
||||
{
|
||||
int startn = nNormalMatricesChanged[0] / 3;
|
||||
|
@ -238,9 +243,11 @@ void VertexShaderManager::SetConstants()
|
|||
SetVSConstant4f(C_LIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVSConstant4fv(C_LIGHTS+5*i+j+1, xfmemptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nLightsChanged[0] = nLightsChanged[1] = -1;
|
||||
}
|
||||
|
@ -479,21 +486,24 @@ void VertexShaderManager::InvalidateXFRange(int start, int end)
|
|||
if (((u32)start >= (u32)MatrixIndexA.PosNormalMtxIdx * 4 &&
|
||||
(u32)start < (u32)MatrixIndexA.PosNormalMtxIdx * 4 + 12) ||
|
||||
((u32)start >= XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 &&
|
||||
(u32)start < XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 + 9)) {
|
||||
(u32)start < XFMEM_NORMALMATRICES + ((u32)MatrixIndexA.PosNormalMtxIdx & 31) * 3 + 9))
|
||||
{
|
||||
bPosNormalMatrixChanged = true;
|
||||
}
|
||||
|
||||
if (((u32)start >= (u32)MatrixIndexA.Tex0MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex0MtxIdx*4+12) ||
|
||||
((u32)start >= (u32)MatrixIndexA.Tex1MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex1MtxIdx*4+12) ||
|
||||
((u32)start >= (u32)MatrixIndexA.Tex2MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex2MtxIdx*4+12) ||
|
||||
((u32)start >= (u32)MatrixIndexA.Tex3MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex3MtxIdx*4+12)) {
|
||||
((u32)start >= (u32)MatrixIndexA.Tex3MtxIdx*4 && (u32)start < (u32)MatrixIndexA.Tex3MtxIdx*4+12))
|
||||
{
|
||||
bTexMatricesChanged[0] = true;
|
||||
}
|
||||
|
||||
if (((u32)start >= (u32)MatrixIndexB.Tex4MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex4MtxIdx*4+12) ||
|
||||
((u32)start >= (u32)MatrixIndexB.Tex5MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex5MtxIdx*4+12) ||
|
||||
((u32)start >= (u32)MatrixIndexB.Tex6MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex6MtxIdx*4+12) ||
|
||||
((u32)start >= (u32)MatrixIndexB.Tex7MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex7MtxIdx*4+12)) {
|
||||
((u32)start >= (u32)MatrixIndexB.Tex7MtxIdx*4 && (u32)start < (u32)MatrixIndexB.Tex7MtxIdx*4+12))
|
||||
{
|
||||
bTexMatricesChanged[1] = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,9 +129,10 @@ void VideoConfig::GameIniLoad(const char *ini_file)
|
|||
if (tmp != -9000)
|
||||
{
|
||||
if (tmp != SCALE_FORCE_INTEGRAL)
|
||||
{
|
||||
iEFBScale = tmp;
|
||||
// Round down to multiple of native IR
|
||||
else
|
||||
}
|
||||
else // Round down to multiple of native IR
|
||||
{
|
||||
switch (iEFBScale)
|
||||
{
|
||||
|
|
|
@ -202,13 +202,17 @@ struct Light
|
|||
float k0; // k stuff
|
||||
float k1;
|
||||
float k2;
|
||||
|
||||
union
|
||||
{
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
float dpos[3];
|
||||
float ddir[3]; // specular lights only
|
||||
};
|
||||
struct {
|
||||
|
||||
struct
|
||||
{
|
||||
float sdir[3];
|
||||
float shalfangle[3]; // specular lights only
|
||||
};
|
||||
|
|
|
@ -598,14 +598,17 @@ void Shutdown()
|
|||
void Clear()
|
||||
{
|
||||
VDLMap::iterator iter = dl_map.begin();
|
||||
while (iter != dl_map.end()) {
|
||||
while (iter != dl_map.end())
|
||||
{
|
||||
VDlist &ParentEntry = iter->second;
|
||||
DLMap::iterator childiter = ParentEntry.dl_map.begin();
|
||||
while (childiter != ParentEntry.dl_map.end()) {
|
||||
while (childiter != ParentEntry.dl_map.end())
|
||||
{
|
||||
CachedDisplayList &entry = childiter->second;
|
||||
entry.ClearRegions();
|
||||
childiter++;
|
||||
}
|
||||
|
||||
ParentEntry.dl_map.clear();
|
||||
iter++;
|
||||
}
|
||||
|
@ -617,28 +620,35 @@ void Clear()
|
|||
void ProgressiveCleanup()
|
||||
{
|
||||
VDLMap::iterator iter = dl_map.begin();
|
||||
while (iter != dl_map.end()) {
|
||||
while (iter != dl_map.end())
|
||||
{
|
||||
VDlist &ParentEntry = iter->second;
|
||||
DLMap::iterator childiter = ParentEntry.dl_map.begin();
|
||||
while (childiter != ParentEntry.dl_map.end())
|
||||
{
|
||||
CachedDisplayList &entry = childiter->second;
|
||||
int limit = 3600;
|
||||
if (entry.frame_count < frameCount - limit) {
|
||||
if (entry.frame_count < frameCount - limit)
|
||||
{
|
||||
entry.ClearRegions();
|
||||
ParentEntry.dl_map.erase(childiter++); // (this is gcc standard!)
|
||||
}
|
||||
else
|
||||
{
|
||||
++childiter;
|
||||
}
|
||||
}
|
||||
|
||||
if(ParentEntry.dl_map.empty())
|
||||
{
|
||||
dl_map.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t GetSpaceLeft()
|
||||
{
|
||||
|
@ -653,10 +663,12 @@ bool HandleDisplayList(u32 address, u32 size)
|
|||
//Fixed DlistCaching now is fully functional still some things to workout
|
||||
if(!g_ActiveConfig.bDlistCachingEnable)
|
||||
return false;
|
||||
if(size == 0) return false;
|
||||
if(size == 0)
|
||||
return false;
|
||||
|
||||
// Is this thread safe?
|
||||
if (DLCache::GetSpaceLeft() < DL_CODE_CLEAR_THRESHOLD) {
|
||||
// TODO: Is this thread safe?
|
||||
if (DLCache::GetSpaceLeft() < DL_CODE_CLEAR_THRESHOLD)
|
||||
{
|
||||
DLCache::Clear();
|
||||
}
|
||||
|
||||
|
@ -665,12 +677,14 @@ bool HandleDisplayList(u32 address, u32 size)
|
|||
DLCache::VDLMap::iterator Parentiter = DLCache::dl_map.find(dl_id);
|
||||
DLCache::DLMap::iterator iter;
|
||||
bool childexist = false;
|
||||
|
||||
if (Parentiter != DLCache::dl_map.end())
|
||||
{
|
||||
vhash = DLCache::CreateVMapId(Parentiter->second.VATUsed);
|
||||
iter = Parentiter->second.dl_map.find(vhash);
|
||||
childexist = iter != Parentiter->second.dl_map.end();
|
||||
}
|
||||
|
||||
if (Parentiter != DLCache::dl_map.end() && childexist)
|
||||
{
|
||||
DLCache::CachedDisplayList &dl = iter->second;
|
||||
|
|
Loading…
Reference in New Issue