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.
We don't want this homepath thing (yes it should be deleted from the other one too)
There was a problem hiding this comment.
@VReaperV Is it used to load cached reflection cubemaps?
There was a problem hiding this comment.
The one in R_FindImageLoader() is.
There was a problem hiding this comment.
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.
🔹️ 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_FindImageLoaderrequires to read home path
🔹️ xreaperx: Well yeah otherwise it doesn't find the files
🔹️ illwieckz: but this is a cubemap
🔹️ illwieckz:R_FindImageLoaderis for non-cubemap files
🔹️ xreaperx: Yeah there's some weirdness with that
There was a problem hiding this comment.
🔹️ 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.
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.
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.
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.
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.
Could use at least a TODO comment about respecting explicit extensions.
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
| const imageExtLoader_t* loader = R_FindImageLoader( filename, &prefix ); | ||
|
|
||
| if ( *ext && bestLoader == -1 ) | ||
| if ( *ext && 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.
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.
The reflection cubemaps aren't "skyboxes"
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.
This could use a comment (or function name change) indicating it is only used for single-file variants
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.
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.
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.
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.
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.
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.
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.
The token temporary pointer shouldn't be used after calling a bunch of other functions.
There was a problem hiding this comment.
Removed. In fact the whole token wording was a because of this code parsing the .shader file, which was wrong.
c40fc19 to
58c3631
Compare
illwieckz
left a comment
There was a problem hiding this comment.
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.
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 ) |
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. |
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.
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.
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.
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: