mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 11:48:06 +02:00
st/nine: Dummy sampler should have a=1
Reviewed-by: Tiziano Bacocco <tizbac2@gmail.com> Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
parent
9ac74e604b
commit
2c54d154e8
5 changed files with 163 additions and 43 deletions
|
|
@ -298,6 +298,43 @@ NineDevice9_ctor( struct NineDevice9 *This,
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* allocate dummy texture/sampler for when there are missing ones bound */
|
||||
{
|
||||
struct pipe_resource tmplt;
|
||||
struct pipe_sampler_view templ;
|
||||
|
||||
tmplt.target = PIPE_TEXTURE_2D;
|
||||
tmplt.width0 = 1;
|
||||
tmplt.height0 = 1;
|
||||
tmplt.depth0 = 1;
|
||||
tmplt.last_level = 0;
|
||||
tmplt.array_size = 1;
|
||||
tmplt.usage = PIPE_USAGE_DEFAULT;
|
||||
tmplt.flags = 0;
|
||||
tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
tmplt.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
tmplt.nr_samples = 0;
|
||||
|
||||
This->dummy_texture = This->screen->resource_create(This->screen, &tmplt);
|
||||
if (!This->dummy_texture)
|
||||
return D3DERR_DRIVERINTERNALERROR;
|
||||
|
||||
templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
templ.u.tex.first_layer = 0;
|
||||
templ.u.tex.last_layer = 0;
|
||||
templ.u.tex.first_level = 0;
|
||||
templ.u.tex.last_level = 0;
|
||||
templ.swizzle_r = PIPE_SWIZZLE_ZERO;
|
||||
templ.swizzle_g = PIPE_SWIZZLE_ZERO;
|
||||
templ.swizzle_b = PIPE_SWIZZLE_ZERO;
|
||||
templ.swizzle_a = PIPE_SWIZZLE_ONE;
|
||||
templ.target = This->dummy_texture->target;
|
||||
|
||||
This->dummy_sampler = This->pipe->create_sampler_view(This->pipe, This->dummy_texture, &templ);
|
||||
if (!This->dummy_sampler)
|
||||
return D3DERR_DRIVERINTERNALERROR;
|
||||
}
|
||||
|
||||
/* Allocate upload helper for drivers that suck (from st pov ;). */
|
||||
{
|
||||
unsigned bind = 0;
|
||||
|
|
@ -346,6 +383,8 @@ NineDevice9_dtor( struct NineDevice9 *This )
|
|||
|
||||
nine_bind(&This->record, NULL);
|
||||
|
||||
pipe_sampler_view_reference(&This->dummy_sampler, NULL);
|
||||
pipe_resource_reference(&This->dummy_texture, NULL);
|
||||
pipe_resource_reference(&This->constbuf_vs, NULL);
|
||||
pipe_resource_reference(&This->constbuf_ps, NULL);
|
||||
FREE(This->state.vs_const_f);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ struct NineDevice9
|
|||
uint16_t max_vs_const_f;
|
||||
uint16_t max_ps_const_f;
|
||||
|
||||
struct pipe_resource *dummy_texture;
|
||||
struct pipe_sampler_view *dummy_sampler;
|
||||
|
||||
struct gen_mipmap_state *gen_mipmap;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -1493,6 +1493,7 @@ nine_ff_get_ps(struct NineDevice9 *device)
|
|||
enum pipe_error err;
|
||||
struct nine_ff_ps_key key;
|
||||
unsigned s;
|
||||
uint8_t sampler_mask = 0;
|
||||
|
||||
assert(sizeof(key) <= sizeof(key.value32));
|
||||
|
||||
|
|
@ -1506,12 +1507,17 @@ nine_ff_get_ps(struct NineDevice9 *device)
|
|||
key.ts[s].alphaop = D3DTOP_DISABLE; /* DISABLE == 1, avoid degenerate keys */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!state->texture[s] &&
|
||||
state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE) {
|
||||
/* This should also disable the stage. */
|
||||
key.ts[s].colorop = key.ts[s].alphaop = D3DTOP_DISABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state->ff.tex_stage[s][D3DTSS_COLORARG1] == D3DTA_TEXTURE)
|
||||
sampler_mask |= (1 << s);
|
||||
|
||||
if (key.ts[s].colorop != D3DTOP_DISABLE) {
|
||||
uint8_t used_c = ps_d3dtop_args_mask(key.ts[s].colorop);
|
||||
if (used_c & 0x1) key.ts[s].colorarg0 = state->ff.tex_stage[s][D3DTSS_COLORARG0];
|
||||
|
|
@ -1570,6 +1576,7 @@ nine_ff_get_ps(struct NineDevice9 *device)
|
|||
NineUnknown_ConvertRefToBind(NineUnknown(ps));
|
||||
|
||||
ps->rt_mask = 0x1;
|
||||
ps->sampler_mask = sampler_mask;
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,6 +279,7 @@ update_vs(struct NineDevice9 *device)
|
|||
{
|
||||
struct nine_state *state = &device->state;
|
||||
struct NineVertexShader9 *vs = state->vs;
|
||||
uint32_t changed_group = 0;
|
||||
|
||||
/* likely because we dislike FF */
|
||||
if (likely(vs)) {
|
||||
|
|
@ -291,17 +292,13 @@ update_vs(struct NineDevice9 *device)
|
|||
|
||||
if (state->rs[NINED3DRS_VSPOINTSIZE] != vs->point_size) {
|
||||
state->rs[NINED3DRS_VSPOINTSIZE] = vs->point_size;
|
||||
return NINE_STATE_RASTERIZER;
|
||||
changed_group |= NINE_STATE_RASTERIZER;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
{
|
||||
unsigned s, mask = vs->sampler_mask;
|
||||
for (s = 0; mask; ++s, mask >>= 1)
|
||||
if ((mask & 1) && !(device->state.texture[NINE_SAMPLER_VS(s)]))
|
||||
WARN_ONCE("FIXME: unbound sampler should return alpha=1\n");
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
if ((state->bound_samplers_mask_vs & vs->sampler_mask) != vs->sampler_mask)
|
||||
/* Bound dummy sampler. */
|
||||
changed_group |= NINE_STATE_SAMPLER;
|
||||
return changed_group;
|
||||
}
|
||||
|
||||
static INLINE uint32_t
|
||||
|
|
@ -309,6 +306,7 @@ update_ps(struct NineDevice9 *device)
|
|||
{
|
||||
struct nine_state *state = &device->state;
|
||||
struct NinePixelShader9 *ps = state->ps;
|
||||
uint32_t changed_group = 0;
|
||||
|
||||
if (likely(ps)) {
|
||||
state->cso.ps = NinePixelShader9_GetVariant(ps, state->ps_key);
|
||||
|
|
@ -318,15 +316,10 @@ update_ps(struct NineDevice9 *device)
|
|||
}
|
||||
device->pipe->bind_fs_state(device->pipe, state->cso.ps);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
unsigned s, mask = ps->sampler_mask;
|
||||
for (s = 0; mask; ++s, mask >>= 1)
|
||||
if ((mask & 1) && !(device->state.texture[NINE_SAMPLER_PS(s)]))
|
||||
WARN_ONCE("FIXME: unbound sampler should return alpha=1\n");
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
if ((state->bound_samplers_mask_ps & ps->sampler_mask) != ps->sampler_mask)
|
||||
/* Bound dummy sampler. */
|
||||
changed_group |= NINE_STATE_SAMPLER;
|
||||
return changed_group;
|
||||
}
|
||||
|
||||
#define DO_UPLOAD_CONST_F(buf,p,c,d) \
|
||||
|
|
@ -651,66 +644,142 @@ update_textures_and_samplers(struct NineDevice9 *device)
|
|||
struct pipe_context *pipe = device->pipe;
|
||||
struct nine_state *state = &device->state;
|
||||
struct pipe_sampler_view *view[NINE_MAX_SAMPLERS];
|
||||
struct pipe_sampler_state samp;
|
||||
unsigned num_textures;
|
||||
unsigned i;
|
||||
boolean commit_views;
|
||||
boolean commit_samplers;
|
||||
uint16_t sampler_mask = state->ps ? state->ps->sampler_mask :
|
||||
device->ff.ps->sampler_mask;
|
||||
|
||||
/* TODO: Can we reduce iterations here ? */
|
||||
|
||||
commit_views = FALSE;
|
||||
commit_samplers = FALSE;
|
||||
state->bound_samplers_mask_ps = 0;
|
||||
for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_PS; ++i) {
|
||||
const unsigned s = NINE_SAMPLER_PS(i);
|
||||
int sRGB;
|
||||
if (!state->texture[s]) {
|
||||
|
||||
if (!state->texture[s] && !(sampler_mask & (1 << i))) {
|
||||
view[i] = NULL;
|
||||
#ifdef DEBUG
|
||||
if (state->ps && state->ps->sampler_mask & (1 << i))
|
||||
WARN_ONCE("FIXME: unbound sampler should return alpha=1\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
|
||||
|
||||
view[i] = NineBaseTexture9_GetSamplerView(state->texture[s], sRGB);
|
||||
num_textures = i + 1;
|
||||
if (state->texture[s]) {
|
||||
sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
|
||||
|
||||
if (update_sampler_derived(state, s) || (state->changed.sampler[s] & 0x05fe)) {
|
||||
state->changed.sampler[s] = 0;
|
||||
view[i] = NineBaseTexture9_GetSamplerView(state->texture[s], sRGB);
|
||||
num_textures = i + 1;
|
||||
|
||||
if (update_sampler_derived(state, s) || (state->changed.sampler[s] & 0x05fe)) {
|
||||
state->changed.sampler[s] = 0;
|
||||
commit_samplers = TRUE;
|
||||
nine_convert_sampler_state(device->cso, s, state->samp[s]);
|
||||
}
|
||||
} else {
|
||||
/* Bind dummy sampler. We do not bind dummy sampler when
|
||||
* it is not needed because it could add overhead. The
|
||||
* dummy sampler should have r=g=b=0 and a=1. We do not
|
||||
* unbind dummy sampler directly when they are not needed
|
||||
* anymore, but they're going to be removed as long as texture
|
||||
* or sampler states are changed. */
|
||||
view[i] = device->dummy_sampler;
|
||||
num_textures = i + 1;
|
||||
|
||||
memset(&samp, 0, sizeof(samp));
|
||||
samp.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
samp.max_lod = 15.0f;
|
||||
samp.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
samp.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
samp.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
samp.min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
samp.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
samp.compare_mode = PIPE_TEX_COMPARE_NONE;
|
||||
samp.compare_func = PIPE_FUNC_LEQUAL;
|
||||
samp.normalized_coords = 1;
|
||||
samp.seamless_cube_map = 1;
|
||||
|
||||
cso_single_sampler(device->cso, PIPE_SHADER_FRAGMENT,
|
||||
s - NINE_SAMPLER_PS(0), &samp);
|
||||
|
||||
commit_views = TRUE;
|
||||
commit_samplers = TRUE;
|
||||
nine_convert_sampler_state(device->cso, s, state->samp[s]);
|
||||
state->changed.sampler[s] = ~0;
|
||||
}
|
||||
|
||||
state->bound_samplers_mask_ps |= (1 << s);
|
||||
}
|
||||
if (state->changed.texture & NINE_PS_SAMPLERS_MASK || state->changed.srgb)
|
||||
|
||||
commit_views |= (state->changed.texture & NINE_PS_SAMPLERS_MASK) != 0;
|
||||
commit_views |= state->changed.srgb;
|
||||
if (commit_views)
|
||||
pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
|
||||
num_textures, view);
|
||||
|
||||
if (commit_samplers)
|
||||
cso_single_sampler_done(device->cso, PIPE_SHADER_FRAGMENT);
|
||||
|
||||
commit_views = FALSE;
|
||||
commit_samplers = FALSE;
|
||||
sampler_mask = state->vs ? state->vs->sampler_mask : 0;
|
||||
state->bound_samplers_mask_vs = 0;
|
||||
for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_VS; ++i) {
|
||||
const unsigned s = NINE_SAMPLER_VS(i);
|
||||
int sRGB;
|
||||
if (!state->texture[s]) {
|
||||
|
||||
if (!state->texture[s] && !(sampler_mask & (1 << i))) {
|
||||
view[i] = NULL;
|
||||
#ifdef DEBUG
|
||||
if (state->vs && state->vs->sampler_mask & (1 << i))
|
||||
WARN_ONCE("FIXME: unbound sampler should return alpha=1\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
|
||||
|
||||
view[i] = NineBaseTexture9_GetSamplerView(state->texture[s], sRGB);
|
||||
num_textures = i + 1;
|
||||
if (state->texture[s]) {
|
||||
sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
|
||||
|
||||
if (update_sampler_derived(state, s) || (state->changed.sampler[s] & 0x05fe)) {
|
||||
state->changed.sampler[s] = 0;
|
||||
view[i] = NineBaseTexture9_GetSamplerView(state->texture[s], sRGB);
|
||||
num_textures = i + 1;
|
||||
|
||||
if (update_sampler_derived(state, s) || (state->changed.sampler[s] & 0x05fe)) {
|
||||
state->changed.sampler[s] = 0;
|
||||
commit_samplers = TRUE;
|
||||
nine_convert_sampler_state(device->cso, s, state->samp[s]);
|
||||
}
|
||||
} else {
|
||||
/* Bind dummy sampler. We do not bind dummy sampler when
|
||||
* it is not needed because it could add overhead. The
|
||||
* dummy sampler should have r=g=b=0 and a=1. We do not
|
||||
* unbind dummy sampler directly when they are not needed
|
||||
* anymore, but they're going to be removed as long as texture
|
||||
* or sampler states are changed. */
|
||||
view[i] = device->dummy_sampler;
|
||||
num_textures = i + 1;
|
||||
|
||||
memset(&samp, 0, sizeof(samp));
|
||||
samp.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
samp.max_lod = 15.0f;
|
||||
samp.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
samp.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
samp.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
samp.min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
samp.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
samp.compare_mode = PIPE_TEX_COMPARE_NONE;
|
||||
samp.compare_func = PIPE_FUNC_LEQUAL;
|
||||
samp.normalized_coords = 1;
|
||||
samp.seamless_cube_map = 1;
|
||||
|
||||
cso_single_sampler(device->cso, PIPE_SHADER_VERTEX,
|
||||
s - NINE_SAMPLER_VS(0), &samp);
|
||||
|
||||
commit_views = TRUE;
|
||||
commit_samplers = TRUE;
|
||||
nine_convert_sampler_state(device->cso, s, state->samp[s]);
|
||||
state->changed.sampler[s] = ~0;
|
||||
}
|
||||
|
||||
state->bound_samplers_mask_vs |= (1 << s);
|
||||
}
|
||||
if (state->changed.texture & NINE_VS_SAMPLERS_MASK || state->changed.srgb)
|
||||
commit_views |= (state->changed.texture & NINE_VS_SAMPLERS_MASK) != 0;
|
||||
commit_views |= state->changed.srgb;
|
||||
if (commit_views)
|
||||
pipe->set_sampler_views(pipe, PIPE_SHADER_VERTEX, 0,
|
||||
num_textures, view);
|
||||
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ struct nine_state
|
|||
|
||||
DWORD samp[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
|
||||
uint32_t samplers_shadow;
|
||||
uint8_t bound_samplers_mask_vs;
|
||||
uint16_t bound_samplers_mask_ps;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue