mirror of https://github.com/xemu-project/xemu.git
nv2a: Cache texture attributes to avoid resetting unnecessarily
This commit is contained in:
parent
5f306e749e
commit
c2031108c5
|
@ -177,6 +177,13 @@ typedef struct TextureBinding {
|
||||||
int draw_time;
|
int draw_time;
|
||||||
uint64_t data_hash;
|
uint64_t data_hash;
|
||||||
unsigned int scale;
|
unsigned int scale;
|
||||||
|
unsigned int min_filter;
|
||||||
|
unsigned int mag_filter;
|
||||||
|
unsigned int addru;
|
||||||
|
unsigned int addrv;
|
||||||
|
unsigned int addrp;
|
||||||
|
uint32_t border_color;
|
||||||
|
bool border_color_set;
|
||||||
} TextureBinding;
|
} TextureBinding;
|
||||||
|
|
||||||
typedef struct TextureKey {
|
typedef struct TextureKey {
|
||||||
|
|
|
@ -6403,17 +6403,20 @@ static bool pgraph_check_texture_possibly_dirty(NV2AState *d, hwaddr texture_vra
|
||||||
return possibly_dirty;
|
return possibly_dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_texture_parameters(GLenum gl_target,
|
static void apply_texture_parameters(TextureBinding *binding,
|
||||||
const ColorFormatInfo *f,
|
const ColorFormatInfo *f,
|
||||||
unsigned int dimensionality,
|
unsigned int dimensionality,
|
||||||
unsigned int min_filter,
|
unsigned int filter,
|
||||||
unsigned int mag_filter,
|
unsigned int address,
|
||||||
unsigned int addru,
|
|
||||||
unsigned int addrv,
|
|
||||||
unsigned int addrp,
|
|
||||||
bool is_bordered,
|
bool is_bordered,
|
||||||
uint32_t border_color)
|
uint32_t border_color)
|
||||||
{
|
{
|
||||||
|
unsigned int min_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIN);
|
||||||
|
unsigned int mag_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MAG);
|
||||||
|
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);
|
||||||
|
|
||||||
if (f->linear) {
|
if (f->linear) {
|
||||||
/* somtimes games try to set mipmap min filters on linear textures.
|
/* somtimes games try to set mipmap min filters on linear textures.
|
||||||
* this could indicate a bug... */
|
* this could indicate a bug... */
|
||||||
|
@ -6429,37 +6432,59 @@ static void apply_texture_parameters(GLenum gl_target,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexParameteri(gl_target, GL_TEXTURE_MIN_FILTER,
|
if (min_filter != binding->min_filter) {
|
||||||
pgraph_texture_min_filter_map[min_filter]);
|
glTexParameteri(binding->gl_target, GL_TEXTURE_MIN_FILTER,
|
||||||
glTexParameteri(gl_target, GL_TEXTURE_MAG_FILTER,
|
pgraph_texture_min_filter_map[min_filter]);
|
||||||
pgraph_texture_mag_filter_map[mag_filter]);
|
binding->min_filter = min_filter;
|
||||||
|
}
|
||||||
|
if (mag_filter != binding->mag_filter) {
|
||||||
|
glTexParameteri(binding->gl_target, GL_TEXTURE_MAG_FILTER,
|
||||||
|
pgraph_texture_mag_filter_map[mag_filter]);
|
||||||
|
binding->mag_filter = mag_filter;
|
||||||
|
}
|
||||||
|
|
||||||
/* Texture wrapping */
|
/* Texture wrapping */
|
||||||
assert(addru < ARRAY_SIZE(pgraph_texture_addr_map));
|
assert(addru < ARRAY_SIZE(pgraph_texture_addr_map));
|
||||||
glTexParameteri(gl_target, GL_TEXTURE_WRAP_S,
|
if (addru != binding->addru) {
|
||||||
pgraph_texture_addr_map[addru]);
|
glTexParameteri(binding->gl_target, GL_TEXTURE_WRAP_S,
|
||||||
|
pgraph_texture_addr_map[addru]);
|
||||||
|
binding->addru = addru;
|
||||||
|
}
|
||||||
|
bool needs_border_color = binding->addru == NV_PGRAPH_TEXADDRESS0_ADDRU_BORDER;
|
||||||
if (dimensionality > 1) {
|
if (dimensionality > 1) {
|
||||||
assert(addrv < ARRAY_SIZE(pgraph_texture_addr_map));
|
if (addrv != binding->addrv) {
|
||||||
glTexParameteri(gl_target, GL_TEXTURE_WRAP_T,
|
assert(addrv < ARRAY_SIZE(pgraph_texture_addr_map));
|
||||||
pgraph_texture_addr_map[addrv]);
|
glTexParameteri(binding->gl_target, GL_TEXTURE_WRAP_T,
|
||||||
|
pgraph_texture_addr_map[addrv]);
|
||||||
|
binding->addrv = addrv;
|
||||||
|
}
|
||||||
|
needs_border_color = needs_border_color || binding->addrv == NV_PGRAPH_TEXADDRESS0_ADDRU_BORDER;
|
||||||
}
|
}
|
||||||
if (dimensionality > 2) {
|
if (dimensionality > 2) {
|
||||||
assert(addrp < ARRAY_SIZE(pgraph_texture_addr_map));
|
if (addrp != binding->addrp) {
|
||||||
glTexParameteri(gl_target, GL_TEXTURE_WRAP_R,
|
assert(addrp < ARRAY_SIZE(pgraph_texture_addr_map));
|
||||||
pgraph_texture_addr_map[addrp]);
|
glTexParameteri(binding->gl_target, GL_TEXTURE_WRAP_R,
|
||||||
|
pgraph_texture_addr_map[addrp]);
|
||||||
|
binding->addrp = addrp;
|
||||||
|
}
|
||||||
|
needs_border_color = needs_border_color || binding->addrp == NV_PGRAPH_TEXADDRESS0_ADDRU_BORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_bordered) {
|
if (!is_bordered && needs_border_color) {
|
||||||
/* FIXME: Only upload if necessary? [s, t or r = GL_CLAMP_TO_BORDER] */
|
if (!binding->border_color_set || binding->border_color != border_color) {
|
||||||
GLfloat gl_border_color[] = {
|
GLfloat gl_border_color[] = {
|
||||||
/* FIXME: Color channels might be wrong order */
|
/* FIXME: Color channels might be wrong order */
|
||||||
((border_color >> 16) & 0xFF) / 255.0f, /* red */
|
((border_color >> 16) & 0xFF) / 255.0f, /* red */
|
||||||
((border_color >> 8) & 0xFF) / 255.0f, /* green */
|
((border_color >> 8) & 0xFF) / 255.0f, /* green */
|
||||||
(border_color & 0xFF) / 255.0f, /* blue */
|
(border_color & 0xFF) / 255.0f, /* blue */
|
||||||
((border_color >> 24) & 0xFF) / 255.0f /* alpha */
|
((border_color >> 24) & 0xFF) / 255.0f /* alpha */
|
||||||
};
|
};
|
||||||
glTexParameterfv(gl_target, GL_TEXTURE_BORDER_COLOR,
|
glTexParameterfv(binding->gl_target, GL_TEXTURE_BORDER_COLOR,
|
||||||
gl_border_color);
|
gl_border_color);
|
||||||
|
|
||||||
|
binding->border_color_set = true;
|
||||||
|
binding->border_color = border_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6522,13 +6547,6 @@ static void pgraph_bind_textures(NV2AState *d)
|
||||||
unsigned int lod_bias =
|
unsigned int lod_bias =
|
||||||
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS);
|
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS);
|
||||||
#endif
|
#endif
|
||||||
unsigned int min_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIN);
|
|
||||||
unsigned int mag_filter = GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MAG);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
unsigned int border_source = GET_MASK(fmt,
|
unsigned int border_source = GET_MASK(fmt,
|
||||||
NV_PGRAPH_TEXFMT0_BORDER_SOURCE);
|
NV_PGRAPH_TEXFMT0_BORDER_SOURCE);
|
||||||
uint32_t border_color = pg->regs[NV_PGRAPH_BORDERCOLOR0 + i*4];
|
uint32_t border_color = pg->regs[NV_PGRAPH_BORDERCOLOR0 + i*4];
|
||||||
|
@ -6715,14 +6733,11 @@ static void pgraph_bind_textures(NV2AState *d)
|
||||||
if (reusable) {
|
if (reusable) {
|
||||||
glBindTexture(pg->texture_binding[i]->gl_target,
|
glBindTexture(pg->texture_binding[i]->gl_target,
|
||||||
pg->texture_binding[i]->gl_texture);
|
pg->texture_binding[i]->gl_texture);
|
||||||
apply_texture_parameters(pg->texture_binding[i]->gl_target,
|
apply_texture_parameters(pg->texture_binding[i],
|
||||||
&f,
|
&f,
|
||||||
dimensionality,
|
dimensionality,
|
||||||
min_filter,
|
filter,
|
||||||
mag_filter,
|
address,
|
||||||
addru,
|
|
||||||
addrv,
|
|
||||||
addrp,
|
|
||||||
is_bordered,
|
is_bordered,
|
||||||
border_color);
|
border_color);
|
||||||
continue;
|
continue;
|
||||||
|
@ -6843,14 +6858,11 @@ static void pgraph_bind_textures(NV2AState *d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_texture_parameters(binding->gl_target,
|
apply_texture_parameters(binding,
|
||||||
&f,
|
&f,
|
||||||
dimensionality,
|
dimensionality,
|
||||||
min_filter,
|
filter,
|
||||||
mag_filter,
|
address,
|
||||||
addru,
|
|
||||||
addrv,
|
|
||||||
addrp,
|
|
||||||
is_bordered,
|
is_bordered,
|
||||||
border_color);
|
border_color);
|
||||||
|
|
||||||
|
@ -7592,6 +7604,12 @@ static TextureBinding* generate_texture(const TextureShape s,
|
||||||
ret->refcnt = 1;
|
ret->refcnt = 1;
|
||||||
ret->draw_time = 0;
|
ret->draw_time = 0;
|
||||||
ret->data_hash = 0;
|
ret->data_hash = 0;
|
||||||
|
ret->min_filter = 0xFFFFFFFF;
|
||||||
|
ret->mag_filter = 0xFFFFFFFF;
|
||||||
|
ret->addru = 0xFFFFFFFF;
|
||||||
|
ret->addrv = 0xFFFFFFFF;
|
||||||
|
ret->addrp = 0xFFFFFFFF;
|
||||||
|
ret->border_color_set = false;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue