r600g: fix binding of same texture to several target slot
authorJerome Glisse <jglisse@redhat.com>
Thu, 2 Sep 2010 01:57:43 +0000 (21:57 -0400)
committerJerome Glisse <jglisse@redhat.com>
Thu, 2 Sep 2010 01:59:28 +0000 (21:59 -0400)
One can bind same texture or sampler to different slot,
each slot needs it own state. The solution implemented
here is not exactly beautifull or optimal need to think
to somethings better.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
src/gallium/drivers/r600/r600_context.h
src/gallium/drivers/r600/r600_state.c

index eb7a64bfbd53e19b437383c58feb4838e2963ec5..d4e3baa69d23684f79b00933f50d5bda36129118 100644 (file)
@@ -95,13 +95,16 @@ enum pipe_state_type {
        pipe_type_count
 };
 
+#define R600_MAX_RSTATE                16
+
 struct r600_context_state {
        union pipe_states               state;
        unsigned                        refcount;
        unsigned                        type;
-       struct radeon_state             rstate[16];
+       struct radeon_state             rstate[R600_MAX_RSTATE];
        struct r600_shader              shader;
        struct radeon_bo                *bo;
+       unsigned                        nrstate;
 };
 
 struct r600_vertex_element
@@ -153,10 +156,10 @@ struct r600_context {
        struct r600_context_state       *stencil_ref;
        struct r600_context_state       *viewport;
        struct r600_context_state       *framebuffer;
-       struct r600_context_state       *ps_sampler[PIPE_MAX_ATTRIBS];
-       struct r600_context_state       *vs_sampler[PIPE_MAX_ATTRIBS];
-       struct r600_context_state       *ps_sampler_view[PIPE_MAX_ATTRIBS];
-       struct r600_context_state       *vs_sampler_view[PIPE_MAX_ATTRIBS];
+       struct radeon_state             *ps_sampler[PIPE_MAX_ATTRIBS];
+       struct radeon_state             *vs_sampler[PIPE_MAX_ATTRIBS];
+       struct radeon_state             *ps_sampler_view[PIPE_MAX_ATTRIBS];
+       struct radeon_state             *vs_sampler_view[PIPE_MAX_ATTRIBS];
        struct r600_vertex_element      *vertex_elements;
        struct pipe_vertex_buffer       vertex_buffer[PIPE_MAX_ATTRIBS];
        struct pipe_index_buffer        index_buffer;
index 888507747b355ce1e619dbc4d439ef780ab21f59..95611d173948d17c9cdd8fd867e26637ebbcbea1 100644 (file)
@@ -235,14 +235,23 @@ static void r600_bind_ps_sampler(struct pipe_context *ctx,
        struct r600_context_state *rstate;
        unsigned i;
 
-       for (i = 0; i < rctx->ps_nsampler; i++) {
-               rctx->ps_sampler[i] = r600_context_state_decref(rctx->ps_sampler[i]);
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)states[i];
+               if (rstate) {
+                       rstate->nrstate = 0;
+               }
        }
        for (i = 0; i < count; i++) {
                rstate = (struct r600_context_state *)states[i];
-               rctx->ps_sampler[i] = r600_context_state_incref(rstate);
                if (rstate) {
-                       radeon_state_convert(&rstate->rstate[0], R600_STATE_SAMPLER, i, R600_SHADER_PS);
+                       if (rstate->nrstate >= R600_MAX_RSTATE)
+                               continue;
+                       if (rstate->nrstate) {
+                               memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
+                       }
+                       radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_SAMPLER, i, R600_SHADER_PS);
+                       rctx->ps_sampler[i] = &rstate->rstate[rstate->nrstate];
+                       rstate->nrstate++;
                }
        }
        rctx->ps_nsampler = count;
@@ -255,14 +264,23 @@ static void r600_bind_vs_sampler(struct pipe_context *ctx,
        struct r600_context_state *rstate;
        unsigned i;
 
-       for (i = 0; i < rctx->vs_nsampler; i++) {
-               rctx->vs_sampler[i] = r600_context_state_decref(rctx->vs_sampler[i]);
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)states[i];
+               if (rstate) {
+                       rstate->nrstate = 0;
+               }
        }
        for (i = 0; i < count; i++) {
                rstate = (struct r600_context_state *)states[i];
-               rctx->vs_sampler[i] = r600_context_state_incref(rstate);
                if (rstate) {
-                       radeon_state_convert(&rstate->rstate[0], R600_STATE_SAMPLER, i, R600_SHADER_VS);
+                       if (rstate->nrstate >= R600_MAX_RSTATE)
+                               continue;
+                       if (rstate->nrstate) {
+                               memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
+                       }
+                       radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_SAMPLER, i, R600_SHADER_VS);
+                       rctx->vs_sampler[i] = &rstate->rstate[rstate->nrstate];
+                       rstate->nrstate++;
                }
        }
        rctx->vs_nsampler = count;
@@ -349,14 +367,23 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx,
        struct r600_context_state *rstate;
        unsigned i;
 
-       for (i = 0; i < rctx->ps_nsampler_view; i++) {
-               rctx->ps_sampler_view[i] = r600_context_state_decref(rctx->ps_sampler_view[i]);
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)views[i];
+               if (rstate) {
+                       rstate->nrstate = 0;
+               }
        }
        for (i = 0; i < count; i++) {
                rstate = (struct r600_context_state *)views[i];
-               rctx->ps_sampler_view[i] = r600_context_state_incref(rstate);
                if (rstate) {
-                       radeon_state_convert(&rstate->rstate[0], R600_STATE_RESOURCE, i, R600_SHADER_PS);
+                       if (rstate->nrstate >= R600_MAX_RSTATE)
+                               continue;
+                       if (rstate->nrstate) {
+                               memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
+                       }
+                       radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_RESOURCE, i, R600_SHADER_PS);
+                       rctx->ps_sampler_view[i] = &rstate->rstate[rstate->nrstate];
+                       rstate->nrstate++;
                }
        }
        rctx->ps_nsampler_view = count;
@@ -370,14 +397,23 @@ static void r600_set_vs_sampler_view(struct pipe_context *ctx,
        struct r600_context_state *rstate;
        unsigned i;
 
-       for (i = 0; i < rctx->vs_nsampler_view; i++) {
-               rctx->vs_sampler_view[i] = r600_context_state_decref(rctx->vs_sampler_view[i]);
+       for (i = 0; i < count; i++) {
+               rstate = (struct r600_context_state *)views[i];
+               if (rstate) {
+                       rstate->nrstate = 0;
+               }
        }
        for (i = 0; i < count; i++) {
                rstate = (struct r600_context_state *)views[i];
-               rctx->vs_sampler_view[i] = r600_context_state_incref(rstate);
                if (rstate) {
-                       radeon_state_convert(&rstate->rstate[0], R600_STATE_RESOURCE, i, R600_SHADER_VS);
+                       if (rstate->nrstate >= R600_MAX_RSTATE)
+                               continue;
+                       if (rstate->nrstate) {
+                               memcpy(&rstate->rstate[rstate->nrstate], &rstate->rstate[0], sizeof(struct radeon_state));
+                       }
+                       radeon_state_convert(&rstate->rstate[rstate->nrstate], R600_STATE_RESOURCE, i, R600_SHADER_VS);
+                       rctx->vs_sampler_view[i] = &rstate->rstate[rstate->nrstate];
+                       rstate->nrstate++;
                }
        }
        rctx->vs_nsampler_view = count;
@@ -1354,12 +1390,12 @@ int r600_context_hw_states(struct pipe_context *ctx)
        }
        for (i = 0; i < rctx->ps_nsampler; i++) {
                if (rctx->ps_sampler[i]) {
-                       radeon_draw_bind(&rctx->draw, &rctx->ps_sampler[i]->rstate[0]);
+                       radeon_draw_bind(&rctx->draw, rctx->ps_sampler[i]);
                }
        }
        for (i = 0; i < rctx->ps_nsampler_view; i++) {
                if (rctx->ps_sampler_view[i]) {
-                       radeon_draw_bind(&rctx->draw, &rctx->ps_sampler_view[i]->rstate[0]);
+                       radeon_draw_bind(&rctx->draw, rctx->ps_sampler_view[i]);
                }
        }
        return 0;