nv2a: Handle anisotropic filter setting

This commit is contained in:
Erik Abair
2025-09-25 12:12:28 -07:00
committed by GitHub
parent 59626b1f5d
commit 518208e849
7 changed files with 44 additions and 13 deletions
+1
View File
@@ -539,6 +539,7 @@
#define NV_PGRAPH_TEXCTL0_0 0x000019CC
# define NV_PGRAPH_TEXCTL0_0_COLORKEYMODE 0x03
# define NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN (1 << 2)
# define NV_PGRAPH_TEXCTL0_0_MAX_ANISOTROPY 0x30
# define NV_PGRAPH_TEXCTL0_0_MAX_LOD_CLAMP 0x0003FFC0
# define NV_PGRAPH_TEXCTL0_0_MIN_LOD_CLAMP 0x3FFC0000
# define NV_PGRAPH_TEXCTL0_0_ENABLE (1 << 30)
+3
View File
@@ -66,6 +66,9 @@ static void pgraph_gl_init(NV2AState *d, Error **errp)
pg->uniform_attrs = 0;
pg->swizzle_attrs = 0;
r->supported_extensions.texture_filter_anisotropic =
glo_check_extension("GL_EXT_texture_filter_anisotropic");
}
static void pgraph_gl_finalize(NV2AState *d)
+4
View File
@@ -234,6 +234,10 @@ typedef struct PGRAPHGLState {
GLfloat supported_aliased_line_width_range[2];
GLfloat supported_smooth_line_width_range[2];
struct supported_extensions {
GLboolean texture_filter_anisotropic;
} supported_extensions;
} PGRAPHGLState;
extern GloContext *g_nv2a_context_render;
+20 -6
View File
@@ -107,13 +107,15 @@ static bool check_texture_possibly_dirty(NV2AState *d,
return possibly_dirty;
}
static void apply_texture_parameters(TextureBinding *binding,
static void apply_texture_parameters(PGRAPHGLState *r,
TextureBinding *binding,
const BasicColorFormatInfo *f,
unsigned int dimensionality,
unsigned int filter,
unsigned int address,
bool is_bordered,
uint32_t border_color)
uint32_t border_color,
uint32_t max_anisotropy)
{
unsigned int min_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIN);
unsigned int mag_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MAG);
@@ -181,6 +183,11 @@ static void apply_texture_parameters(TextureBinding *binding,
needs_border_color = needs_border_color || binding->addrp == NV_PGRAPH_TEXADDRESS0_ADDRU_BORDER;
}
if (r->supported_extensions.texture_filter_anisotropic) {
glTexParameterf(binding->gl_target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
max_anisotropy);
}
if (!is_bordered && needs_border_color) {
if (!binding->border_color_set || binding->border_color != border_color) {
/* FIXME: Color channels might be wrong order */
@@ -219,6 +226,9 @@ void pgraph_gl_bind_textures(NV2AState *d)
uint32_t filter = pgraph_reg_r(pg, NV_PGRAPH_TEXFILTER0 + i*4);
uint32_t address = pgraph_reg_r(pg, NV_PGRAPH_TEXADDRESS0 + i*4);
uint32_t border_color = pgraph_reg_r(pg, NV_PGRAPH_BORDERCOLOR0 + i*4);
uint32_t max_anisotropy =
1 << (GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_TEXCTL0_0 + i*4),
NV_PGRAPH_TEXCTL0_0_MAX_ANISOTROPY));
/* Check for unsupported features */
if (filter & NV_PGRAPH_TEXFILTER0_ASIGNED) NV2A_UNIMPLEMENTED("NV_PGRAPH_TEXFILTER0_ASIGNED");
@@ -262,13 +272,15 @@ void pgraph_gl_bind_textures(NV2AState *d)
if (reusable) {
glBindTexture(r->texture_binding[i]->gl_target,
r->texture_binding[i]->gl_texture);
apply_texture_parameters(r->texture_binding[i],
apply_texture_parameters(r,
r->texture_binding[i],
&kelvin_color_format_info_map[state.color_format],
state.dimensionality,
filter,
address,
state.border,
border_color);
border_color,
max_anisotropy);
continue;
}
}
@@ -372,13 +384,15 @@ void pgraph_gl_bind_textures(NV2AState *d)
binding->scale = pg->surface_scale_factor;
}
apply_texture_parameters(binding,
apply_texture_parameters(r,
binding,
&kelvin_color_format_info_map[state.color_format],
state.dimensionality,
filter,
address,
state.border,
border_color);
border_color,
max_anisotropy);
if (r->texture_binding[i]) {
if (r->texture_binding[i]->gl_target != binding->gl_target) {
+5 -4
View File
@@ -540,12 +540,13 @@ static bool create_logical_device(PGRAPHState *pg, Error **errp)
.enabled = &r->enabled_physical_device_features.n, \
.required = req, \
}
F(shaderClipDistance, true),
F(geometryShader, true),
F(shaderTessellationAndGeometryPointSize, true),
F(depthClamp, true),
F(occlusionQueryPrecise, true),
F(fillModeNonSolid, true),
F(geometryShader, true),
F(occlusionQueryPrecise, true),
F(samplerAnisotropy, false),
F(shaderClipDistance, true),
F(shaderTessellationAndGeometryPointSize, true),
F(wideLines, false),
#undef F
// clang-format on
+1
View File
@@ -206,6 +206,7 @@ typedef struct TextureKey {
uint32_t filter;
uint32_t address;
uint32_t border_color;
uint32_t max_anisotropy;
} TextureKey;
typedef struct TextureBinding {
+10 -3
View File
@@ -1101,6 +1101,9 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
pgraph_reg_r(pg, NV_PGRAPH_BORDERCOLOR0 + texture_idx * 4);
bool is_indexed = (state.color_format ==
NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8);
uint32_t max_anisotropy =
1 << (GET_MASK(pgraph_reg_r(pg, NV_PGRAPH_TEXCTL0_0 + texture_idx*4),
NV_PGRAPH_TEXCTL0_0_MAX_ANISOTROPY));
TextureKey key;
memset(&key, 0, sizeof(key));
@@ -1120,6 +1123,7 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
key.filter = filter;
key.address = address;
key.border_color = border_color_pack32;
key.max_anisotropy = max_anisotropy;
bool possibly_dirty = false;
bool possibly_dirty_checked = false;
@@ -1343,6 +1347,8 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
} else if (lod_bias < -r->device_props.limits.maxSamplerLodBias) {
lod_bias = -r->device_props.limits.maxSamplerLodBias;
}
uint32_t sampler_max_anisotropy =
MIN(r->device_props.limits.maxSamplerAnisotropy, max_anisotropy);
VkSamplerCreateInfo sampler_create_info = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@@ -1354,9 +1360,10 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRV)),
.addressModeW = (state.dimensionality > 2) ? lookup_texture_address_mode(
GET_MASK(address, NV_PGRAPH_TEXADDRESS0_ADDRP)) : 0,
.anisotropyEnable = VK_FALSE,
// .anisotropyEnable = VK_TRUE,
// .maxAnisotropy = properties.limits.maxSamplerAnisotropy,
.anisotropyEnable =
r->enabled_physical_device_features.samplerAnisotropy &&
sampler_max_anisotropy > 1,
.maxAnisotropy = sampler_max_anisotropy,
.borderColor = vk_border_color,
.compareEnable = VK_FALSE,
.compareOp = VK_COMPARE_OP_ALWAYS,