From 494ace4b851fc3201bdb0297e53ccf8dfde78510 Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Sat, 16 May 2015 16:46:51 +0200 Subject: [PATCH] st/nine: Add validation to SetSamplerState Check value validity and mimick Win behaviour. Signed-off-by: Axel Davy --- src/gallium/state_trackers/nine/device9.c | 9 +++-- src/gallium/state_trackers/nine/nine_limits.h | 36 +++++++++++++++++++ src/gallium/state_trackers/nine/nine_state.c | 2 ++ src/gallium/state_trackers/nine/nine_state.h | 1 + src/gallium/state_trackers/nine/stateblock9.c | 3 ++ 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)); -- 2.30.2