if (Sampler >= D3DDMAPSAMPLER)
Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS;
- if (state->samp_advertised[Sampler][Type] != Value || unlikely(This->is_recording)) {
- /* Contrary to render states, old value is kept if new value is wrong (except intel + Value == 0) */
- if (likely(nine_check_sampler_state_value(Type, Value)))
- state->samp[Sampler][Type] = Value;
+ if (unlikely(This->is_recording)) {
state->samp_advertised[Sampler][Type] = Value;
state->changed.group |= NINE_STATE_SAMPLER;
state->changed.sampler[Sampler] |= 1 << Type;
+ return D3D_OK;
}
+ if (state->samp_advertised[Sampler][Type] == Value)
+ return D3D_OK;
+
+ state->samp_advertised[Sampler][Type] = Value;
+ nine_context_set_sampler_state(This, Sampler, Type, Value);
+
return D3D_OK;
}
DBG("This=%p pNumPasses=%p\n", This, pNumPasses);
- for (i = 0; i < ARRAY_SIZE(state->samp); ++i) {
- if (state->samp[i][D3DSAMP_MINFILTER] == D3DTEXF_NONE ||
- state->samp[i][D3DSAMP_MAGFILTER] == D3DTEXF_NONE)
+ for (i = 0; i < ARRAY_SIZE(state->samp_advertised); ++i) {
+ if (state->samp_advertised[i][D3DSAMP_MINFILTER] == D3DTEXF_NONE ||
+ state->samp_advertised[i][D3DSAMP_MAGFILTER] == D3DTEXF_NONE)
return D3DERR_UNSUPPORTEDTEXTUREFILTER;
}
}
static inline boolean
-update_sampler_derived(struct nine_state *state, struct nine_context *context, unsigned s)
+update_sampler_derived(struct nine_context *context, unsigned s)
{
boolean changed = FALSE;
- if (state->samp[s][NINED3DSAMP_SHADOW] != context->texture[s]->shadow) {
+ if (context->samp[s][NINED3DSAMP_SHADOW] != context->texture[s]->shadow) {
changed = TRUE;
- state->samp[s][NINED3DSAMP_SHADOW] = context->texture[s]->shadow;
+ context->samp[s][NINED3DSAMP_SHADOW] = context->texture[s]->shadow;
}
- if (state->samp[s][NINED3DSAMP_CUBETEX] !=
+ if (context->samp[s][NINED3DSAMP_CUBETEX] !=
(NineResource9(context->texture[s])->type == D3DRTYPE_CUBETEXTURE)) {
changed = TRUE;
- state->samp[s][NINED3DSAMP_CUBETEX] =
+ context->samp[s][NINED3DSAMP_CUBETEX] =
NineResource9(context->texture[s])->type == D3DRTYPE_CUBETEXTURE;
}
- if (state->samp[s][D3DSAMP_MIPFILTER] != D3DTEXF_NONE) {
- int lod = state->samp[s][D3DSAMP_MAXMIPLEVEL] - context->texture[s]->managed.lod;
+ if (context->samp[s][D3DSAMP_MIPFILTER] != D3DTEXF_NONE) {
+ int lod = context->samp[s][D3DSAMP_MAXMIPLEVEL] - context->texture[s]->managed.lod;
if (lod < 0)
lod = 0;
- if (state->samp[s][NINED3DSAMP_MINLOD] != lod) {
+ if (context->samp[s][NINED3DSAMP_MINLOD] != lod) {
changed = TRUE;
- state->samp[s][NINED3DSAMP_MINLOD] = lod;
+ context->samp[s][NINED3DSAMP_MINLOD] = lod;
}
} else {
- state->changed.sampler[s] &= ~0x300; /* lod changes irrelevant */
+ context->changed.sampler[s] &= ~0x300; /* lod changes irrelevant */
}
return changed;
}
if (context->texture[s]) {
- sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
+ sRGB = context->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
view[i] = NineBaseTexture9_GetSamplerView(context->texture[s], sRGB);
num_textures = i + 1;
- if (update_sampler_derived(state, context, s) || (state->changed.sampler[s] & 0x05fe)) {
- state->changed.sampler[s] = 0;
+ if (update_sampler_derived(context, s) || (context->changed.sampler[s] & 0x05fe)) {
+ context->changed.sampler[s] = 0;
commit_samplers = TRUE;
- nine_convert_sampler_state(device->cso, s, state->samp[s]);
+ nine_convert_sampler_state(device->cso, s, context->samp[s]);
}
} else {
/* Bind dummy sampler. We do not bind dummy sampler when
s - NINE_SAMPLER_PS(0), &device->dummy_sampler_state);
commit_samplers = TRUE;
- state->changed.sampler[s] = ~0;
+ context->changed.sampler[s] = ~0;
}
context->bound_samplers_mask_ps |= (1 << s);
}
if (context->texture[s]) {
- sRGB = state->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
+ sRGB = context->samp[s][D3DSAMP_SRGBTEXTURE] ? 1 : 0;
view[i] = NineBaseTexture9_GetSamplerView(context->texture[s], sRGB);
num_textures = i + 1;
- if (update_sampler_derived(state, context, s) || (state->changed.sampler[s] & 0x05fe)) {
- state->changed.sampler[s] = 0;
+ if (update_sampler_derived(context, s) || (context->changed.sampler[s] & 0x05fe)) {
+ context->changed.sampler[s] = 0;
commit_samplers = TRUE;
- nine_convert_sampler_state(device->cso, s, state->samp[s]);
+ nine_convert_sampler_state(device->cso, s, context->samp[s]);
}
} else {
/* Bind dummy sampler. We do not bind dummy sampler when
s - NINE_SAMPLER_VS(0), &device->dummy_sampler_state);
commit_samplers = TRUE;
- state->changed.sampler[s] = ~0;
+ context->changed.sampler[s] = ~0;
}
context->bound_samplers_mask_vs |= (1 << s);
state->changed.group |= NINE_STATE_TEXTURE;
}
+void
+nine_context_set_sampler_state(struct NineDevice9 *device,
+ DWORD Sampler,
+ D3DSAMPLERSTATETYPE Type,
+ DWORD Value)
+{
+ struct nine_state *state = &device->state;
+ struct nine_context *context = &device->context;
+
+ if (unlikely(!nine_check_sampler_state_value(Type, Value)))
+ return;
+
+ context->samp[Sampler][Type] = Value;
+ state->changed.group |= NINE_STATE_SAMPLER;
+ context->changed.sampler[Sampler] |= 1 << Type;
+}
+
void
nine_context_set_stream_source(struct NineDevice9 *device,
UINT StreamNumber,
}
}
+ /* Sampler state */
+ if (src->changed.group & NINE_STATE_SAMPLER) {
+ unsigned s;
+
+ for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
+ uint32_t m = src->changed.sampler[s];
+ while (m) {
+ const int i = ffs(m) - 1;
+ m &= ~(1 << i);
+ if (nine_check_sampler_state_value(i, src->samp_advertised[s][i]))
+ context->samp[s][i] = src->samp_advertised[s][i];
+ }
+ context->changed.sampler[s] |= src->changed.sampler[s];
+ }
+ }
+
/* Vertex buffers */
if (src->changed.vtxbuf | src->changed.stream_freq) {
uint32_t m = src->changed.vtxbuf | src->changed.stream_freq;
state->ff.tex_stage[0][D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
memset(&context->bumpmap_vars, 0, sizeof(context->bumpmap_vars));
- for (s = 0; s < ARRAY_SIZE(state->samp); ++s) {
- memcpy(&state->samp[s], nine_samp_state_defaults,
- sizeof(state->samp[s]));
+ for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
+ memcpy(&context->samp[s], nine_samp_state_defaults,
+ sizeof(context->samp[s]));
memcpy(&state->samp_advertised[s], nine_samp_state_defaults,
sizeof(state->samp_advertised[s]));
}
state->viewport.MaxZ = 1.0f;
}
- for (s = 0; s < ARRAY_SIZE(state->changed.sampler); ++s)
- state->changed.sampler[s] = ~0;
+ for (s = 0; s < NINE_MAX_SAMPLERS; ++s)
+ context->changed.sampler[s] = ~0;
if (!is_reset) {
context->dummy_vbo_bound_at = -1;
#define NINED3DRS_MULTISAMPLE (D3DRS_BLENDOPALPHA + 4)
#define D3DRS_LAST D3DRS_BLENDOPALPHA
+#define D3DSAMP_LAST D3DSAMP_DMAPOFFSET
#define NINED3DRS_LAST NINED3DRS_MULTISAMPLE /* 214 */
#define NINED3DSAMP_LAST NINED3DSAMP_CUBETEX /* 16 */
#define NINED3DTSS_LAST D3DTSS_CONSTANT
#define NINED3DTS_LAST D3DTS_WORLDMATRIX(255)
#define D3DRS_COUNT (D3DRS_LAST + 1)
+#define D3DSAMP_COUNT (D3DSAMP_LAST + 1)
#define NINED3DRS_COUNT (NINED3DRS_LAST + 1)
#define NINED3DSAMP_COUNT (NINED3DSAMP_LAST + 1)
#define NINED3DTSS_COUNT (NINED3DTSS_LAST + 1)
uint32_t vtxbuf; /* stateblocks only */
uint32_t stream_freq; /* stateblocks only */
uint32_t texture; /* stateblocks only */
- uint16_t sampler[NINE_MAX_SAMPLERS];
+ uint16_t sampler[NINE_MAX_SAMPLERS]; /* stateblocks only */
struct nine_range *vs_const_f;
struct nine_range *ps_const_f;
struct nine_range *vs_const_i;
struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */
- DWORD samp[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
- DWORD samp_advertised[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
+ DWORD samp_advertised[NINE_MAX_SAMPLERS][D3DSAMP_COUNT];
struct {
struct {
struct nine_context {
struct {
+ uint16_t sampler[NINE_MAX_SAMPLERS];
uint32_t vtxbuf;
} changed;
struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS];
+ DWORD samp[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
+
uint32_t samplers_shadow;
uint8_t bound_samplers_mask_vs;
DWORD Stage,
struct NineBaseTexture9 *tex);
+void
+nine_context_set_sampler_state(struct NineDevice9 *device,
+ DWORD Sampler,
+ D3DSAMPLERSTATETYPE Type,
+ DWORD Value);
+
void
nine_context_set_stream_source(struct NineDevice9 *device,
UINT StreamNumber,