swr: [rasterizer] Miscellaneous backend changes
[mesa.git] / src / gallium / drivers / swr / swr_state.cpp
index 47ee3cb2664d68895110b6954b78f16a7eb11cb7..a7ae9df2d3ef54f98f768ff1bc1e249c36953fda 100644 (file)
@@ -239,7 +239,7 @@ swr_bind_sampler_states(struct pipe_context *pipe,
    unsigned i;
 
    assert(shader < PIPE_SHADER_TYPES);
-   assert(start + num <= Elements(ctx->samplers[shader]));
+   assert(start + num <= ARRAY_SIZE(ctx->samplers[shader]));
 
    /* set the new samplers */
    ctx->num_samplers[shader] = num;
@@ -288,7 +288,7 @@ swr_set_sampler_views(struct pipe_context *pipe,
    assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
 
    assert(shader < PIPE_SHADER_TYPES);
-   assert(start + num <= Elements(ctx->sampler_views[shader]));
+   assert(start + num <= ARRAY_SIZE(ctx->sampler_views[shader]));
 
    /* set the new sampler views */
    ctx->num_sampler_views[shader] = num;
@@ -317,8 +317,7 @@ static void *
 swr_create_vs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *vs)
 {
-   struct swr_vertex_shader *swr_vs =
-      (swr_vertex_shader *)CALLOC_STRUCT(swr_vertex_shader);
+   struct swr_vertex_shader *swr_vs = new swr_vertex_shader;
    if (!swr_vs)
       return NULL;
 
@@ -327,8 +326,6 @@ swr_create_vs_state(struct pipe_context *pipe,
 
    lp_build_tgsi_info(vs->tokens, &swr_vs->info);
 
-   swr_vs->func = swr_compile_vs(pipe, swr_vs);
-
    swr_vs->soState = {0};
 
    if (swr_vs->pipe.stream_output.num_outputs) {
@@ -368,7 +365,7 @@ swr_delete_vs_state(struct pipe_context *pipe, void *vs)
 {
    struct swr_vertex_shader *swr_vs = (swr_vertex_shader *)vs;
    FREE((void *)swr_vs->pipe.tokens);
-   FREE(vs);
+   delete swr_vs;
 }
 
 static void *
@@ -418,7 +415,7 @@ swr_set_constant_buffer(struct pipe_context *pipe,
    struct pipe_resource *constants = cb ? cb->buffer : NULL;
 
    assert(shader < PIPE_SHADER_TYPES);
-   assert(index < Elements(ctx->constants[shader]));
+   assert(index < ARRAY_SIZE(ctx->constants[shader]));
 
    /* note: reference counting */
    util_copy_constant_buffer(&ctx->constants[shader][index], cb);
@@ -646,24 +643,24 @@ swr_update_resource_status(struct pipe_context *pipe,
    if (fb->nr_cbufs)
       for (uint32_t i = 0; i < fb->nr_cbufs; ++i)
          if (fb->cbufs[i])
-            swr_resource_write(pipe, swr_resource(fb->cbufs[i]->texture));
+            swr_resource_write(fb->cbufs[i]->texture);
 
    /* depth/stencil target */
    if (fb->zsbuf)
-      swr_resource_write(pipe, swr_resource(fb->zsbuf->texture));
+      swr_resource_write(fb->zsbuf->texture);
 
    /* VBO vertex buffers */
    for (uint32_t i = 0; i < ctx->num_vertex_buffers; i++) {
       struct pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];
       if (!vb->user_buffer)
-         swr_resource_read(pipe, swr_resource(vb->buffer));
+         swr_resource_read(vb->buffer);
    }
 
    /* VBO index buffer */
    if (p_draw_info && p_draw_info->indexed) {
       struct pipe_index_buffer *ib = &ctx->index_buffer;
       if (!ib->user_buffer)
-         swr_resource_read(pipe, swr_resource(ib->buffer));
+         swr_resource_read(ib->buffer);
    }
 
    /* texture sampler views */
@@ -671,7 +668,104 @@ swr_update_resource_status(struct pipe_context *pipe,
       struct pipe_sampler_view *view =
          ctx->sampler_views[PIPE_SHADER_FRAGMENT][i];
       if (view)
-         swr_resource_read(pipe, swr_resource(view->texture));
+         swr_resource_read(view->texture);
+   }
+}
+
+static void
+swr_update_texture_state(struct swr_context *ctx,
+                         unsigned shader_type,
+                         unsigned num_sampler_views,
+                         swr_jit_texture *textures)
+{
+   for (unsigned i = 0; i < num_sampler_views; i++) {
+      struct pipe_sampler_view *view =
+         ctx->sampler_views[shader_type][i];
+
+      if (view) {
+         struct pipe_resource *res = view->texture;
+         struct swr_resource *swr_res = swr_resource(res);
+         struct swr_jit_texture *jit_tex = &textures[i];
+         memset(jit_tex, 0, sizeof(*jit_tex));
+         jit_tex->width = res->width0;
+         jit_tex->height = res->height0;
+         jit_tex->depth = res->depth0;
+         jit_tex->first_level = view->u.tex.first_level;
+         jit_tex->last_level = view->u.tex.last_level;
+         jit_tex->base_ptr = swr_res->swr.pBaseAddress;
+
+         for (unsigned level = jit_tex->first_level;
+              level <= jit_tex->last_level;
+              level++) {
+            jit_tex->row_stride[level] = swr_res->row_stride[level];
+            jit_tex->img_stride[level] = swr_res->img_stride[level];
+            jit_tex->mip_offsets[level] = swr_res->mip_offsets[level];
+         }
+      }
+   }
+}
+
+static void
+swr_update_sampler_state(struct swr_context *ctx,
+                         unsigned shader_type,
+                         unsigned num_samplers,
+                         swr_jit_sampler *samplers)
+{
+   for (unsigned i = 0; i < num_samplers; i++) {
+      const struct pipe_sampler_state *sampler =
+         ctx->samplers[shader_type][i];
+
+      if (sampler) {
+         samplers[i].min_lod = sampler->min_lod;
+         samplers[i].max_lod = sampler->max_lod;
+         samplers[i].lod_bias = sampler->lod_bias;
+         COPY_4V(samplers[i].border_color, sampler->border_color.f);
+      }
+   }
+}
+
+static void
+swr_update_constants(struct swr_context *ctx, enum pipe_shader_type shaderType)
+{
+   swr_draw_context *pDC = &ctx->swrDC;
+
+   const float **constant;
+   uint32_t *num_constants;
+   struct swr_scratch_space *scratch;
+
+   switch (shaderType) {
+   case PIPE_SHADER_VERTEX:
+      constant = pDC->constantVS;
+      num_constants = pDC->num_constantsVS;
+      scratch = &ctx->scratch->vs_constants;
+      break;
+   case PIPE_SHADER_FRAGMENT:
+      constant = pDC->constantFS;
+      num_constants = pDC->num_constantsFS;
+      scratch = &ctx->scratch->fs_constants;
+      break;
+   default:
+      debug_printf("Unsupported shader type constants\n");
+      return;
+   }
+
+   for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+      const pipe_constant_buffer *cb = &ctx->constants[shaderType][i];
+      num_constants[i] = cb->buffer_size;
+      if (cb->buffer) {
+         constant[i] =
+            (const float *)(swr_resource_data(cb->buffer) +
+                            cb->buffer_offset);
+      } else {
+         /* Need to copy these constants to scratch space */
+         if (cb->user_buffer && cb->buffer_size) {
+            const void *ptr =
+               ((const uint8_t *)cb->user_buffer + cb->buffer_offset);
+            uint32_t size = AlignUp(cb->buffer_size, 4);
+            ptr = swr_copy_to_scratch_space(ctx, scratch, ptr, size);
+            constant[i] = (const float *)ptr;
+         }
+      }
    }
 }
 
@@ -782,7 +876,7 @@ swr_update_derived(struct pipe_context *pipe,
       rastState->msaaRastEnable = false;
       rastState->rastMode = SWR_MSAA_RASTMODE_OFF_PIXEL;
       rastState->sampleCount = SWR_MULTISAMPLE_1X;
-      rastState->bForcedSampleCount = false;
+      rastState->forcedSampleCount = false;
 
       bool do_offset = false;
       switch (rasterizer->fill_front) {
@@ -887,8 +981,7 @@ swr_update_derived(struct pipe_context *pipe,
             max_vertex = size / pitch;
             partial_inbounds = size % pitch;
 
-            p_data = (const uint8_t *)swr_resource_data(vb->buffer)
-               + vb->buffer_offset;
+            p_data = swr_resource_data(vb->buffer) + vb->buffer_offset;
          } else {
             /* Client buffer
              * client memory is one-time use, re-trigger SWR_NEW_VERTEX to
@@ -940,8 +1033,7 @@ swr_update_derived(struct pipe_context *pipe,
              * size is based on buffer->width0 rather than info.count
              * to prevent having to validate VBO on each draw */
             size = ib->buffer->width0;
-            p_data =
-               (const uint8_t *)swr_resource_data(ib->buffer) + ib->offset;
+            p_data = swr_resource_data(ib->buffer) + ib->offset;
          } else {
             /* Client buffer
              * client memory is one-time use, re-trigger SWR_NEW_VERTEX to
@@ -974,22 +1066,49 @@ swr_update_derived(struct pipe_context *pipe,
    }
 
    /* VertexShader */
-   if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_FRAMEBUFFER)) {
-      SwrSetVertexFunc(ctx->swrContext, ctx->vs->func);
+   if (ctx->dirty & (SWR_NEW_VS |
+                     SWR_NEW_SAMPLER |
+                     SWR_NEW_SAMPLER_VIEW |
+                     SWR_NEW_FRAMEBUFFER)) {
+      swr_jit_vs_key key;
+      swr_generate_vs_key(key, ctx, ctx->vs);
+      auto search = ctx->vs->map.find(key);
+      PFN_VERTEX_FUNC func;
+      if (search != ctx->vs->map.end()) {
+         func = search->second->shader;
+      } else {
+         func = swr_compile_vs(ctx, key);
+      }
+      SwrSetVertexFunc(ctx->swrContext, func);
+
+      /* JIT sampler state */
+      if (ctx->dirty & SWR_NEW_SAMPLER) {
+         swr_update_sampler_state(ctx,
+                                  PIPE_SHADER_VERTEX,
+                                  key.nr_samplers,
+                                  ctx->swrDC.samplersVS);
+      }
+
+      /* JIT sampler view state */
+      if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
+         swr_update_texture_state(ctx,
+                                  PIPE_SHADER_VERTEX,
+                                  key.nr_sampler_views,
+                                  ctx->swrDC.texturesVS);
+      }
    }
 
-   swr_jit_key key;
+   /* FragmentShader */
    if (ctx->dirty & (SWR_NEW_FS | SWR_NEW_SAMPLER | SWR_NEW_SAMPLER_VIEW
                      | SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {
-      memset(&key, 0, sizeof(key));
+      swr_jit_fs_key key;
       swr_generate_fs_key(key, ctx, ctx->fs);
       auto search = ctx->fs->map.find(key);
       PFN_PIXEL_KERNEL func;
       if (search != ctx->fs->map.end()) {
-         func = search->second;
+         func = search->second->shader;
       } else {
          func = swr_compile_fs(ctx, key);
-         ctx->fs->map.insert(std::make_pair(key, func));
       }
       SWR_PS_STATE psState = {0};
       psState.pfnPixelShader = func;
@@ -1031,104 +1150,33 @@ swr_update_derived(struct pipe_context *pipe,
       psState.usesUAV = false; // XXX
       psState.forceEarlyZ = false;
       SwrSetPixelShaderState(ctx->swrContext, &psState);
-   }
 
-   /* JIT sampler state */
-   if (ctx->dirty & SWR_NEW_SAMPLER) {
-      swr_draw_context *pDC = &ctx->swrDC;
-
-      for (unsigned i = 0; i < key.nr_samplers; i++) {
-         const struct pipe_sampler_state *sampler =
-            ctx->samplers[PIPE_SHADER_FRAGMENT][i];
-
-         if (sampler) {
-            pDC->samplersFS[i].min_lod = sampler->min_lod;
-            pDC->samplersFS[i].max_lod = sampler->max_lod;
-            pDC->samplersFS[i].lod_bias = sampler->lod_bias;
-            COPY_4V(pDC->samplersFS[i].border_color, sampler->border_color.f);
-         }
+      /* JIT sampler state */
+      if (ctx->dirty & SWR_NEW_SAMPLER) {
+         swr_update_sampler_state(ctx,
+                                  PIPE_SHADER_FRAGMENT,
+                                  key.nr_samplers,
+                                  ctx->swrDC.samplersFS);
       }
-   }
-
-   /* JIT sampler view state */
-   if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
-      swr_draw_context *pDC = &ctx->swrDC;
 
-      for (unsigned i = 0; i < key.nr_sampler_views; i++) {
-         struct pipe_sampler_view *view =
-            ctx->sampler_views[PIPE_SHADER_FRAGMENT][i];
-
-         if (view) {
-            struct pipe_resource *res = view->texture;
-            struct swr_resource *swr_res = swr_resource(res);
-            struct swr_jit_texture *jit_tex = &pDC->texturesFS[i];
-            memset(jit_tex, 0, sizeof(*jit_tex));
-            jit_tex->width = res->width0;
-            jit_tex->height = res->height0;
-            jit_tex->depth = res->depth0;
-            jit_tex->first_level = view->u.tex.first_level;
-            jit_tex->last_level = view->u.tex.last_level;
-            jit_tex->base_ptr = swr_res->swr.pBaseAddress;
-
-            for (unsigned level = jit_tex->first_level;
-                 level <= jit_tex->last_level;
-                 level++) {
-               jit_tex->row_stride[level] = swr_res->row_stride[level];
-               jit_tex->img_stride[level] = swr_res->img_stride[level];
-               jit_tex->mip_offsets[level] = swr_res->mip_offsets[level];
-            }
-         }
+      /* JIT sampler view state */
+      if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
+         swr_update_texture_state(ctx,
+                                  PIPE_SHADER_FRAGMENT,
+                                  key.nr_sampler_views,
+                                  ctx->swrDC.texturesFS);
       }
    }
 
+
    /* VertexShader Constants */
    if (ctx->dirty & SWR_NEW_VSCONSTANTS) {
-      swr_draw_context *pDC = &ctx->swrDC;
-
-      for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-         const pipe_constant_buffer *cb =
-            &ctx->constants[PIPE_SHADER_VERTEX][i];
-         pDC->num_constantsVS[i] = cb->buffer_size;
-         if (cb->buffer)
-            pDC->constantVS[i] =
-               (const float *)((const uint8_t *)cb->buffer + cb->buffer_offset);
-         else {
-            /* Need to copy these constants to scratch space */
-            if (cb->user_buffer && cb->buffer_size) {
-               const void *ptr =
-                  ((const uint8_t *)cb->user_buffer + cb->buffer_offset);
-               uint32_t size = AlignUp(cb->buffer_size, 4);
-               ptr = swr_copy_to_scratch_space(
-                  ctx, &ctx->scratch->vs_constants, ptr, size);
-               pDC->constantVS[i] = (const float *)ptr;
-            }
-         }
-      }
+      swr_update_constants(ctx, PIPE_SHADER_VERTEX);
    }
 
    /* FragmentShader Constants */
    if (ctx->dirty & SWR_NEW_FSCONSTANTS) {
-      swr_draw_context *pDC = &ctx->swrDC;
-
-      for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-         const pipe_constant_buffer *cb =
-            &ctx->constants[PIPE_SHADER_FRAGMENT][i];
-         pDC->num_constantsFS[i] = cb->buffer_size;
-         if (cb->buffer)
-            pDC->constantFS[i] =
-               (const float *)((const uint8_t *)cb->buffer + cb->buffer_offset);
-         else {
-            /* Need to copy these constants to scratch space */
-            if (cb->user_buffer && cb->buffer_size) {
-               const void *ptr =
-                  ((const uint8_t *)cb->user_buffer + cb->buffer_offset);
-               uint32_t size = AlignUp(cb->buffer_size, 4);
-               ptr = swr_copy_to_scratch_space(
-                  ctx, &ctx->scratch->fs_constants, ptr, size);
-               pDC->constantFS[i] = (const float *)ptr;
-            }
-         }
-      }
+      swr_update_constants(ctx, PIPE_SHADER_FRAGMENT);
    }
 
    /* Depth/stencil state */