fixed delayed shader loads leading to incorrect rendering and crashes (dynamic lights)

This commit is contained in:
myT 2022-04-10 22:14:19 +02:00
parent 981f059b7b
commit dbfb3c5028
4 changed files with 33 additions and 0 deletions

View file

@ -25,6 +25,8 @@ chg: with r_backend GL3, depth fade with MSAA now requires GLSL 4.00 at a minimu
chg: with r_backend GL3, alpha to coverage now requires GLSL 4.00 at a minimum
fix: delayed shader loads could lead to incorrect rendering and crashes (mostly with dynamic lights)
fix: the nextdemo variable wasn't used to start the playback of a new demo when:
- a drop error happened during demo playback
- the engine failed to open the current demo file

View file

@ -508,6 +508,7 @@ struct drawSurf_t {
qhandle_t model; // MD3 model handle
int index; // transparent surface's registration order
float shaderSort; // transparent surface's shader sort
int shaderNum; // unsorted shader index, for when we need to do fix-ups
};
extern void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( const void* );
@ -515,6 +516,7 @@ extern void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( const void* );
struct litSurf_t {
unsigned sort; // bit combination for fast compares
int shaderNum; // unsorted shader index, for when we need to do fix-ups
const surfaceType_t* surface; // any of surface*_t
litSurf_t* next;
};

View file

@ -1074,6 +1074,7 @@ void R_AddDrawSurf( const surfaceType_t* surface, const shader_t* shader, int fo
drawSurf->sort = R_ComposeSort( tr.currentEntityNum, shader, fogIndex );
drawSurf->surface = surface;
drawSurf->model = tr.currentModel != NULL ? tr.currentModel->index : 0;
drawSurf->shaderNum = shader->index;
}
@ -1087,6 +1088,7 @@ void R_AddLitSurf( const surfaceType_t* surface, const shader_t* shader, int fog
litSurf_t* const litSurf = &tr.refdef.litSurfs[tr.refdef.numLitSurfs++];
litSurf->sort = R_ComposeSort( tr.currentEntityNum, shader, fogIndex );
litSurf->surface = surface;
litSurf->shaderNum = shader->index;
if (!tr.light->head)
tr.light->head = litSurf;

View file

@ -1552,6 +1552,33 @@ static void SortNewShader()
for ( i = 0; i < tr.numShaders; ++i ) {
tr.sortedShaders[i]->sortedIndex = i;
}
//
// If we register a new shader when surfaces are already added,
// the decoded sorted shader index for the added surfaces will not always be correct anymore.
// This can lead to incorrect rendering (wrong shader used)
// and potentially crashes too (lit surfaces referencing shaders with no diffuse stage).
// We'll therefore update all surfaces that have already been added for this entire frame,
// not just the last view. Hence why we don't use firstDrawSurf / firstLitSurf.
// The extra CPU cost for the fix-up is nothing compared to loading new textures mid-frame.
//
int entityNum, fogNum;
const shader_t* wrongShader;
const int numDrawSurfs = tr.refdef.numDrawSurfs;
drawSurf_t* drawSurfs = tr.refdef.drawSurfs;
for( int i = 0; i < numDrawSurfs; ++i, ++drawSurfs ) {
R_DecomposeSort( drawSurfs->sort, &entityNum, &wrongShader, &fogNum );
drawSurfs->sort = R_ComposeSort( entityNum, tr.shaders[drawSurfs->shaderNum], fogNum );
}
const int numLitSurfs = tr.refdef.numLitSurfs;
litSurf_t* litSurfs = tr.refdef.litSurfs;
for ( int i = 0; i < numLitSurfs; ++i, ++litSurfs ) {
R_DecomposeSort( litSurfs->sort, &entityNum, &wrongShader, &fogNum );
litSurfs->sort = R_ComposeSort( entityNum, tr.shaders[litSurfs->shaderNum], fogNum );
}
}