mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
nv2a: Handle anisotropic filter setting
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user