st/nine: Add validation to SetSamplerState
authorAxel Davy <axel.davy@ens.fr>
Sat, 16 May 2015 14:46:51 +0000 (16:46 +0200)
committerAxel Davy <axel.davy@ens.fr>
Tue, 20 Dec 2016 22:44:20 +0000 (23:44 +0100)
Check value validity and mimick Win behaviour.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/device9.c
src/gallium/state_trackers/nine/nine_limits.h
src/gallium/state_trackers/nine/nine_state.c
src/gallium/state_trackers/nine/nine_state.h
src/gallium/state_trackers/nine/stateblock9.c

index c0a3c3937fba1f22aa6ec3399ad8fdc8b1dc9114..055e71dcfcabfc288da005f58badb2609255462c 100644 (file)
@@ -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;
     }
index ef1ed2566ba9e2e9597e59e69e6abc5faf3f2d55..b5090daa11d82181a54781c87d78bf09873f47b4 100644 (file)
@@ -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_ */
index ea72c778d171e49a533cd3674aba35127cfafd45..57f7b2d13625d14bc724065854fe43be25100d4b 100644 (file)
@@ -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)
index 1c50775670d9936e570d8cfae9b2b8ca55c86299..714f1a9a0eb192464c0060695bc55cc865c160ba 100644 (file)
@@ -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;
index 102213e417e86d982bb83c22956aebaeda13138a..75754dfe12ab1ca51a43102e66831dad7cb895e7 100644 (file)
@@ -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));