Another bug fix.

With the old code, it was possible that we skipped a compression with unlucky
preemption of our threads. I'm not exactly sure why, but that caused deadlock
(livelock?) in some very unfortunate circumstances. This new algorithm should
work regardless of how many threads execute at once and should also prevent
textures in the compression job list from being skipped. This algorithm seems
to be an improvement on low-core count machines (around 4 cores), but it is
slower on high-core count machines (40 cores or more)...
This commit is contained in:
Pavel Krajcevski 2013-03-11 16:20:52 -04:00
parent 9c48aaa7f2
commit 6f6ca2d867

View File

@ -1555,7 +1555,7 @@ namespace BC7C
// Help finish whatever texture we're compressing before we start again on my work... // Help finish whatever texture we're compressing before we start again on my work...
uint32 blockIdx; uint32 blockIdx;
while((blockIdx = FetchAndAdd(&(cjl.m_CurrentBlockIndex))) < nBlocks && jobIdx == cjl.m_CurrentJobIndex) { while((blockIdx = FetchAndAdd(&(cjl.m_CurrentBlockIndex))) < nBlocks && *(cjl.GetFinishedFlag(jobIdx)) == 0) {
unsigned char *out = cj->outBuf + (16 * blockIdx); unsigned char *out = cj->outBuf + (16 * blockIdx);
const unsigned char *in = cj->inBuf + (64 * blockIdx); const unsigned char *in = cj->inBuf + (64 * blockIdx);
@ -1563,8 +1563,8 @@ namespace BC7C
} }
if(TestAndSet(cjl.GetFinishedFlag(jobIdx)) == 0) { if(TestAndSet(cjl.GetFinishedFlag(jobIdx)) == 0) {
cjl.m_CurrentJobIndex++;
cjl.m_CurrentBlockIndex = 0; cjl.m_CurrentBlockIndex = 0;
cjl.m_CurrentJobIndex++;
} }
// Wait until this texture finishes. // Wait until this texture finishes.