tfu
[mesa.git] / src / gallium / drivers / swr / swr_state.cpp
index 1491868eaeb5418c1b1a0f38626c45b474f58670..e540ddb06c868046d9afcd3aaccc776d85670235 100644 (file)
@@ -531,7 +531,7 @@ swr_create_vertex_elements_state(struct pipe_context *pipe,
             ? ComponentControl::StoreSrc
             : ComponentControl::Store1Fp;
          velems->fsState.layout[i].ComponentPacking = ComponentEnable::XYZW;
-         velems->fsState.layout[i].InstanceDataStepRate =
+         velems->fsState.layout[i].InstanceAdvancementState =
             attribs[i].instance_divisor;
 
          /* Calculate the pitch of each stream */
@@ -953,6 +953,47 @@ swr_change_rt(struct swr_context *ctx,
    return need_fence;
 }
 
+/*
+ * for cases where resources are shared between contexts, invalidate
+ * this ctx's resource. so it can be fetched fresh.  Old ctx's resource
+ * is already stored during a flush
+ */
+static inline void
+swr_invalidate_buffers_after_ctx_change(struct pipe_context *pipe)
+{
+   struct swr_context *ctx = swr_context(pipe);
+
+   for (uint32_t i = 0; i < ctx->framebuffer.nr_cbufs; i++) {
+      struct pipe_surface *cb = ctx->framebuffer.cbufs[i];
+      if (cb) {
+         struct swr_resource *res = swr_resource(cb->texture);
+         if (res->curr_pipe != pipe) {
+            /* if curr_pipe is NULL (first use), status should not be WRITE */
+            assert(res->curr_pipe || !(res->status & SWR_RESOURCE_WRITE));
+            if (res->status & SWR_RESOURCE_WRITE) {
+               swr_invalidate_render_target(pipe, i, cb->width, cb->height);
+            }
+         }
+         res->curr_pipe = pipe;
+      }
+   }
+   if (ctx->framebuffer.zsbuf) {
+      struct pipe_surface *zb = ctx->framebuffer.zsbuf;
+      if (zb) {
+         struct swr_resource *res = swr_resource(zb->texture);
+         if (res->curr_pipe != pipe) {
+            /* if curr_pipe is NULL (first use), status should not be WRITE */
+            assert(res->curr_pipe || !(res->status & SWR_RESOURCE_WRITE));
+            if (res->status & SWR_RESOURCE_WRITE) {
+               swr_invalidate_render_target(pipe, SWR_ATTACHMENT_DEPTH, zb->width, zb->height);
+               swr_invalidate_render_target(pipe, SWR_ATTACHMENT_STENCIL, zb->width, zb->height);
+            }
+         }
+         res->curr_pipe = pipe;
+      }
+   }
+}
+
 static inline void
 swr_user_vbuf_range(const struct pipe_draw_info *info,
                     const struct swr_vertex_element_state *velems,
@@ -971,8 +1012,8 @@ swr_user_vbuf_range(const struct pipe_draw_info *info,
       *size = elems * vb->stride;
    } else if (vb->stride) {
       elems = info->max_index - info->min_index + 1;
-      *totelems = info->max_index + 1;
-      *base = info->min_index * vb->stride;
+      *totelems = (info->max_index + info->index_bias) + 1;
+      *base = (info->min_index + info->index_bias) * vb->stride;
       *size = elems * vb->stride;
    } else {
       *totelems = 1;
@@ -1033,13 +1074,15 @@ swr_update_derived(struct pipe_context *pipe,
    }
 
    /* Update screen->pipe to current pipe context. */
-   if (screen->pipe != pipe)
-      screen->pipe = pipe;
+   screen->pipe = pipe;
 
    /* Any state that requires dirty flags to be re-triggered sets this mask */
    /* For example, user_buffer vertex and index buffers. */
    unsigned post_update_dirty_flags = 0;
 
+   /* bring resources that changed context up-to-date */
+   swr_invalidate_buffers_after_ctx_change(pipe);
+
    /* Render Targets */
    if (ctx->dirty & SWR_NEW_FRAMEBUFFER) {
       struct pipe_framebuffer_state *fb = &ctx->framebuffer;
@@ -1155,17 +1198,12 @@ swr_update_derived(struct pipe_context *pipe,
       if (zb && swr_resource(zb->texture)->has_depth)
          rastState->depthFormat = swr_resource(zb->texture)->swr.format;
 
-      rastState->depthClipEnable = rasterizer->depth_clip;
+      rastState->depthClipEnable = rasterizer->depth_clip_near;
       rastState->clipHalfZ = rasterizer->clip_halfz;
 
       ctx->api.pfnSwrSetRastState(ctx->swrContext, rastState);
    }
 
-   /* Scissor */
-   if (ctx->dirty & SWR_NEW_SCISSOR) {
-      ctx->api.pfnSwrSetScissorRects(ctx->swrContext, 1, &ctx->swr_scissor);
-   }
-
    /* Viewport */
    if (ctx->dirty & (SWR_NEW_VIEWPORT | SWR_NEW_FRAMEBUFFER
                      | SWR_NEW_RASTERIZER)) {
@@ -1206,18 +1244,26 @@ swr_update_derived(struct pipe_context *pipe,
       ctx->api.pfnSwrSetViewports(ctx->swrContext, 1, vp, vpm);
    }
 
-   /* Set vertex & index buffers
-    * (using draw info if called by swr_draw_vbo)
-    * If indexed draw, revalidate since index buffer comes from
-    * pipe_draw_info.
-    */
-   if (ctx->dirty & SWR_NEW_VERTEX ||
-      (p_draw_info && p_draw_info->index_size)) {
+   /* When called from swr_clear (p_draw_info = null), render targets,
+    * rasterState and viewports (dependent on render targets) are the only
+    * necessary validation.  Defer remaining validation by setting
+    * post_update_dirty_flags and clear all dirty flags.  BackendState is
+    * still unconditionally validated below */
+   if (!p_draw_info) {
+      post_update_dirty_flags = ctx->dirty & ~(SWR_NEW_FRAMEBUFFER |
+                                               SWR_NEW_RASTERIZER |
+                                               SWR_NEW_VIEWPORT);
+      ctx->dirty = 0;
+   }
+
+   /* Scissor */
+   if (ctx->dirty & SWR_NEW_SCISSOR) {
+      ctx->api.pfnSwrSetScissorRects(ctx->swrContext, 1, &ctx->swr_scissor);
+   }
 
-      /* If being called by swr_draw_vbo, copy draw details */
-      struct pipe_draw_info info = {0};
-      if (p_draw_info)
-         info = *p_draw_info;
+   /* Set vertex & index buffers */
+   if (ctx->dirty & SWR_NEW_VERTEX) {
+      const struct pipe_draw_info &info = *p_draw_info;
 
       /* vertex buffers */
       SWR_VERTEX_BUFFER_STATE swrVertexBuffers[PIPE_MAX_ATTRIBS];
@@ -1258,7 +1304,7 @@ swr_update_derived(struct pipe_context *pipe,
             uint32_t base;
             swr_user_vbuf_range(&info, ctx->velems, vb, i, &elems, &base, &size);
             partial_inbounds = 0;
-            min_vertex_index = info.min_index;
+            min_vertex_index = info.min_index + info.index_bias;
 
             size = AlignUp(size, 4);
             /* If size of client memory copy is too large, don't copy. The
@@ -1279,7 +1325,7 @@ swr_update_derived(struct pipe_context *pipe,
          swrVertexBuffers[i] = {0};
          swrVertexBuffers[i].index = i;
          swrVertexBuffers[i].pitch = pitch;
-         swrVertexBuffers[i].pData = p_data;
+         swrVertexBuffers[i].xpData = (gfxptr_t) p_data;
          swrVertexBuffers[i].size = size;
          swrVertexBuffers[i].minVertex = min_vertex_index;
          swrVertexBuffers[i].maxVertex = elems;
@@ -1329,7 +1375,7 @@ swr_update_derived(struct pipe_context *pipe,
 
          SWR_INDEX_BUFFER_STATE swrIndexBuffer;
          swrIndexBuffer.format = swr_convert_index_type(info.index_size);
-         swrIndexBuffer.pIndices = p_data;
+         swrIndexBuffer.xpIndices = (gfxptr_t) p_data;
          swrIndexBuffer.size = size;
 
          ctx->api.pfnSwrSetIndexBuffer(ctx->swrContext, &swrIndexBuffer);