gl3: skip streamed-texture mip tail on Switch (nouveau per-call cost)

This commit is contained in:
Dima353
2026-07-21 01:40:00 +03:00
parent 5501c4fdc7
commit 64e805c718
+31
View File
@@ -319,9 +319,15 @@ allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha)
glGenTextures(1, &natras->texid);
uint32 prev = bindTexture(natras->texid);
#ifndef __SWITCH__
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
raster->width, raster->height,
0, natras->format, natras->type, nil);
#else
// __SWITCH__: skip this level-0 allocation. rasterUnlock's
// glCompressedTexImage2D allocates+uploads level 0 anyway, so pre-allocating
// here just wastes a driver call per texture (~0.5ms each on nouveau).
#endif
// TODO: allocate other levels...probably
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, natras->numLevels-1);
natras->filterMode = 0;
@@ -946,14 +952,39 @@ readNativeTexture(Stream *stream)
natras = GETGL3RASTEREXT(raster);
tex->raster = raster;
int32 uploadLevels = numLevels;
#ifdef __SWITCH__
// switch-mesa/nouveau charges a fixed ~0.7ms per texture-upload driver call
// regardless of data size. A txd's long tail of tiny mip levels (each an
// 8-16 byte block) then dominates load time and causes streaming hitches.
// Upload only the largest RW_SWITCH_TEX_MAXLEVELS level(s); bump this if
// distant-texture aliasing becomes noticeable.
#ifndef RW_SWITCH_TEX_MAXLEVELS
#define RW_SWITCH_TEX_MAXLEVELS 1
#endif
if(uploadLevels > RW_SWITCH_TEX_MAXLEVELS)
uploadLevels = RW_SWITCH_TEX_MAXLEVELS;
#endif
uint32 size;
uint8 *data;
for(int32 i = 0; i < numLevels; i++){
size = stream->readU32();
if(i >= uploadLevels){
// skipped level: consume its bytes, don't upload
stream->seek(size);
continue;
}
data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
stream->read8(data, size);
raster->unlock(i);
}
if(uploadLevels < numLevels){
// cap the sampled mip level so undefined higher levels aren't read
uint32 prev = bindTexture(natras->texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, uploadLevels-1);
bindTexture(prev);
}
return tex;
}