Skip to content

Commit 2d26f18

Browse files
authored
nv2a: Implement texture LOD bias
1 parent ff1617d commit 2d26f18

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

hw/xbox/nv2a/pgraph/gl/renderer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ typedef struct TextureBinding {
7373
unsigned int scale;
7474
unsigned int min_filter;
7575
unsigned int mag_filter;
76+
uint32_t lod_bias;
7677
unsigned int addru;
7778
unsigned int addrv;
7879
unsigned int addrp;

hw/xbox/nv2a/pgraph/gl/texture.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ static void apply_texture_parameters(TextureBinding *binding,
117117
{
118118
unsigned int min_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIN);
119119
unsigned int mag_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MAG);
120+
unsigned int lod_bias =
121+
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS);
120122
unsigned int addru = GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRU);
121123
unsigned int addrv = GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRV);
122124
unsigned int addrp = GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRP);
@@ -146,6 +148,11 @@ static void apply_texture_parameters(TextureBinding *binding,
146148
pgraph_texture_mag_filter_gl_map[mag_filter]);
147149
binding->mag_filter = mag_filter;
148150
}
151+
if (lod_bias != binding->lod_bias) {
152+
binding->lod_bias = lod_bias;
153+
glTexParameterf(binding->gl_target, GL_TEXTURE_LOD_BIAS,
154+
pgraph_convert_lod_bias_to_float(lod_bias));
155+
}
149156

150157
/* Texture wrapping */
151158
assert(addru < ARRAY_SIZE(pgraph_texture_addr_gl_map));
@@ -727,6 +734,7 @@ static TextureBinding* generate_texture(const TextureShape s,
727734
ret->data_hash = 0;
728735
ret->min_filter = 0xFFFFFFFF;
729736
ret->mag_filter = 0xFFFFFFFF;
737+
ret->lod_bias = 0xFFFFFFFF;
730738
ret->addru = 0xFFFFFFFF;
731739
ret->addrv = 0xFFFFFFFF;
732740
ret->addrp = 0xFFFFFFFF;

hw/xbox/nv2a/pgraph/texture.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,13 @@ hwaddr pgraph_get_texture_palette_phys_addr_length(PGRAPHState *pg, int texture_
6464
TextureShape pgraph_get_texture_shape(PGRAPHState *pg, int texture_idx);
6565
size_t pgraph_get_texture_length(PGRAPHState *pg, TextureShape *shape);
6666

67+
static inline float pgraph_convert_lod_bias_to_float(uint32_t lod_bias)
68+
{
69+
int sign_extended_bias = lod_bias;
70+
if (lod_bias & (1 << 12)) {
71+
sign_extended_bias |= ~NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS;
72+
}
73+
return (float)sign_extended_bias / 256.f;
74+
}
75+
6776
#endif

hw/xbox/nv2a/pgraph/vk/texture.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,14 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
13361336
min_filter == NV_PGRAPH_TEXFILTER0_MIN_BOX_NEARESTLOD ||
13371337
min_filter == NV_PGRAPH_TEXFILTER0_MIN_TENT_NEARESTLOD;
13381338

1339+
float lod_bias = pgraph_convert_lod_bias_to_float(
1340+
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS));
1341+
if (lod_bias > r->device_props.limits.maxSamplerLodBias) {
1342+
lod_bias = r->device_props.limits.maxSamplerLodBias;
1343+
} else if (lod_bias < -r->device_props.limits.maxSamplerLodBias) {
1344+
lod_bias = -r->device_props.limits.maxSamplerLodBias;
1345+
}
1346+
13391347
VkSamplerCreateInfo sampler_create_info = {
13401348
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
13411349
.magFilter = vk_mag_filter,
@@ -1356,7 +1364,7 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
13561364
VK_SAMPLER_MIPMAP_MODE_LINEAR,
13571365
.minLod = mipmap_en ? MIN(state.min_mipmap_level, state.levels - 1) : 0.0,
13581366
.maxLod = mipmap_en ? MIN(state.max_mipmap_level, state.levels - 1) : 0.0,
1359-
.mipLodBias = 0.0,
1367+
.mipLodBias = lod_bias,
13601368
.pNext = sampler_next_struct,
13611369
};
13621370

0 commit comments

Comments
 (0)