Esempio n. 1
0
void
setupFrame(void)
{
   static Matrix world;
   static Matrix view;
   SVGA3dTextureState *ts;
   SVGA3dRenderState *rs;

   Matrix_Copy(view, gIdentityMatrix);
   Matrix_Translate(view, 0, 0, 3);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_VIEW, view);

   Matrix_Copy(world, gIdentityMatrix);
   Matrix_RotateX(world, -60.0 * PI_OVER_180);
   Matrix_RotateY(world, gFPS.frame * 0.01f);

   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_WORLD, world);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_PROJECTION, perspectiveMat);

   SVGA3D_BeginSetRenderState(CID, &rs, 4);
   {
      rs[0].state     = SVGA3D_RS_BLENDENABLE;
      rs[0].uintValue = FALSE;

      rs[1].state     = SVGA3D_RS_ZENABLE;
      rs[1].uintValue = TRUE;

      rs[2].state     = SVGA3D_RS_ZWRITEENABLE;
      rs[2].uintValue = TRUE;

      rs[3].state     = SVGA3D_RS_ZFUNC;
      rs[3].uintValue = SVGA3D_CMP_LESS;
   }
   SVGA_FIFOCommitAll();

   SVGA3D_BeginSetTextureState(CID, &ts, 4);
   {
      ts[0].stage = 0;
      ts[0].name  = SVGA3D_TS_BIND_TEXTURE;
      ts[0].value = SVGA3D_INVALID_ID;

      ts[1].stage = 0;
      ts[1].name  = SVGA3D_TS_COLOROP;
      ts[1].value = SVGA3D_TC_SELECTARG1;

      ts[2].stage = 0;
      ts[2].name  = SVGA3D_TS_COLORARG1;
      ts[2].value = SVGA3D_TA_DIFFUSE;

      ts[3].stage = 0;
      ts[3].name  = SVGA3D_TS_ALPHAARG1;
      ts[3].value = SVGA3D_TA_DIFFUSE;
   }
   SVGA_FIFOCommitAll();
}
Esempio n. 2
0
/*
 * Rebind textures.
 *
 * Similar to update_tss_binding, but without any state checking/update.
 *
 * Called at the beginning of every new command buffer to ensure that
 * non-dirty textures are properly paged-in.
 */
enum pipe_error
svga_reemit_tss_bindings(struct svga_context *svga)
{
   unsigned i;
   enum pipe_error ret;
   struct bind_queue queue;

   assert(svga->rebind.texture_samplers);

   queue.bind_count = 0;

   for (i = 0; i < svga->state.hw_draw.num_views; i++) {
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];

      if (view->v) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      }
   }

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      ret = SVGA3D_BeginSetTextureState(svga->swc,
                                        &ts,
                                        queue.bind_count);
      if (ret != PIPE_OK) {
         return ret;
      }

      for (i = 0; i < queue.bind_count; i++) {
         struct svga_winsys_surface *handle;

         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         assert(queue.bind[i].view->v);
         handle = queue.bind[i].view->v->handle;
         svga->swc->surface_relocation(svga->swc,
                                       &ts[i].value,
                                       handle,
                                       SVGA_RELOC_READ);
      }

      SVGA_FIFOCommitAll(svga->swc);
   }

   svga->rebind.texture_samplers = FALSE;

   return PIPE_OK;
}
Esempio n. 3
0
void
renderCube(float x,
           float y,
           Bool useShaders,
           Bool useHalf)
{
   SVGA3dTextureState *ts;
   SVGA3dRenderState *rs;
   SVGA3dVertexDecl *decls;
   SVGA3dPrimitiveRange *ranges;
   static Matrix view;

   Matrix_Copy(view, gIdentityMatrix);
   Matrix_RotateX(view, 30.0 * M_PI / 180.0);
   Matrix_RotateY(view, gFPS.frame * 0.01f);
   Matrix_Translate(view, x, y, 15);

   if (useShaders) {
      SVGA3D_SetShader(CID, SVGA3D_SHADERTYPE_VS, MY_VSHADER_ID);
      SVGA3D_SetShader(CID, SVGA3D_SHADERTYPE_PS, MY_PSHADER_ID);

      SVGA3DUtil_SetShaderConstMatrix(CID, CONST_MAT_PROJ,
                                      SVGA3D_SHADERTYPE_VS, perspectiveMat);
      SVGA3DUtil_SetShaderConstMatrix(CID, CONST_MAT_VIEW,
                                      SVGA3D_SHADERTYPE_VS, view);
   } else {
      SVGA3D_SetShader(CID, SVGA3D_SHADERTYPE_VS, SVGA3D_INVALID_ID);
      SVGA3D_SetShader(CID, SVGA3D_SHADERTYPE_PS, SVGA3D_INVALID_ID);

      SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_VIEW, view);
      SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_WORLD, gIdentityMatrix);
      SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_PROJECTION, perspectiveMat);
   }

   SVGA3D_BeginSetRenderState(CID, &rs, 4);
   {
      rs[0].state     = SVGA3D_RS_BLENDENABLE;
      rs[0].uintValue = FALSE;

      rs[1].state     = SVGA3D_RS_ZENABLE;
      rs[1].uintValue = TRUE;

      rs[2].state     = SVGA3D_RS_ZWRITEENABLE;
      rs[2].uintValue = TRUE;

      rs[3].state     = SVGA3D_RS_ZFUNC;
      rs[3].uintValue = SVGA3D_CMP_LESS;
   }
   SVGA_FIFOCommitAll();

   SVGA3D_BeginSetTextureState(CID, &ts, 4);
   {
      ts[0].stage = 0;
      ts[0].name  = SVGA3D_TS_BIND_TEXTURE;
      ts[0].value = SVGA3D_INVALID_ID;

      ts[1].stage = 0;
      ts[1].name  = SVGA3D_TS_COLOROP;
      ts[1].value = SVGA3D_TC_SELECTARG1;

      ts[2].stage = 0;
      ts[2].name  = SVGA3D_TS_COLORARG1;
      ts[2].value = SVGA3D_TA_DIFFUSE;

      ts[3].stage = 0;
      ts[3].name  = SVGA3D_TS_ALPHAARG1;
      ts[3].value = SVGA3D_TA_DIFFUSE;
   }
   SVGA_FIFOCommitAll();

   SVGA3D_BeginDrawPrimitives(CID, &decls, 2, &ranges, 1);
   {
      decls[0].identity.usage = SVGA3D_DECLUSAGE_POSITION;
      decls[0].array.surfaceId = vertexSid;
      decls[0].array.stride = sizeof(MyVertex);
      if (useHalf) {
         decls[0].identity.type = SVGA3D_DECLTYPE_FLOAT16_4;
         decls[0].array.offset = offsetof(MyVertex, position16);
      } else {
         decls[0].identity.type = SVGA3D_DECLTYPE_FLOAT3;
         decls[0].array.offset = offsetof(MyVertex, position32);
      }

      decls[1].identity.type = SVGA3D_DECLTYPE_D3DCOLOR;
      decls[1].identity.usage = SVGA3D_DECLUSAGE_COLOR;
      decls[1].array.surfaceId = vertexSid;
      decls[1].array.stride = sizeof(MyVertex);
      decls[1].array.offset = offsetof(MyVertex, color);

      ranges[0].primType = SVGA3D_PRIMITIVE_TRIANGLELIST;
      ranges[0].primitiveCount = numTriangles;
      ranges[0].indexArray.surfaceId = indexSid;
      ranges[0].indexArray.stride = sizeof(uint16);
      ranges[0].indexWidth = sizeof(uint16);
   }
   SVGA_FIFOCommitAll();

   SVGA3D_SetShader(CID, SVGA3D_SHADERTYPE_VS, SVGA3D_INVALID_ID);
   SVGA3D_SetShader(CID, SVGA3D_SHADERTYPE_PS, SVGA3D_INVALID_ID);
}
Esempio n. 4
0
void
render(void)
{
   SVGA3dTextureState *ts;
   SVGA3dRenderState *rs;
   SVGA3dVertexDecl *decls;
   SVGA3dPrimitiveRange *ranges;
   static Matrix view;

   Matrix_Copy(view, gIdentityMatrix);
   Matrix_Scale(view, 0.5, 0.5, 0.5, 1.0);

   if (lastMouseState.buttons & VMMOUSE_LEFT_BUTTON) {
      Matrix_RotateX(view, lastMouseState.y *  0.0001);
      Matrix_RotateY(view, lastMouseState.x * -0.0001);
   } else {
      Matrix_RotateX(view, 30.0 * M_PI / 180.0);
      Matrix_RotateY(view, gFPS.frame * 0.01f);
   }

   Matrix_Translate(view, 0, 0, 3);

   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_VIEW, view);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_WORLD, gIdentityMatrix);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_PROJECTION, perspectiveMat);

   SVGA3D_BeginSetRenderState(CID, &rs, 4);
   {
      rs[0].state     = SVGA3D_RS_BLENDENABLE;
      rs[0].uintValue = FALSE;

      rs[1].state     = SVGA3D_RS_ZENABLE;
      rs[1].uintValue = TRUE;

      rs[2].state     = SVGA3D_RS_ZWRITEENABLE;
      rs[2].uintValue = TRUE;

      rs[3].state     = SVGA3D_RS_ZFUNC;
      rs[3].uintValue = SVGA3D_CMP_LESS;
   }
   SVGA_FIFOCommitAll();

   SVGA3D_BeginSetTextureState(CID, &ts, 4);
   {
      ts[0].stage = 0;
      ts[0].name  = SVGA3D_TS_BIND_TEXTURE;
      ts[0].value = SVGA3D_INVALID_ID;

      ts[1].stage = 0;
      ts[1].name  = SVGA3D_TS_COLOROP;
      ts[1].value = SVGA3D_TC_SELECTARG1;

      ts[2].stage = 0;
      ts[2].name  = SVGA3D_TS_COLORARG1;
      ts[2].value = SVGA3D_TA_DIFFUSE;

      ts[3].stage = 0;
      ts[3].name  = SVGA3D_TS_ALPHAARG1;
      ts[3].value = SVGA3D_TA_DIFFUSE;
   }
   SVGA_FIFOCommitAll();

   SVGA3D_BeginDrawPrimitives(CID, &decls, 2, &ranges, 1);
   {
      decls[0].identity.type = SVGA3D_DECLTYPE_FLOAT3;
      decls[0].identity.usage = SVGA3D_DECLUSAGE_POSITION;
      decls[0].array.surfaceId = vertexSid;
      decls[0].array.stride = sizeof(MyVertex);
      decls[0].array.offset = offsetof(MyVertex, position);

      decls[1].identity.type = SVGA3D_DECLTYPE_D3DCOLOR;
      decls[1].identity.usage = SVGA3D_DECLUSAGE_COLOR;
      decls[1].array.surfaceId = vertexSid;
      decls[1].array.stride = sizeof(MyVertex);
      decls[1].array.offset = offsetof(MyVertex, color);

      ranges[0].primType = SVGA3D_PRIMITIVE_TRIANGLELIST;
      ranges[0].primitiveCount = numTriangles;
      ranges[0].indexArray.surfaceId = indexSid;
      ranges[0].indexArray.stride = sizeof(uint16);
      ranges[0].indexWidth = sizeof(uint16);
   }
   SVGA_FIFOCommitAll();
}
Esempio n. 5
0
static int
update_tss_binding(struct svga_context *svga, 
                   unsigned dirty )
{
   unsigned i;
   unsigned count = MAX2( svga->curr.num_textures,
                          svga->state.hw_draw.num_views );
   unsigned min_lod;
   unsigned max_lod;


   struct {
      struct {
         unsigned unit;
         struct svga_hw_view_state *view;
      } bind[PIPE_MAX_SAMPLERS];

      unsigned bind_count;
   } queue;

   queue.bind_count = 0;
   
   for (i = 0; i < count; i++) {
      const struct svga_sampler_state *s = svga->curr.sampler[i];
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];

      /* get min max lod */
      if (svga->curr.texture[i]) {
         min_lod = MAX2(s->view_min_lod, 0);
         max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
      } else {
         min_lod = 0;
         max_lod = 0;
      }

      if (view->texture != svga->curr.texture[i] ||
          view->min_lod != min_lod ||
          view->max_lod != max_lod) {

         svga_sampler_view_reference(&view->v, NULL);
         pipe_texture_reference( &view->texture, svga->curr.texture[i] );

         view->dirty = TRUE;
         view->min_lod = min_lod;
         view->max_lod = max_lod;

         if (svga->curr.texture[i])
            view->v = svga_get_tex_sampler_view(&svga->pipe, 
                                                svga->curr.texture[i], 
                                                min_lod,
                                                max_lod);
      }

      if (view->dirty) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      } 
      else if (view->v) {
         svga_validate_sampler_view(svga, view->v);
      }
   }

   svga->state.hw_draw.num_views = svga->curr.num_textures;

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.bind_count ) != PIPE_OK)
         goto fail;

      for (i = 0; i < queue.bind_count; i++) {
         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         if (queue.bind[i].view->v) {
            svga->swc->surface_relocation(svga->swc,
                                          &ts[i].value,
                                          queue.bind[i].view->v->handle,
                                          PIPE_BUFFER_USAGE_GPU_READ);
         }
         else {
            ts[i].value = SVGA3D_INVALID_ID;
         }
         
         queue.bind[i].view->dirty = FALSE;
      }

      SVGA_FIFOCommitAll( svga->swc );
   }

   return 0;

fail:
   return PIPE_ERROR_OUT_OF_MEMORY;
}
Esempio n. 6
0
static int
update_tss(struct svga_context *svga, 
           unsigned dirty )
{
   unsigned i;
   struct ts_queue queue;

   queue.ts_count = 0;
   for (i = 0; i < svga->curr.num_samplers; i++) {
      if (svga->curr.sampler[i]) {
         const struct svga_sampler_state *curr = svga->curr.sampler[i];

         EMIT_TS(svga, i, curr->mipfilter, MIPFILTER, fail);
         EMIT_TS(svga, i, curr->min_lod, TEXTURE_MIPMAP_LEVEL, fail);
         EMIT_TS(svga, i, curr->magfilter, MAGFILTER, fail);
         EMIT_TS(svga, i, curr->minfilter, MINFILTER, fail);
         EMIT_TS(svga, i, curr->aniso_level, TEXTURE_ANISOTROPIC_LEVEL, fail);
         EMIT_TS_FLOAT(svga, i, curr->lod_bias, TEXTURE_LOD_BIAS, fail);
         EMIT_TS(svga, i, curr->addressu, ADDRESSU, fail);
         EMIT_TS(svga, i, curr->addressw, ADDRESSW, fail);
         EMIT_TS(svga, i, curr->bordercolor, BORDERCOLOR, fail);
         // TEXCOORDINDEX -- hopefully not needed

         if (svga->curr.tex_flags.flag_1d & (1 << i)) {
            debug_printf("wrap 1d tex %d\n", i);
            EMIT_TS(svga, i, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV, fail);
         }
         else
            EMIT_TS(svga, i, curr->addressv, ADDRESSV, fail);

         if (svga->curr.tex_flags.flag_srgb & (1 << i))
            EMIT_TS_FLOAT(svga, i, 2.2f, GAMMA, fail);
         else
            EMIT_TS_FLOAT(svga, i, 1.0f, GAMMA, fail);

      }
   }
 
   if (queue.ts_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.ts_count ) != PIPE_OK)
         goto fail;

      memcpy( ts,
              queue.ts,
              queue.ts_count * sizeof queue.ts[0]);
      
      SVGA_FIFOCommitAll( svga->swc );
   }

   return 0;

fail:
   /* XXX: need to poison cached hardware state on failure to ensure
    * dirty state gets re-emitted.  Fix this by re-instating partial
    * FIFOCommit command and only updating cached hw state once the
    * initial allocation has succeeded.
    */
   memset(svga->state.hw_draw.ts, 0xcd, sizeof(svga->state.hw_draw.ts));

   return PIPE_ERROR_OUT_OF_MEMORY;
}
Esempio n. 7
0
static void
drawCube(void)
{
   static float angle = 0.5f;
   SVGA3dRect *rect;
   Matrix perspectiveMat;
   SVGA3dTextureState *ts;
   SVGA3dRenderState *rs;
   SVGA3dRect viewport = { 0, 0, surfWidth, surfHeight };

   SVGA3D_SetRenderTarget(CID, SVGA3D_RT_COLOR0, &colorImage);
   SVGA3D_SetRenderTarget(CID, SVGA3D_RT_DEPTH, &depthImage);

   SVGA3D_SetViewport(CID, &viewport);
   SVGA3D_SetZRange(CID, 0.0f, 1.0f);

   SVGA3D_BeginSetRenderState(CID, &rs, 5);
   {
      rs[0].state     = SVGA3D_RS_BLENDENABLE;
      rs[0].uintValue = FALSE;

      rs[1].state     = SVGA3D_RS_ZENABLE;
      rs[1].uintValue = TRUE;

      rs[2].state     = SVGA3D_RS_ZWRITEENABLE;
      rs[2].uintValue = TRUE;

      rs[3].state     = SVGA3D_RS_ZFUNC;
      rs[3].uintValue = SVGA3D_CMP_LESS;

      rs[4].state     = SVGA3D_RS_LIGHTINGENABLE;
      rs[4].uintValue = FALSE;
   }
   SVGA_FIFOCommitAll();

   SVGA3D_BeginSetTextureState(CID, &ts, 4);
   {
      ts[0].stage = 0;
      ts[0].name  = SVGA3D_TS_BIND_TEXTURE;
      ts[0].value = SVGA3D_INVALID_ID;

      ts[1].stage = 0;
      ts[1].name  = SVGA3D_TS_COLOROP;
      ts[1].value = SVGA3D_TC_SELECTARG1;

      ts[2].stage = 0;
      ts[2].name  = SVGA3D_TS_COLORARG1;
      ts[2].value = SVGA3D_TA_DIFFUSE;

      ts[3].stage = 0;
      ts[3].name  = SVGA3D_TS_ALPHAARG1;
      ts[3].value = SVGA3D_TA_DIFFUSE;
   }
   SVGA_FIFOCommitAll();

   /*
    * Draw a red border around the render target, to test edge
    * accuracy in Present.
    */
   SVGA3D_BeginClear(CID, SVGA3D_CLEAR_COLOR | SVGA3D_CLEAR_DEPTH,
                     0xFF0000, 1.0f, 0, &rect, 1);
   *rect = viewport;
   SVGA_FIFOCommitAll();

   /*
    * Draw the background color
    */
   SVGA3D_BeginClear(CID, SVGA3D_CLEAR_COLOR | SVGA3D_CLEAR_DEPTH,
                     0x336699, 1.0f, 0, &rect, 1);
   rect->x = viewport.x + 1;
   rect->y = viewport.y + 1;
   rect->w = viewport.w - 2;
   rect->h = viewport.h - 2;
   SVGA_FIFOCommitAll();

   SVGA3dVertexDecl *decls;
   SVGA3dPrimitiveRange *ranges;
   Matrix view;

   Matrix_Copy(view, gIdentityMatrix);
   Matrix_Scale(view, 0.5, 0.5, 0.5, 1.0);
   Matrix_RotateX(view, 30.0 * M_PI / 180.0);
   Matrix_RotateY(view, angle);
   Matrix_Translate(view, 0, 0, 2.2);

   angle += 0.02;

   Matrix_Perspective(perspectiveMat, 45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_WORLD, gIdentityMatrix);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_PROJECTION, perspectiveMat);
   SVGA3D_SetTransform(CID, SVGA3D_TRANSFORM_VIEW, view);

   SVGA3D_BeginDrawPrimitives(CID, &decls, 2, &ranges, 1);
   {
      decls[0].identity.type = SVGA3D_DECLTYPE_FLOAT3;
      decls[0].identity.usage = SVGA3D_DECLUSAGE_POSITION;
      decls[0].array.surfaceId = vertexSid;
      decls[0].array.stride = sizeof(MyVertex);
      decls[0].array.offset = offsetof(MyVertex, position);

      decls[1].identity.type = SVGA3D_DECLTYPE_D3DCOLOR;
      decls[1].identity.usage = SVGA3D_DECLUSAGE_COLOR;
      decls[1].array.surfaceId = vertexSid;
      decls[1].array.stride = sizeof(MyVertex);
      decls[1].array.offset = offsetof(MyVertex, color);

      ranges[0].primType = SVGA3D_PRIMITIVE_LINELIST;
      ranges[0].primitiveCount = numLines;
      ranges[0].indexArray.surfaceId = indexSid;
      ranges[0].indexArray.stride = sizeof(uint16);
      ranges[0].indexWidth = sizeof(uint16);
   }
   SVGA_FIFOCommitAll();
}
Esempio n. 8
0
static int
update_tss_binding(struct svga_context *svga, 
                   unsigned dirty )
{
   boolean reemit = svga->rebind.texture_samplers;
   unsigned i;
   unsigned count = MAX2( svga->curr.num_sampler_views,
                          svga->state.hw_draw.num_views );
   unsigned min_lod;
   unsigned max_lod;

   struct bind_queue queue;

   queue.bind_count = 0;
   
   for (i = 0; i < count; i++) {
      const struct svga_sampler_state *s = svga->curr.sampler[i];
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
      struct pipe_resource *texture = NULL;

      /* get min max lod */
      if (svga->curr.sampler_views[i]) {
         min_lod = MAX2(s->view_min_lod, 0);
         max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level);
         texture = svga->curr.sampler_views[i]->texture;
      } else {
         min_lod = 0;
         max_lod = 0;
      }

      if (view->texture != texture ||
          view->min_lod != min_lod ||
          view->max_lod != max_lod) {

         svga_sampler_view_reference(&view->v, NULL);
         pipe_resource_reference( &view->texture, texture );

         view->dirty = TRUE;
         view->min_lod = min_lod;
         view->max_lod = max_lod;

         if (texture)
            view->v = svga_get_tex_sampler_view(&svga->pipe, 
                                                texture, 
                                                min_lod,
                                                max_lod);
      }

      /*
       * We need to reemit non-null texture bindings, even when they are not
       * dirty, to ensure that the resources are paged in.
       */

      if (view->dirty ||
          (reemit && view->v)) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      } 
      if (!view->dirty && view->v) {
         svga_validate_sampler_view(svga, view->v);
      }
   }

   svga->state.hw_draw.num_views = svga->curr.num_sampler_views;

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.bind_count ) != PIPE_OK)
         goto fail;

      for (i = 0; i < queue.bind_count; i++) {
         struct svga_winsys_surface *handle;

         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         if (queue.bind[i].view->v) {
            handle = queue.bind[i].view->v->handle;
         }
         else {
            handle = NULL;
         }
         svga->swc->surface_relocation(svga->swc,
                                       &ts[i].value,
                                       handle,
                                       SVGA_RELOC_READ);
         
         queue.bind[i].view->dirty = FALSE;
      }

      SVGA_FIFOCommitAll( svga->swc );
   }

   svga->rebind.texture_samplers = FALSE;

   return 0;

fail:
   return PIPE_ERROR_OUT_OF_MEMORY;
}