summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2015-05-16 16:46:51 +0200
committerAxel Davy <[email protected]>2016-12-20 23:44:20 +0100
commit494ace4b851fc3201bdb0297e53ccf8dfde78510 (patch)
tree893c3aeb9978636ded44b7d6e01459f6a7eff8c6 /src/gallium/state_trackers
parentf4d5bc2555a419bd5304b64fedc91fad79cd8d2b (diff)
st/nine: Add validation to SetSamplerState
Check value validity and mimick Win behaviour. Signed-off-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/nine/device9.c9
-rw-r--r--src/gallium/state_trackers/nine/nine_limits.h36
-rw-r--r--src/gallium/state_trackers/nine/nine_state.c2
-rw-r--r--src/gallium/state_trackers/nine/nine_state.h1
-rw-r--r--src/gallium/state_trackers/nine/stateblock9.c3
5 files changed, 48 insertions, 3 deletions
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index c0a3c3937fb..055e71dcfca 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -2766,7 +2766,7 @@ NineDevice9_GetSamplerState( struct NineDevice9 *This,
if (Sampler >= D3DDMAPSAMPLER)
Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS;
- *pValue = This->state.samp[Sampler][Type];
+ *pValue = This->state.samp_advertised[Sampler][Type];
return D3D_OK;
}
@@ -2789,8 +2789,11 @@ NineDevice9_SetSamplerState( struct NineDevice9 *This,
if (Sampler >= D3DDMAPSAMPLER)
Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS;
- if (state->samp[Sampler][Type] != Value || unlikely(This->is_recording)) {
- state->samp[Sampler][Type] = Value;
+ 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;
+ state->samp_advertised[Sampler][Type] = Value;
state->changed.group |= NINE_STATE_SAMPLER;
state->changed.sampler[Sampler] |= 1 << Type;
}
diff --git a/src/gallium/state_trackers/nine/nine_limits.h b/src/gallium/state_trackers/nine/nine_limits.h
index ef1ed2566ba..b5090daa11d 100644
--- a/src/gallium/state_trackers/nine/nine_limits.h
+++ b/src/gallium/state_trackers/nine/nine_limits.h
@@ -208,4 +208,40 @@ nine_fix_render_state_value(D3DRENDERSTATETYPE State,
return Value;
}
+struct nine_limits
+{
+ unsigned min;
+ unsigned max;
+};
+
+#define __VALUE_SAMP(o, m, M) \
+ [D3DSAMP_##o] = {m, M}
+
+static const struct nine_limits
+sampler_state_limits_table[D3DRS_BLENDOPALPHA + 1] = {
+ __VALUE_SAMP(ADDRESSU, 1, 5),
+ __VALUE_SAMP(ADDRESSV, 1, 5),
+ __VALUE_SAMP(ADDRESSW, 1, 5),
+ __VALUE_SAMP(BORDERCOLOR, 0, 0xFFFFFFFF),
+ __VALUE_SAMP(MAGFILTER, 0, 8), /* 4-5 should be forbidden */
+ __VALUE_SAMP(MINFILTER, 0, 8), /* same */
+ __VALUE_SAMP(MIPFILTER, 0, 8), /* same */
+ __VALUE_SAMP(MIPMAPLODBIAS, 0, 0xFFFFFFFF),
+ __VALUE_SAMP(MAXMIPLEVEL, 0, 0xFFFFFFFF),
+ __VALUE_SAMP(MAXANISOTROPY, 1, 0xFFFFFFFF), /* Max value should be pCaps->MaxAnisotropy */
+ __VALUE_SAMP(SRGBTEXTURE, 0, 1),
+ __VALUE_SAMP(ELEMENTINDEX, 0, 0xFFFFFFFF),
+ __VALUE_SAMP(DMAPOFFSET, 0, 0xFFFFFFFF)
+};
+
+static BOOL inline
+nine_check_sampler_state_value(D3DSAMPLERSTATETYPE State,
+ DWORD Value)
+{
+ struct nine_limits limit;
+
+ limit = sampler_state_limits_table[State];
+ return (limit.min <= Value && Value <= limit.max);
+}
+
#endif /* _NINE_HELPERS_H_ */
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index ea72c778d17..57f7b2d1362 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -1306,6 +1306,8 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
for (s = 0; s < ARRAY_SIZE(state->samp); ++s) {
memcpy(&state->samp[s], nine_samp_state_defaults,
sizeof(state->samp[s]));
+ memcpy(&state->samp_advertised[s], nine_samp_state_defaults,
+ sizeof(state->samp_advertised[s]));
}
if (state->vs_const_f)
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index 1c50775670d..714f1a9a0eb 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -199,6 +199,7 @@ struct nine_state
struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */
DWORD samp[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
+ DWORD samp_advertised[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
uint32_t samplers_shadow;
uint8_t bound_samplers_mask_vs;
uint16_t bound_samplers_mask_ps;
diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c
index 102213e417e..75754dfe12a 100644
--- a/src/gallium/state_trackers/nine/stateblock9.c
+++ b/src/gallium/state_trackers/nine/stateblock9.c
@@ -245,12 +245,14 @@ nine_state_copy_common(struct NineDevice9 *device,
for (s = 0; s < NINE_MAX_SAMPLERS; ++s) {
if (mask->changed.sampler[s] == 0x3ffe) {
memcpy(&dst->samp[s], &src->samp[s], sizeof(dst->samp[s]));
+ memcpy(&dst->samp_advertised[s], &src->samp_advertised[s], sizeof(dst->samp_advertised[s]));
} else {
uint32_t m = mask->changed.sampler[s];
while (m) {
const int i = ffs(m) - 1;
m &= ~(1 << i);
dst->samp[s][i] = src->samp[s][i];
+ dst->samp_advertised[s][i] = src->samp_advertised[s][i];
}
}
if (apply)
@@ -446,6 +448,7 @@ nine_state_copy_common_all(struct NineDevice9 *device,
/* Sampler state. */
memcpy(dst->samp, src->samp, sizeof(dst->samp));
+ memcpy(dst->samp_advertised, src->samp_advertised, sizeof(dst->samp_advertised));
if (apply)
memcpy(dst->changed.sampler,
src->changed.sampler, sizeof(dst->changed.sampler));