summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Davy <axel.davy@ens.fr>2015-11-07 17:47:06 +0100
committerAxel Davy <axel.davy@ens.fr>2016-02-04 22:12:17 +0100
commitb5876e47623a20c9a123d33927f97bada7c95f3c (patch)
tree4fb7e026bd16e39ce2576d822417afe4b8c25e0f
parent531acbc56b987a1ea288b95046e4181e34b611e8 (diff)
st/nine: Use ff vertex shader when position_t is used
When an application sets a vertex shader, we are supposed to use it, and when no vertex shader are set, we are supposed to revert to fixed function vertex shader. It seems there is an exception: when the vertex declaration has a position_t index, we should revert to fixed function vertex shader. Up to know we were checking if device->state.vs is set to know whether to use programmable shader or not. With this commit we determine whether we use programmable shader or not when vertex shader/declaration are set, but stateblocks do complicate things a bit. Signed-off-by: Axel Davy <axel.davy@ens.fr> Reviewed-by: Patrick Rudolph <siro@das-labor.org>
-rw-r--r--src/gallium/state_trackers/nine/device9.c17
-rw-r--r--src/gallium/state_trackers/nine/nine_ff.c4
-rw-r--r--src/gallium/state_trackers/nine/nine_state.c16
-rw-r--r--src/gallium/state_trackers/nine/nine_state.h1
-rw-r--r--src/gallium/state_trackers/nine/stateblock9.c6
-rw-r--r--src/gallium/state_trackers/nine/vertexdeclaration9.c3
-rw-r--r--src/gallium/state_trackers/nine/vertexdeclaration9.h2
7 files changed, 35 insertions, 14 deletions
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 29e8aae54f..055433ac85 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -3185,13 +3185,21 @@ NineDevice9_SetVertexDeclaration( struct NineDevice9 *This,
IDirect3DVertexDeclaration9 *pDecl )
{
struct nine_state *state = This->update;
+ BOOL was_programmable_vs = This->state.programmable_vs;
DBG("This=%p pDecl=%p\n", This, pDecl);
if (likely(!This->is_recording) && state->vdecl == NineVertexDeclaration9(pDecl))
return D3D_OK;
+
nine_bind(&state->vdecl, pDecl);
+ This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t);
+ if (likely(!This->is_recording) && was_programmable_vs != This->state.programmable_vs) {
+ state->commit |= NINE_STATE_COMMIT_CONST_VS;
+ state->changed.group |= NINE_STATE_VS;
+ }
+
state->changed.group |= NINE_STATE_VDECL;
return D3D_OK;
@@ -3263,18 +3271,21 @@ NineDevice9_SetVertexShader( struct NineDevice9 *This,
IDirect3DVertexShader9 *pShader )
{
struct nine_state *state = This->update;
+ BOOL was_programmable_vs = This->state.programmable_vs;
DBG("This=%p pShader=%p\n", This, pShader);
if (!This->is_recording && state->vs == (struct NineVertexShader9*)pShader)
return D3D_OK;
+ nine_bind(&state->vs, pShader);
+
+ This->state.programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t);
+
/* ff -> non-ff: commit back non-ff constants */
- if (!state->vs && pShader)
+ if (!was_programmable_vs && This->state.programmable_vs)
state->commit |= NINE_STATE_COMMIT_CONST_VS;
- nine_bind(&state->vs, pShader);
-
state->changed.group |= NINE_STATE_VS;
return D3D_OK;
diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c
index 9098684cb6..120c605658 100644
--- a/src/gallium/state_trackers/nine/nine_ff.c
+++ b/src/gallium/state_trackers/nine/nine_ff.c
@@ -1868,7 +1868,7 @@ nine_ff_update(struct NineDevice9 *device)
DBG("vs=%p ps=%p\n", device->state.vs, device->state.ps);
/* NOTE: the only reference belongs to the hash table */
- if (!device->state.vs) {
+ if (!state->programmable_vs) {
device->ff.vs = nine_ff_get_vs(device);
device->state.changed.group |= NINE_STATE_VS;
}
@@ -1877,7 +1877,7 @@ nine_ff_update(struct NineDevice9 *device)
device->state.changed.group |= NINE_STATE_PS;
}
- if (!device->state.vs) {
+ if (!state->programmable_vs) {
nine_ff_load_vs_transforms(device);
nine_ff_load_tex_matrices(device);
nine_ff_load_lights(device);
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index aee3162208..2e77d62b64 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -367,14 +367,14 @@ prepare_vs(struct NineDevice9 *device, uint8_t shader_changed)
uint32_t changed_group = 0;
int has_key_changed = 0;
- if (likely(vs))
+ if (likely(state->programmable_vs))
has_key_changed = NineVertexShader9_UpdateKey(vs, state);
if (!shader_changed && !has_key_changed)
return 0;
/* likely because we dislike FF */
- if (likely(vs)) {
+ if (likely(state->programmable_vs)) {
state->cso.vs = NineVertexShader9_GetVariant(vs);
} else {
vs = device->ff.vs;
@@ -567,7 +567,7 @@ update_vertex_elements(struct NineDevice9 *device)
state->stream_usage_mask = 0;
memset(vdecl_index_map, -1, 16);
memset(used_streams, 0, device->caps.MaxStreams);
- vs = device->state.vs ? device->state.vs : device->ff.vs;
+ vs = state->programmable_vs ? device->state.vs : device->ff.vs;
if (vdecl) {
for (n = 0; n < vs->num_inputs; ++n) {
@@ -761,7 +761,7 @@ update_textures_and_samplers(struct NineDevice9 *device)
cso_single_sampler_done(device->cso, PIPE_SHADER_FRAGMENT);
commit_samplers = FALSE;
- sampler_mask = state->vs ? state->vs->sampler_mask : 0;
+ sampler_mask = state->programmable_vs ? state->vs->sampler_mask : 0;
state->bound_samplers_mask_vs = 0;
for (num_textures = 0, i = 0; i < NINE_MAX_SAMPLERS_VS; ++i) {
const unsigned s = NINE_SAMPLER_VS(i);
@@ -854,7 +854,7 @@ commit_vs_constants(struct NineDevice9 *device)
{
struct pipe_context *pipe = device->pipe;
- if (unlikely(!device->state.vs))
+ if (unlikely(!device->state.programmable_vs))
pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs_ff);
else
pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &device->state.pipe.cb_vs);
@@ -964,7 +964,7 @@ nine_update_state(struct NineDevice9 *device)
validate_textures(device); /* may clobber state */
/* ff_update may change VS/PS dirty bits */
- if (unlikely(!state->vs || !state->ps))
+ if (unlikely(!state->programmable_vs || !state->ps))
nine_ff_update(device);
group = state->changed.group;
@@ -997,12 +997,12 @@ nine_update_state(struct NineDevice9 *device)
if (group & (NINE_STATE_TEXTURE | NINE_STATE_SAMPLER))
update_textures_and_samplers(device);
if (device->prefer_user_constbuf) {
- if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS)) && state->vs)
+ if ((group & (NINE_STATE_VS_CONST | NINE_STATE_VS)) && state->programmable_vs)
prepare_vs_constants_userbuf(device);
if ((group & (NINE_STATE_PS_CONST | NINE_STATE_PS)) && state->ps)
prepare_ps_constants_userbuf(device);
} else {
- if ((group & NINE_STATE_VS_CONST) && state->vs)
+ if ((group & NINE_STATE_VS_CONST) && state->programmable_vs)
upload_constants(device, PIPE_SHADER_VERTEX);
if ((group & NINE_STATE_PS_CONST) && state->ps)
upload_constants(device, PIPE_SHADER_FRAGMENT);
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index b34da70ef4..88e5665c8c 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -152,6 +152,7 @@ struct nine_state
int vs_const_i[NINE_MAX_CONST_I][4];
BOOL vs_const_b[NINE_MAX_CONST_B];
float *vs_lconstf_temp;
+ BOOL programmable_vs;
struct NinePixelShader9 *ps;
float *ps_const_f;
diff --git a/src/gallium/state_trackers/nine/stateblock9.c b/src/gallium/state_trackers/nine/stateblock9.c
index 77039596fd..a1227f929c 100644
--- a/src/gallium/state_trackers/nine/stateblock9.c
+++ b/src/gallium/state_trackers/nine/stateblock9.c
@@ -24,6 +24,7 @@
#include "device9.h"
#include "basetexture9.h"
#include "nine_helpers.h"
+#include "vertexdeclaration9.h"
#define DBG_CHANNEL DBG_STATEBLOCK
@@ -490,7 +491,10 @@ NineStateBlock9_Apply( struct NineStateBlock9 *This )
nine_state_copy_common(dst, src, src, TRUE, pool);
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
- nine_bind(&dst->vdecl, src->vdecl);
+ NineDevice9_SetVertexDeclaration(This->base.device, (IDirect3DVertexDeclaration9 *)src->vdecl);
+
+ /* Recomputing it is needed if we changed vs but not vdecl */
+ dst->programmable_vs = dst->vs && !(dst->vdecl && dst->vdecl->position_t);
/* Textures */
if (src->changed.texture) {
diff --git a/src/gallium/state_trackers/nine/vertexdeclaration9.c b/src/gallium/state_trackers/nine/vertexdeclaration9.c
index b35e72c322..36c594b5be 100644
--- a/src/gallium/state_trackers/nine/vertexdeclaration9.c
+++ b/src/gallium/state_trackers/nine/vertexdeclaration9.c
@@ -203,6 +203,9 @@ NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
This->decls[i].UsageIndex);
This->usage_map[i] = usage;
+ if (This->decls[i].Usage == D3DDECLUSAGE_POSITIONT)
+ This->position_t = TRUE;
+
This->elems[i].src_offset = This->decls[i].Offset;
This->elems[i].instance_divisor = 0;
This->elems[i].vertex_buffer_index = This->decls[i].Stream;
diff --git a/src/gallium/state_trackers/nine/vertexdeclaration9.h b/src/gallium/state_trackers/nine/vertexdeclaration9.h
index 655bcfbf16..e39f259440 100644
--- a/src/gallium/state_trackers/nine/vertexdeclaration9.h
+++ b/src/gallium/state_trackers/nine/vertexdeclaration9.h
@@ -46,6 +46,8 @@ struct NineVertexDeclaration9
D3DVERTEXELEMENT9 *decls;
DWORD fvf;
+
+ BOOL position_t;
};
static inline struct NineVertexDeclaration9 *
NineVertexDeclaration9( void *data )