diff options
author | Axel Davy <[email protected]> | 2016-02-06 19:29:10 +0100 |
---|---|---|
committer | Axel Davy <[email protected]> | 2016-02-12 23:26:36 +0100 |
commit | 17078d92ea524c9f0e9dff8d17f8b2df752d24cc (patch) | |
tree | d8c3e9b47ba9eee0445942ea72b84a94ddd12545 /src/gallium/state_trackers/nine/stateblock9.c | |
parent | 6cba347530433c61b218d2b897fb57f33835b37b (diff) |
st/nine: Fix stateblocks crashes with lights
We had several issues of crashes with it.
This should fix it.
Signed-off-by: Axel Davy <[email protected]>
Reviewed-by: Patrick Rudolph <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/nine/stateblock9.c')
-rw-r--r-- | src/gallium/state_trackers/nine/stateblock9.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c index 0d1a04b657a..47893465f08 100644 --- a/src/gallium/state_trackers/nine/stateblock9.c +++ b/src/gallium/state_trackers/nine/stateblock9.c @@ -86,7 +86,7 @@ NineStateBlock9_dtor( struct NineStateBlock9 *This ) */ static void nine_state_copy_common(struct nine_state *dst, - const struct nine_state *src, + struct nine_state *src, struct nine_state *mask, /* aliases either src or dst */ const boolean apply, struct nine_range_pool *pool) @@ -267,17 +267,41 @@ nine_state_copy_common(struct nine_state *dst, } } if (mask->changed.group & NINE_STATE_FF_LIGHTING) { - if (dst->ff.num_lights < mask->ff.num_lights) { + unsigned num_lights = MAX2(dst->ff.num_lights, src->ff.num_lights); + /* Can happen in Capture() if device state has created new lights after + * the stateblock was created. + * Can happen in Apply() if the stateblock had recorded the creation of + * new lights. */ + if (dst->ff.num_lights < num_lights) { dst->ff.light = REALLOC(dst->ff.light, dst->ff.num_lights * sizeof(D3DLIGHT9), - mask->ff.num_lights * sizeof(D3DLIGHT9)); - for (i = dst->ff.num_lights; i < mask->ff.num_lights; ++i) { - memset(&dst->ff.light[i], 0, sizeof(D3DLIGHT9)); - dst->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID; + num_lights * sizeof(D3DLIGHT9)); + memset(&dst->ff.light[dst->ff.num_lights], 0, (num_lights - dst->ff.num_lights) * sizeof(D3DLIGHT9)); + /* if mask == dst, a Type of 0 will trigger + * "dst->ff.light[i] = src->ff.light[i];" later, + * which is what we want in that case. */ + if (mask != dst) { + for (i = src->ff.num_lights; i < num_lights; ++i) + src->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID; } - dst->ff.num_lights = mask->ff.num_lights; + dst->ff.num_lights = num_lights; } - for (i = 0; i < mask->ff.num_lights; ++i) + /* Can happen in Capture() if the stateblock had recorded the creation of + * new lights. + * Can happen in Apply() if device state has created new lights after + * the stateblock was created. */ + if (src->ff.num_lights < num_lights) { + src->ff.light = REALLOC(src->ff.light, + src->ff.num_lights * sizeof(D3DLIGHT9), + num_lights * sizeof(D3DLIGHT9)); + memset(&src->ff.light[src->ff.num_lights], 0, (num_lights - src->ff.num_lights) * sizeof(D3DLIGHT9)); + for (i = src->ff.num_lights; i < num_lights; ++i) + src->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID; + src->ff.num_lights = num_lights; + } + /* Note: mask is either src or dst, so at this point src, dst and mask + * have num_lights lights. */ + for (i = 0; i < num_lights; ++i) if (mask->ff.light[i].Type != NINED3DLIGHT_INVALID) dst->ff.light[i] = src->ff.light[i]; |