Merge pull request #1390 from vlj/rsx

rsx/common: Fix program state cache Shader program comparaison.
This commit is contained in:
Ivan 2016-01-03 18:19:37 +03:00
commit 2bccf3f2af

View file

@ -73,26 +73,6 @@ namespace ProgramHashUtil
return ((sourceOperand >> 8) & 0x3) == 2; return ((sourceOperand >> 8) & 0x3) == 2;
} }
/**
* RSX fragment program constants are inlined inside shader code.
* This function takes an instruction from a fragment program and
* returns an equivalent instruction where inlined constants
* are masked.
* This allows to hash/compare fragment programs even if their
* inlined constants are modified inbetween
*/
static qword fragmentMaskConstant(const qword &initialQword)
{
qword result = initialQword;
if (isConstant(initialQword.word[1]))
result.word[1] = 0;
if (isConstant(initialQword.word[2]))
result.word[2] = 0;
if (isConstant(initialQword.word[3]))
result.word[3] = 0;
return result;
}
static static
size_t getFPBinarySize(void *ptr) size_t getFPBinarySize(void *ptr)
{ {
@ -131,13 +111,9 @@ namespace ProgramHashUtil
while (true) while (true)
{ {
const qword& inst = instbuffer[instIndex]; const qword& inst = instbuffer[instIndex];
bool end = (inst.word[0] >> 8) & 0x1; hash ^= inst.dword[0];
if (end)
return hash;
const qword& maskedInst = FragmentProgramUtil::fragmentMaskConstant(inst);
hash ^= maskedInst.dword[0];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40); hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
hash ^= maskedInst.dword[1]; hash ^= inst.dword[1];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40); hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
instIndex++; instIndex++;
// Skip constants // Skip constants
@ -145,6 +121,10 @@ namespace ProgramHashUtil
FragmentProgramUtil::isConstant(inst.word[2]) || FragmentProgramUtil::isConstant(inst.word[2]) ||
FragmentProgramUtil::isConstant(inst.word[3])) FragmentProgramUtil::isConstant(inst.word[3]))
instIndex++; instIndex++;
bool end = (inst.word[0] >> 8) & 0x1;
if (end)
return hash;
} }
return 0; return 0;
} }
@ -161,14 +141,8 @@ namespace ProgramHashUtil
{ {
const qword& inst1 = instBuffer1[instIndex]; const qword& inst1 = instBuffer1[instIndex];
const qword& inst2 = instBuffer2[instIndex]; const qword& inst2 = instBuffer2[instIndex];
bool end = ((inst1.word[0] >> 8) & 0x1) && ((inst2.word[0] >> 8) & 0x1);
if (end)
return true;
const qword& maskedInst1 = FragmentProgramUtil::fragmentMaskConstant(inst1); if (inst1.dword[0] != inst2.dword[0] || inst1.dword[1] != inst2.dword[1])
const qword& maskedInst2 = FragmentProgramUtil::fragmentMaskConstant(inst2);
if (maskedInst1.dword[0] != maskedInst2.dword[0] || maskedInst1.dword[1] != maskedInst2.dword[1])
return false; return false;
instIndex++; instIndex++;
// Skip constants // Skip constants
@ -176,6 +150,10 @@ namespace ProgramHashUtil
FragmentProgramUtil::isConstant(inst1.word[2]) || FragmentProgramUtil::isConstant(inst1.word[2]) ||
FragmentProgramUtil::isConstant(inst1.word[3])) FragmentProgramUtil::isConstant(inst1.word[3]))
instIndex++; instIndex++;
bool end = ((inst1.word[0] >> 8) & 0x1) && ((inst2.word[0] >> 8) & 0x1);
if (end)
return true;
} }
} }
}; };