From 2594b2efdc3f250f0e8b6bc5412d509eb693541e Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Sun, 23 Sep 2018 16:22:01 +0200 Subject: [PATCH] st/nine: Capture also default matrices for D3DSBT_ALL We avoid allocating space for never unused matrices. However we must do as if we had captured them. Thus when a D3DSBT_ALL stateblock apply has fewer matrices than device state, allocate the default matrices for the stateblock before applying. Signed-off-by: Axel Davy --- src/gallium/state_trackers/nine/nine_state.c | 37 ++++++++++++------- src/gallium/state_trackers/nine/nine_state.h | 3 ++ src/gallium/state_trackers/nine/stateblock9.c | 25 ++++++++----- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c index f4d9b423510..569a1b47292 100644 --- a/src/gallium/state_trackers/nine/nine_state.c +++ b/src/gallium/state_trackers/nine/nine_state.c @@ -3398,14 +3398,31 @@ const uint32_t nine_render_state_group[NINED3DRS_LAST + 1] = /* Misc */ +static D3DMATRIX nine_state_identity = { .m[0] = { 1, 0, 0, 0 }, + .m[1] = { 0, 1, 0, 0 }, + .m[2] = { 0, 0, 1, 0 }, + .m[3] = { 0, 0, 0, 1 } }; + +void +nine_state_resize_transform(struct nine_ff_state *ff_state, unsigned N) +{ + unsigned n = ff_state->num_transforms; + + if (N <= n) + return; + + ff_state->transform = REALLOC(ff_state->transform, + n * sizeof(D3DMATRIX), + N * sizeof(D3DMATRIX)); + for (; n < N; ++n) + ff_state->transform[n] = nine_state_identity; + ff_state->num_transforms = N; +} + D3DMATRIX * nine_state_access_transform(struct nine_ff_state *ff_state, D3DTRANSFORMSTATETYPE t, boolean alloc) { - static D3DMATRIX Identity = { .m[0] = { 1, 0, 0, 0 }, - .m[1] = { 0, 1, 0, 0 }, - .m[2] = { 0, 0, 1, 0 }, - .m[3] = { 0, 0, 0, 1 } }; unsigned index; switch (t) { @@ -3427,17 +3444,9 @@ nine_state_access_transform(struct nine_ff_state *ff_state, D3DTRANSFORMSTATETYP } if (index >= ff_state->num_transforms) { - unsigned N = index + 1; - unsigned n = ff_state->num_transforms; - if (!alloc) - return &Identity; - ff_state->transform = REALLOC(ff_state->transform, - n * sizeof(D3DMATRIX), - N * sizeof(D3DMATRIX)); - for (; n < N; ++n) - ff_state->transform[n] = Identity; - ff_state->num_transforms = N; + return &nine_state_identity; + nine_state_resize_transform(ff_state, index + 1); } return &ff_state->transform[index]; } diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h index 7c4517b3fef..55ccfd0f519 100644 --- a/src/gallium/state_trackers/nine/nine_state.h +++ b/src/gallium/state_trackers/nine/nine_state.h @@ -609,6 +609,9 @@ void nine_state_prepare_draw_sw(struct NineDevice9 *device, void nine_state_after_draw_sw(struct NineDevice9 *device); void nine_state_destroy_sw(struct NineDevice9 *device); +void +nine_state_resize_transform(struct nine_ff_state *ff_state, unsigned N); + /* If @alloc is FALSE, the return value may be a const identity matrix. * Therefore, do not modify if you set alloc to FALSE ! */ diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c index ebfd622ff91..7b2deae7f9b 100644 --- a/src/gallium/state_trackers/nine/stateblock9.c +++ b/src/gallium/state_trackers/nine/stateblock9.c @@ -357,8 +357,7 @@ nine_state_copy_common(struct NineDevice9 *device, if (!(mask->ff.changed.transform[i] & (1 << (s % 32)))) continue; *nine_state_access_transform(&dst->ff, s, TRUE) = - *nine_state_access_transform( /* const because !alloc */ - (struct nine_ff_state *)&src->ff, s, FALSE); + *nine_state_access_transform(&src->ff, s, FALSE); } if (apply) dst->ff.changed.transform[i] |= mask->ff.changed.transform[i]; @@ -369,7 +368,7 @@ nine_state_copy_common(struct NineDevice9 *device, static void nine_state_copy_common_all(struct NineDevice9 *device, struct nine_state *dst, - const struct nine_state *src, + struct nine_state *src, struct nine_state *help, const boolean apply, struct nine_range_pool *pool, @@ -488,15 +487,21 @@ nine_state_copy_common_all(struct NineDevice9 *device, /* Transforms. */ if (1) { - if (dst->ff.num_transforms < src->ff.num_transforms) { - dst->ff.transform = REALLOC(dst->ff.transform, - dst->ff.num_transforms * sizeof(dst->ff.transform[0]), - src->ff.num_transforms * sizeof(src->ff.transform[0])); - dst->ff.num_transforms = src->ff.num_transforms; + /* Increase dst size if required (to copy the new states). + * Increase src size if required (to initialize missing transforms). + */ + if (dst->ff.num_transforms != src->ff.num_transforms) { + int num_transforms = MAX2(src->ff.num_transforms, dst->ff.num_transforms); + nine_state_resize_transform(&src->ff, num_transforms); + nine_state_resize_transform(&dst->ff, num_transforms); } memcpy(dst->ff.transform, - src->ff.transform, src->ff.num_transforms * sizeof(D3DMATRIX)); - if (apply) /* TODO: memset */ + src->ff.transform, dst->ff.num_transforms * sizeof(D3DMATRIX)); + /* Apply is always used on device state. + * src is then the D3DSBT_ALL stateblock which + * ff.changed.transform indicates all matrices are dirty. + */ + if (apply) memcpy(dst->ff.changed.transform, src->ff.changed.transform, sizeof(dst->ff.changed.transform)); } -- 2.30.2