nv2a: Implement texture LOD bias

This commit is contained in:
Erik Abair
2025-09-23 12:56:08 -07:00
committed by GitHub
parent ff1617d664
commit 2d26f185a0
4 changed files with 27 additions and 1 deletions
+1
View File
@@ -73,6 +73,7 @@ typedef struct TextureBinding {
unsigned int scale;
unsigned int min_filter;
unsigned int mag_filter;
uint32_t lod_bias;
unsigned int addru;
unsigned int addrv;
unsigned int addrp;
+8
View File
@@ -117,6 +117,8 @@ static void apply_texture_parameters(TextureBinding *binding,
{
unsigned int min_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIN);
unsigned int mag_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MAG);
unsigned int lod_bias =
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS);
unsigned int addru = GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRU);
unsigned int addrv = GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRV);
unsigned int addrp = GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRP);
@@ -146,6 +148,11 @@ static void apply_texture_parameters(TextureBinding *binding,
pgraph_texture_mag_filter_gl_map[mag_filter]);
binding->mag_filter = mag_filter;
}
if (lod_bias != binding->lod_bias) {
binding->lod_bias = lod_bias;
glTexParameterf(binding->gl_target, GL_TEXTURE_LOD_BIAS,
pgraph_convert_lod_bias_to_float(lod_bias));
}
/* Texture wrapping */
assert(addru < ARRAY_SIZE(pgraph_texture_addr_gl_map));
@@ -727,6 +734,7 @@ static TextureBinding* generate_texture(const TextureShape s,
ret->data_hash = 0;
ret->min_filter = 0xFFFFFFFF;
ret->mag_filter = 0xFFFFFFFF;
ret->lod_bias = 0xFFFFFFFF;
ret->addru = 0xFFFFFFFF;
ret->addrv = 0xFFFFFFFF;
ret->addrp = 0xFFFFFFFF;
+9
View File
@@ -64,4 +64,13 @@ hwaddr pgraph_get_texture_palette_phys_addr_length(PGRAPHState *pg, int texture_
TextureShape pgraph_get_texture_shape(PGRAPHState *pg, int texture_idx);
size_t pgraph_get_texture_length(PGRAPHState *pg, TextureShape *shape);
static inline float pgraph_convert_lod_bias_to_float(uint32_t lod_bias)
{
int sign_extended_bias = lod_bias;
if (lod_bias & (1 << 12)) {
sign_extended_bias |= ~NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS;
}
return (float)sign_extended_bias / 256.f;
}
#endif
+9 -1
View File
@@ -1336,6 +1336,14 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
min_filter == NV_PGRAPH_TEXFILTER0_MIN_BOX_NEARESTLOD ||
min_filter == NV_PGRAPH_TEXFILTER0_MIN_TENT_NEARESTLOD;
float lod_bias = pgraph_convert_lod_bias_to_float(
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS));
if (lod_bias > r->device_props.limits.maxSamplerLodBias) {
lod_bias = r->device_props.limits.maxSamplerLodBias;
} else if (lod_bias < -r->device_props.limits.maxSamplerLodBias) {
lod_bias = -r->device_props.limits.maxSamplerLodBias;
}
VkSamplerCreateInfo sampler_create_info = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.magFilter = vk_mag_filter,
@@ -1356,7 +1364,7 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
VK_SAMPLER_MIPMAP_MODE_LINEAR,
.minLod = mipmap_en ? MIN(state.min_mipmap_level, state.levels - 1) : 0.0,
.maxLod = mipmap_en ? MIN(state.max_mipmap_level, state.levels - 1) : 0.0,
.mipLodBias = 0.0,
.mipLodBias = lod_bias,
.pNext = sampler_next_struct,
};