summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine/stateblock9.c
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2016-09-17 14:16:41 +0200
committerAxel Davy <[email protected]>2016-10-10 23:43:49 +0200
commit3bf02d383fe94a69dfec3ff54ede3e3b2e9dff6b (patch)
treefc45cd758c5ceffcbe95f053430a1a778ecf9c8f /src/gallium/state_trackers/nine/stateblock9.c
parentf8c8f4424405c4789a044470e64df810720358c8 (diff)
st/nine: Partial software vertex processing support
Software Vertex Processing allows: . Less limitations for shaders (more loops, etc) . Less limitations for ff (more enabled lights, 255 matrices for VertexBlend) In particular shaders can get more constants. This patch implements support for this (not using software rendering, but hardware rendering, as llvmpipe and dx10+ hw have the same limits...) This is considered a second class path. Even apps asking for "Mixed Vertex processing" (ie the ability to switch to swvp on demand) do not use the feature much. Some just initialize more constants than the normal limit at the start of the application, but never use more than the normal limit. When the apps do not need the software vertex processing features, they do not seem to turn it on. This means it is ok if that path is slow. Thus no care has been made to make the path optimized. Signed-off-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/nine/stateblock9.c')
-rw-r--r--src/gallium/state_trackers/nine/stateblock9.c85
1 files changed, 60 insertions, 25 deletions
diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c
index 19c3766b3c6..102213e417e 100644
--- a/src/gallium/state_trackers/nine/stateblock9.c
+++ b/src/gallium/state_trackers/nine/stateblock9.c
@@ -30,8 +30,9 @@
/* XXX TODO: handling of lights is broken */
-#define VS_CONST_I_SIZE (NINE_MAX_CONST_I * sizeof(int[4]))
-#define VS_CONST_B_SIZE (NINE_MAX_CONST_B * sizeof(BOOL))
+#define VS_CONST_I_SIZE(device) (device->may_swvp ? (NINE_MAX_CONST_I_SWVP * sizeof(int[4])) : (NINE_MAX_CONST_I * sizeof(int[4])))
+#define VS_CONST_B_SIZE(device) (device->may_swvp ? (NINE_MAX_CONST_B_SWVP * sizeof(BOOL)) : (NINE_MAX_CONST_B * sizeof(BOOL)))
+#define VS_CONST_F_SWVP_SIZE (NINE_MAX_CONST_F_SWVP * sizeof(float[4]))
HRESULT
NineStateBlock9_ctor( struct NineStateBlock9 *This,
@@ -49,12 +50,19 @@ NineStateBlock9_ctor( struct NineStateBlock9 *This,
This->state.vs_const_f = MALLOC(This->base.device->vs_const_size);
This->state.ps_const_f = MALLOC(This->base.device->ps_const_size);
- This->state.vs_const_i = MALLOC(VS_CONST_I_SIZE);
- This->state.vs_const_b = MALLOC(VS_CONST_B_SIZE);
+ This->state.vs_const_i = MALLOC(VS_CONST_I_SIZE(This->base.device));
+ This->state.vs_const_b = MALLOC(VS_CONST_B_SIZE(This->base.device));
if (!This->state.vs_const_f || !This->state.ps_const_f ||
!This->state.vs_const_i || !This->state.vs_const_b)
return E_OUTOFMEMORY;
+ if (This->base.device->may_swvp) {
+ This->state.vs_const_f_swvp = MALLOC(VS_CONST_F_SWVP_SIZE);
+ if (!This->state.vs_const_f_swvp)
+ return E_OUTOFMEMORY;
+ } else
+ This->state.vs_const_f_swvp = NULL;
+
return D3D_OK;
}
@@ -71,6 +79,7 @@ NineStateBlock9_dtor( struct NineStateBlock9 *This )
FREE(state->ps_const_f);
FREE(state->vs_const_i);
FREE(state->vs_const_b);
+ FREE(state->vs_const_f_swvp);
FREE(state->ff.light);
@@ -101,7 +110,8 @@ NineStateBlock9_dtor( struct NineStateBlock9 *This )
* TODO: compare ?
*/
static void
-nine_state_copy_common(struct nine_state *dst,
+nine_state_copy_common(struct NineDevice9 *device,
+ struct nine_state *dst,
struct nine_state *src,
struct nine_state *mask, /* aliases either src or dst */
const boolean apply,
@@ -130,13 +140,32 @@ nine_state_copy_common(struct nine_state *dst,
*/
if (mask->changed.group & NINE_STATE_VS_CONST) {
struct nine_range *r;
- for (r = mask->changed.vs_const_f; r; r = r->next) {
- memcpy(&dst->vs_const_f[r->bgn * 4],
- &src->vs_const_f[r->bgn * 4],
- (r->end - r->bgn) * 4 * sizeof(float));
- if (apply)
- nine_ranges_insert(&dst->changed.vs_const_f, r->bgn, r->end,
- pool);
+ if (device->may_swvp) {
+ for (r = mask->changed.vs_const_f; r; r = r->next) {
+ int bgn = r->bgn;
+ int end = r->end;
+ memcpy(&dst->vs_const_f_swvp[bgn * 4],
+ &src->vs_const_f_swvp[bgn * 4],
+ (end - bgn) * 4 * sizeof(float));
+ if (apply)
+ nine_ranges_insert(&dst->changed.vs_const_f, bgn, end,
+ pool);
+ if (bgn < device->max_vs_const_f) {
+ end = MIN2(end, device->max_vs_const_f);
+ memcpy(&dst->vs_const_f[bgn * 4],
+ &src->vs_const_f[bgn * 4],
+ (end - bgn) * 4 * sizeof(float));
+ }
+ }
+ } else {
+ for (r = mask->changed.vs_const_f; r; r = r->next) {
+ memcpy(&dst->vs_const_f[r->bgn * 4],
+ &src->vs_const_f[r->bgn * 4],
+ (r->end - r->bgn) * 4 * sizeof(float));
+ if (apply)
+ nine_ranges_insert(&dst->changed.vs_const_f, r->bgn, r->end,
+ pool);
+ }
}
for (r = mask->changed.vs_const_i; r; r = r->next) {
memcpy(&dst->vs_const_i[r->bgn * 4],
@@ -342,7 +371,8 @@ nine_state_copy_common(struct nine_state *dst,
}
static void
-nine_state_copy_common_all(struct nine_state *dst,
+nine_state_copy_common_all(struct NineDevice9 *device,
+ struct nine_state *dst,
const struct nine_state *src,
struct nine_state *help,
const boolean apply,
@@ -369,12 +399,15 @@ nine_state_copy_common_all(struct nine_state *dst,
if (1) {
struct nine_range *r = help->changed.vs_const_f;
memcpy(&dst->vs_const_f[0],
- &src->vs_const_f[0], (r->end - r->bgn) * 4 * sizeof(float));
+ &src->vs_const_f[0], device->max_vs_const_f * 4 * sizeof(float));
+ if (device->may_swvp)
+ memcpy(dst->vs_const_f_swvp,
+ src->vs_const_f_swvp, VS_CONST_F_SWVP_SIZE);
if (apply)
nine_ranges_insert(&dst->changed.vs_const_f, r->bgn, r->end, pool);
- memcpy(dst->vs_const_i, src->vs_const_i, VS_CONST_I_SIZE);
- memcpy(dst->vs_const_b, src->vs_const_b, VS_CONST_B_SIZE);
+ memcpy(dst->vs_const_i, src->vs_const_i, VS_CONST_I_SIZE(device));
+ memcpy(dst->vs_const_b, src->vs_const_b, VS_CONST_B_SIZE(device));
if (apply) {
r = help->changed.vs_const_i;
nine_ranges_insert(&dst->changed.vs_const_i, r->bgn, r->end, pool);
@@ -491,17 +524,18 @@ nine_state_copy_common_all(struct nine_state *dst,
HRESULT NINE_WINAPI
NineStateBlock9_Capture( struct NineStateBlock9 *This )
{
+ struct NineDevice9 *device = This->base.device;
struct nine_state *dst = &This->state;
- struct nine_state *src = &This->base.device->state;
- const int MaxStreams = This->base.device->caps.MaxStreams;
+ struct nine_state *src = &device->state;
+ const int MaxStreams = device->caps.MaxStreams;
unsigned s;
DBG("This=%p\n", This);
if (This->type == NINESBT_ALL)
- nine_state_copy_common_all(dst, src, dst, FALSE, NULL, MaxStreams);
+ nine_state_copy_common_all(device, dst, src, dst, FALSE, NULL, MaxStreams);
else
- nine_state_copy_common(dst, src, dst, FALSE, NULL);
+ nine_state_copy_common(device, dst, src, dst, FALSE, NULL);
if (dst->changed.group & NINE_STATE_VDECL)
nine_bind(&dst->vdecl, src->vdecl);
@@ -521,18 +555,19 @@ NineStateBlock9_Capture( struct NineStateBlock9 *This )
HRESULT NINE_WINAPI
NineStateBlock9_Apply( struct NineStateBlock9 *This )
{
- struct nine_state *dst = &This->base.device->state;
+ struct NineDevice9 *device = This->base.device;
+ struct nine_state *dst = &device->state;
struct nine_state *src = &This->state;
- struct nine_range_pool *pool = &This->base.device->range_pool;
- const int MaxStreams = This->base.device->caps.MaxStreams;
+ struct nine_range_pool *pool = &device->range_pool;
+ const int MaxStreams = device->caps.MaxStreams;
unsigned s;
DBG("This=%p\n", This);
if (This->type == NINESBT_ALL)
- nine_state_copy_common_all(dst, src, src, TRUE, pool, MaxStreams);
+ nine_state_copy_common_all(device, dst, src, src, TRUE, pool, MaxStreams);
else
- nine_state_copy_common(dst, src, src, TRUE, pool);
+ nine_state_copy_common(device, dst, src, src, TRUE, pool);
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
NineDevice9_SetVertexDeclaration(This->base.device, (IDirect3DVertexDeclaration9 *)src->vdecl);