-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tr_image: do not use R_FindImageLoader with cube maps, test multifile cubemaps first (or preview may be loaded as cubemap instead) #1394
Conversation
- do not walk .shader files in tr_image.cpp - do not use R_FindImageLoader with cube maps - only use home read for KTX with IF_HOMEPATH - load home KTX with IF_HOMEPATH before doing any lookup - do not do any other home loading - test multifile cubemaps before singlefile ones (or preview may be loaded as cubemap instead) - fix a crash when singlefile cubemap is freed because it was loaded but not created - look for cubemap file with explicit extension - add many debug logs and factorize them
src/engine/renderer/tr_image.cpp
Outdated
foundLoader = true; | ||
} | ||
|
||
if ( pak == nullptr ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want this homepath thing (yes it should be deleted from the other one too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@VReaperV Is it used to load cached reflection cubemaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one in R_FindImageLoader()
is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, something is wrong, R_FindImageLoader()
is not expected to be used to load a cached cubemap.
For now I'll keep the home loader in both, then later we can decide what is to be kept when things are not weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔹️ xreaperx: Well, I thought you were asking about the homepath usage in the loader?
🔹️ xreaperx: I added it so it would look for .ktx under homepath
🔹️ illwieckz: yes
🔹️ illwieckz: but you said onlyR_FindImageLoader
requires to read home path
🔹️ xreaperx: Well yeah otherwise it doesn't find the files
🔹️ illwieckz: but this is a cubemap
🔹️ illwieckz:R_FindImageLoader
is for non-cubemap files
🔹️ xreaperx: Yeah there's some weirdness with that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔹️ xreaperx: @illwieckz
R_FindCubeImage()
useR_FindImageLoader()
, notR_FindCubeImageLoader()
🔹️ xreaperx: So if that's not what it should do, then the error is in that
I say: we merge this that fixes the skybox, then later we fix the reflection cubemap code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable to me. I don't know if there's supposed to be some other way to load images from homepath, but other functionality that I looked at (log, glsl cache) used FS::HomePath
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the code that's used for reflection maps. The reflection map search sets an IF_HOMEPATH
flag instructing to search the homepath instead of the VFS. It's bad to search the homepath for every random image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and no. loader.ImageLoader()
is the only call that uses IF_HOMEPATH
, but R_FindImageLoader()
, which preceeds it, doesn't use that, and is used to know if the file exists in the first place. I suppose a proper solution might be to pass imageParams.bits
to it and then use IF_HOMEPATH
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of this PR is to fix skybox loading, other things like “attempting to remove some code and see if that breaks reflections“ later.
src/engine/renderer/tr_image.cpp
Outdated
char baseName[ MAX_QPATH ]; | ||
COM_StripExtension3( buffer, baseName, sizeof( baseName ) ); | ||
|
||
const FS::PakInfo* bestPak = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use at least a TODO comment about respecting explicit extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
85febb1
to
b1819eb
Compare
I finally reworded the thing in a better way, including the non-cubemap code. |
b1819eb
to
4a9b464
Compare
4a9b464
to
3cc6ef4
Compare
I added some |
src/engine/renderer/tr_image.cpp
Outdated
|
||
if ( *ext && bestLoader == -1 ) | ||
if ( *ext && loader ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be !loader
.
13cb6ae
to
e958009
Compare
So I did a deeper rewrite. First, I refactored much code and added more logs. It makes me able to check how and if the cached KTX loading worked. So I dropped every home loading but cached KTX: now only the cached KTX is loaded from home, nothing else is loaded from home. It even doesn't iterate loaders for them: it does a KTX home dir straight and return. I actually found a crash that happens when loading a singlefile cubmemap succeeds but image creation fails (I had to simulate this case to verify it would crash). I also implemented the look-up of singlefile cubemap with explicit extension. The first post was updated accordingly. |
7ef328f
to
eab6a6a
Compare
I noticed some functions were copying with |
eab6a6a
to
fe3df0b
Compare
src/engine/renderer/tr_image.cpp
Outdated
// We found a file and its pak is better than the best pak we have | ||
// this relies on how the filesystem works internally and should be moved | ||
// to a more explicit interface once there is one. (FIXME) | ||
// FIXME: Move to a more explicit interface once there is one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The preceding sentence is important context for this comment. Without it written together, it would be difficult to guess what it's talking about.
src/engine/renderer/tr_image.cpp
Outdated
COM_StripExtension3( buffer, cubeMapBaseName, sizeof( cubeMapBaseName ) ); | ||
|
||
for ( const cubeMapLoader_t &loader : cubeMapLoaders ) | ||
// Look for cached 6-face skybox file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reflection cubemaps aren't "skyboxes"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewritten.
src/engine/renderer/tr_image.cpp
Outdated
return bestLoader; | ||
} | ||
|
||
static image_t *R_LoadAndCreateCubeImage( const char *imageName, const char* altName, const imageExtLoader_t *loader, imageParams_t& imageParams ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could use a comment (or function name change) indicating it is only used for single-file variants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/engine/renderer/tr_image.cpp
Outdated
Q_strncpyz( buffer, imageName, sizeof( buffer ) ); | ||
unsigned hash = GenerateImageHashValue( buffer ); | ||
char imageName[ 1024 ]; | ||
Q_strncpyz( imageName, untrustedName, sizeof( imageName ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to make a copy of the function argument. The one concern like that which should be taken care of is that when you use COM_Parse*
it returns a pointer to a temporary buffer, which you need to either copy, or finish using immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact all the multiple copies (the thing I first thought it was a security check) and this one ware a VERY UGLY workaround for a bug where the .shader
file was iterating the multiple images of lines like AnimMap 1.5 models/weapons/lgun/display1 models/weapons/lgun/display2 models/weapons/lgun/display3 models/weapons/lgun/display4
twice: once in tr_shader.cpp
, once in tr_image.cpp
… So ParseStage
from tr_shader.cpp
was reading next token, passed it to R_FindImageFile
, then R_FindImageFile
backuped the token position, passed the token to R_LoadImage that was moving to the next token in the back or
ParseStage, etc. And with multi-file cubemaps it meant the image code was iterating next
.shader` file token 6 time, requiring to reset the state 6 times… This was all crazy.
src/engine/renderer/tr_image.cpp
Outdated
if ( IsImageCompressed( imageParams.bits ) ) | ||
{ | ||
Log::Warn("Cube map face '%s' has DXTn compression, cube map unusable", fileName ); | ||
R_FreeCubePics( pic, i ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be i + 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, also done in next free.
src/engine/renderer/tr_image.cpp
Outdated
Log::Warn("cubemap face '%s' is a multilayer image with %d layer(s), cube map unusable", filename, numLayers); | ||
break; | ||
} | ||
R_LoadImage( &fileName[ 0 ], &pic[ i ], &width, &height, &numLayers, &numMips, &imageParams.bits ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just fileName
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. The various &name[0]
were in fact a workaround for the many type discrepancies of the various string copies to workaround the double shader keyword iteration… What a mess!
src/engine/renderer/tr_image.cpp
Outdated
} | ||
} | ||
|
||
/* If the image path is “some.thing” for a file named “some.thing.crn”, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments are written in a confusing way. You could say If we are give the name "some.thing", first we look for some.thing.webp, some.thing.tga etc... Then, some.webp, some.tga, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/engine/renderer/tr_image.cpp
Outdated
try loading with “something” as a basename. */ | ||
if ( *ext && !loader ) | ||
{ | ||
COM_StripExtension3( token, fileName, sizeof(fileName) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The token
temporary pointer shouldn't be used after calling a bunch of other functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed. In fact the whole token
wording was a because of this code parsing the .shader
file, which was wrong.
c40fc19
to
58c3631
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so, lot of that madness code with many copies and pointers were very convoluted workarounds to the fact the image code was walking the .shader
file while the shader code did the same and then there was some crazy code done to make this wrongness work.
src/engine/renderer/tr_image.cpp
Outdated
Q_strncpyz( buffer, imageName, sizeof( buffer ) ); | ||
unsigned hash = GenerateImageHashValue( buffer ); | ||
char imageName[ 1024 ]; | ||
Q_strncpyz( imageName, untrustedName, sizeof( imageName ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact all the multiple copies (the thing I first thought it was a security check) and this one ware a VERY UGLY workaround for a bug where the .shader
file was iterating the multiple images of lines like AnimMap 1.5 models/weapons/lgun/display1 models/weapons/lgun/display2 models/weapons/lgun/display3 models/weapons/lgun/display4
twice: once in tr_shader.cpp
, once in tr_image.cpp
… So ParseStage
from tr_shader.cpp
was reading next token, passed it to R_FindImageFile
, then R_FindImageFile
backuped the token position, passed the token to R_LoadImage that was moving to the next token in the back or
ParseStage, etc. And with multi-file cubemaps it meant the image code was iterating next
.shader` file token 6 time, requiring to reset the state 6 times… This was all crazy.
src/engine/renderer/tr_image.cpp
Outdated
return bestLoader; | ||
} | ||
|
||
static image_t *R_LoadAndCreateCubeImage( const char *imageName, const char* altName, const imageExtLoader_t *loader, imageParams_t& imageParams ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/engine/renderer/tr_image.cpp
Outdated
COM_StripExtension3( buffer, cubeMapBaseName, sizeof( cubeMapBaseName ) ); | ||
|
||
for ( const cubeMapLoader_t &loader : cubeMapLoaders ) | ||
// Look for cached 6-face skybox file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewritten.
src/engine/renderer/tr_image.cpp
Outdated
Log::Warn("cubemap face '%s' is a multilayer image with %d layer(s), cube map unusable", filename, numLayers); | ||
break; | ||
} | ||
R_LoadImage( &fileName[ 0 ], &pic[ i ], &width, &height, &numLayers, &numMips, &imageParams.bits ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. The various &name[0]
were in fact a workaround for the many type discrepancies of the various string copies to workaround the double shader keyword iteration… What a mess!
src/engine/renderer/tr_image.cpp
Outdated
if ( IsImageCompressed( imageParams.bits ) ) | ||
{ | ||
Log::Warn("Cube map face '%s' has DXTn compression, cube map unusable", fileName ); | ||
R_FreeCubePics( pic, i ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, also done in next free.
src/engine/renderer/tr_image.cpp
Outdated
try loading with “something” as a basename. */ | ||
if ( *ext && !loader ) | ||
{ | ||
COM_StripExtension3( token, fileName, sizeof(fileName) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed. In fact the whole token
wording was a because of this code parsing the .shader
file, which was wrong.
LGTM |
Deep rewrite of image loading code.
Fixes #1393: