ilo: introduce ilo_shader_cso for VS
[mesa.git] / src / gallium / drivers / ilo / ilo_3d_pipeline_gen6.c
index f2bdf371d60b05512f99f668db85c15124901170..e51d7942ab3e8a0237b9953b7f85e9e73558c63c 100644 (file)
@@ -29,6 +29,8 @@
 #include "util/u_prim.h"
 #include "intel_reg.h"
 
+#include "shader/ilo_shader_internal.h"
+#include "ilo_3d.h"
 #include "ilo_context.h"
 #include "ilo_cp.h"
 #include "ilo_gpe_gen6.h"
@@ -210,12 +212,13 @@ gen6_pipeline_common_base_address(struct ilo_3d_pipeline *p,
                                   struct gen6_pipeline_session *session)
 {
    /* STATE_BASE_ADDRESS */
-   if (session->state_bo_changed || session->instruction_bo_changed) {
+   if (session->state_bo_changed || session->kernel_bo_changed ||
+       session->batch_bo_changed) {
       if (p->dev->gen == ILO_GEN(6))
          gen6_wa_pipe_control_post_sync(p, false);
 
       p->gen6_STATE_BASE_ADDRESS(p->dev,
-            NULL, p->cp->bo, p->cp->bo, NULL, ilo->shader_cache->bo,
+            NULL, p->cp->bo, p->cp->bo, NULL, ilo->hw3d->kernel.bo,
             0, 0, 0, 0, p->cp);
 
       /*
@@ -396,15 +399,16 @@ gen6_pipeline_vf(struct ilo_3d_pipeline *p,
                  struct gen6_pipeline_session *session)
 {
    /* 3DSTATE_INDEX_BUFFER */
-   if (DIRTY(INDEX_BUFFER)) {
+   if (DIRTY(INDEX_BUFFER) || session->batch_bo_changed) {
       p->gen6_3DSTATE_INDEX_BUFFER(p->dev,
             &ilo->ib.state, session->info->primitive_restart, p->cp);
    }
 
    /* 3DSTATE_VERTEX_BUFFERS */
-   if (DIRTY(VERTEX_BUFFERS)) {
+   if (DIRTY(VERTEX_BUFFERS) || DIRTY(VERTEX_ELEMENTS) ||
+       session->batch_bo_changed) {
       p->gen6_3DSTATE_VERTEX_BUFFERS(p->dev,
-            ilo->vb.states, NULL, ilo->vb.enabled_mask, p->cp);
+            ilo->vb.states, ilo->vb.enabled_mask, ilo->ve, p->cp);
    }
 
    /* 3DSTATE_VERTEX_ELEMENTS */
@@ -425,8 +429,7 @@ gen6_pipeline_vf(struct ilo_3d_pipeline *p,
          prepend_generate_ids = (info->has_instanceid || info->has_vertexid);
       }
 
-      p->gen6_3DSTATE_VERTEX_ELEMENTS(p->dev,
-            ve->states, ve->count,
+      p->gen6_3DSTATE_VERTEX_ELEMENTS(p->dev, ve,
             last_velement_edgeflag, prepend_generate_ids, p->cp);
    }
 }
@@ -456,7 +459,8 @@ gen6_pipeline_vs(struct ilo_3d_pipeline *p,
                  const struct ilo_context *ilo,
                  struct gen6_pipeline_session *session)
 {
-   const bool emit_3dstate_vs = (DIRTY(VS) || DIRTY(VERTEX_SAMPLERS));
+   const bool emit_3dstate_vs = (DIRTY(VS) || DIRTY(VERTEX_SAMPLERS) ||
+                                 session->kernel_bo_changed);
    const bool emit_3dstate_constant_vs = session->pcb_state_vs_changed;
 
    /*
@@ -476,10 +480,9 @@ gen6_pipeline_vs(struct ilo_3d_pipeline *p,
 
    /* 3DSTATE_VS */
    if (emit_3dstate_vs) {
-      const struct ilo_shader *vs = (ilo->vs)? ilo->vs->shader : NULL;
       const int num_samplers = ilo->sampler[PIPE_SHADER_VERTEX].count;
 
-      p->gen6_3DSTATE_VS(p->dev, vs, num_samplers, p->cp);
+      p->gen6_3DSTATE_VS(p->dev, ilo->vs, num_samplers, p->cp);
    }
 
    if (emit_3dstate_constant_vs && p->dev->gen == ILO_GEN(6))
@@ -496,7 +499,8 @@ gen6_pipeline_gs(struct ilo_3d_pipeline *p,
       p->gen6_3DSTATE_CONSTANT_GS(p->dev, NULL, NULL, 0, p->cp);
 
    /* 3DSTATE_GS */
-   if (DIRTY(GS) || DIRTY(VS) || session->prim_changed) {
+   if (DIRTY(GS) || DIRTY(VS) ||
+       session->prim_changed || session->kernel_bo_changed) {
       const struct ilo_shader *gs = (ilo->gs)? ilo->gs->shader : NULL;
       const struct ilo_shader *vs = (ilo->vs)? ilo->vs->shader : NULL;
       const int num_vertices = u_vertices_per_prim(session->reduced_prim);
@@ -616,7 +620,7 @@ gen6_pipeline_clip(struct ilo_3d_pipeline *p,
       }
 
       p->gen6_3DSTATE_CLIP(p->dev,
-            &ilo->rasterizer->state,
+            ilo->rasterizer,
             (ilo->fs && ilo->fs->shader->in.has_linear_interp),
             enable_guardband, 1, p->cp);
    }
@@ -634,8 +638,7 @@ gen6_pipeline_sf(struct ilo_3d_pipeline *p,
          (ilo->gs)? ilo->gs->shader :
          (ilo->vs)? ilo->vs->shader : NULL;
 
-      p->gen6_3DSTATE_SF(p->dev,
-            &ilo->rasterizer->state, fs, last_sh, p->cp);
+      p->gen6_3DSTATE_SF(p->dev, ilo->rasterizer, fs, last_sh, p->cp);
    }
 }
 
@@ -666,15 +669,12 @@ gen6_pipeline_wm(struct ilo_3d_pipeline *p,
    /* 3DSTATE_WM */
    if (DIRTY(FS) || DIRTY(FRAGMENT_SAMPLERS) ||
        DIRTY(BLEND) || DIRTY(DEPTH_STENCIL_ALPHA) ||
-       DIRTY(RASTERIZER)) {
+       DIRTY(RASTERIZER) || session->kernel_bo_changed) {
       const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
       const int num_samplers = ilo->sampler[PIPE_SHADER_FRAGMENT].count;
-      const bool dual_blend =
-         (!ilo->blend->state.logicop_enable &&
-          ilo->blend->state.rt[0].blend_enable &&
-          util_blend_state_is_dual(&ilo->blend->state, 0));
-      const bool cc_may_kill = (ilo->dsa->state.alpha.enabled ||
-                                ilo->blend->state.alpha_to_coverage);
+      const bool dual_blend = ilo->blend->dual_blend;
+      const bool cc_may_kill = (ilo->dsa->alpha.enabled ||
+                                ilo->blend->alpha_to_coverage);
 
       if (fs)
          assert(!fs->pcb.clip_state_size);
@@ -719,14 +719,26 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p,
                        struct gen6_pipeline_session *session)
 {
    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
-   if (DIRTY(FRAMEBUFFER)) {
+   if (DIRTY(FRAMEBUFFER) || session->batch_bo_changed) {
+      const struct ilo_zs_surface *zs;
+
+      if (ilo->fb.state.zsbuf) {
+         const struct ilo_surface_cso *surface =
+            (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
+
+         assert(!surface->is_rt);
+         zs = &surface->u.zs;
+      }
+      else {
+         zs = &ilo->fb.null_zs;
+      }
+
       if (p->dev->gen == ILO_GEN(6)) {
          gen6_wa_pipe_control_post_sync(p, false);
          gen6_wa_pipe_control_wm_depth_flush(p);
       }
 
-      p->gen6_3DSTATE_DEPTH_BUFFER(p->dev,
-            ilo->fb.state.zsbuf, false, p->cp);
+      p->gen6_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp);
 
       /* TODO */
       p->gen6_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp);
@@ -807,7 +819,7 @@ gen6_pipeline_state_cc(struct ilo_3d_pipeline *p,
    /* BLEND_STATE */
    if (DIRTY(BLEND) || DIRTY(FRAMEBUFFER) || DIRTY(DEPTH_STENCIL_ALPHA)) {
       p->state.BLEND_STATE = p->gen6_BLEND_STATE(p->dev,
-            &ilo->blend->state, &ilo->fb, &ilo->dsa->state.alpha, p->cp);
+            ilo->blend, &ilo->fb, &ilo->dsa->alpha, p->cp);
 
       session->cc_state_blend_changed = true;
    }
@@ -816,7 +828,7 @@ gen6_pipeline_state_cc(struct ilo_3d_pipeline *p,
    if (DIRTY(DEPTH_STENCIL_ALPHA) || DIRTY(STENCIL_REF) || DIRTY(BLEND_COLOR)) {
       p->state.COLOR_CALC_STATE =
          p->gen6_COLOR_CALC_STATE(p->dev, &ilo->stencil_ref,
-               ilo->dsa->state.alpha.ref_value, &ilo->blend_color, p->cp);
+               ilo->dsa->alpha.ref_value, &ilo->blend_color, p->cp);
 
       session->cc_state_cc_changed = true;
    }
@@ -824,7 +836,7 @@ gen6_pipeline_state_cc(struct ilo_3d_pipeline *p,
    /* DEPTH_STENCIL_STATE */
    if (DIRTY(DEPTH_STENCIL_ALPHA)) {
       p->state.DEPTH_STENCIL_STATE =
-         p->gen6_DEPTH_STENCIL_STATE(p->dev, &ilo->dsa->state, p->cp);
+         p->gen6_DEPTH_STENCIL_STATE(p->dev, ilo->dsa, p->cp);
 
       session->cc_state_dsa_changed = true;
    }
@@ -839,7 +851,7 @@ gen6_pipeline_state_scissors(struct ilo_3d_pipeline *p,
    if (DIRTY(SCISSOR) || DIRTY(VIEWPORT)) {
       /* there should be as many scissors as there are viewports */
       p->state.SCISSOR_RECT = p->gen6_SCISSOR_RECT(p->dev,
-            ilo->scissor.states, ilo->viewport.count, p->cp);
+            &ilo->scissor, ilo->viewport.count, p->cp);
 
       session->scissor_state_changed = true;
    }
@@ -857,11 +869,12 @@ gen6_pipeline_state_surfaces_rt(struct ilo_3d_pipeline *p,
       int i;
 
       for (i = 0; i < ilo->fb.state.nr_cbufs; i++) {
-         const struct pipe_surface *surface = ilo->fb.state.cbufs[i];
+         const struct ilo_surface_cso *surface =
+            (const struct ilo_surface_cso *) ilo->fb.state.cbufs[i];
 
-         assert(surface);
+         assert(surface && surface->is_rt);
          surface_state[i] =
-            p->gen6_surf_SURFACE_STATE(p->dev, surface, p->cp);
+            p->gen6_SURFACE_STATE(p->dev, &surface->u.rt, true, p->cp);
       }
 
       /*
@@ -869,14 +882,14 @@ gen6_pipeline_state_surfaces_rt(struct ilo_3d_pipeline *p,
        * brw_update_renderbuffer_surfaces() does.  I don't know why.
        */
       if (i == 0) {
-         struct pipe_surface null_surface;
+         struct ilo_view_surface null_surface;
 
-         memset(&null_surface, 0, sizeof(null_surface));
-         null_surface.width = ilo->fb.state.width;
-         null_surface.height = ilo->fb.state.height;
+         ilo_gpe_init_view_surface_null(p->dev,
+               ilo->fb.state.width, ilo->fb.state.height,
+               1, 0, &null_surface);
 
          surface_state[i] =
-            p->gen6_surf_SURFACE_STATE(p->dev, &null_surface, p->cp);
+            p->gen6_SURFACE_STATE(p->dev, &null_surface, true, p->cp);
 
          i++;
       }
@@ -942,7 +955,7 @@ gen6_pipeline_state_surfaces_view(struct ilo_3d_pipeline *p,
                                   int shader_type,
                                   struct gen6_pipeline_session *session)
 {
-   const struct pipe_sampler_view **views =
+   const struct pipe_sampler_view * const *views =
       (const struct pipe_sampler_view **) ilo->view[shader_type].states;
    const int num_views = ilo->view[shader_type].count;
    uint32_t *surface_state;
@@ -983,8 +996,11 @@ gen6_pipeline_state_surfaces_view(struct ilo_3d_pipeline *p,
 
    for (i = 0; i < num_views; i++) {
       if (views[i]) {
+         const struct ilo_view_cso *cso =
+            (const struct ilo_view_cso *) views[i];
+
          surface_state[i] =
-            p->gen6_view_SURFACE_STATE(p->dev, views[i], p->cp);
+            p->gen6_SURFACE_STATE(p->dev, &cso->surface, false, p->cp);
       }
       else {
          surface_state[i] = 0;
@@ -1003,8 +1019,7 @@ gen6_pipeline_state_surfaces_const(struct ilo_3d_pipeline *p,
                                    int shader_type,
                                    struct gen6_pipeline_session *session)
 {
-   const struct pipe_constant_buffer *buffers =
-      ilo->cbuf[shader_type].states;
+   const struct ilo_cbuf_cso *buffers = ilo->cbuf[shader_type].cso;
    const int num_buffers = ilo->cbuf[shader_type].count;
    uint32_t *surface_state;
    int offset, i;
@@ -1043,9 +1058,11 @@ gen6_pipeline_state_surfaces_const(struct ilo_3d_pipeline *p,
       return;
 
    for (i = 0; i < num_buffers; i++) {
-      if (buffers[i].buffer) {
+      if (buffers[i].resource) {
+         const struct ilo_view_surface *surf = &buffers[i].surface;
+
          surface_state[i] =
-            p->gen6_cbuf_SURFACE_STATE(p->dev, &buffers[i], p->cp);
+            p->gen6_SURFACE_STATE(p->dev, surf, false, p->cp);
       }
       else {
          surface_state[i] = 0;
@@ -1123,9 +1140,9 @@ gen6_pipeline_state_samplers(struct ilo_3d_pipeline *p,
                              int shader_type,
                              struct gen6_pipeline_session *session)
 {
-   const struct pipe_sampler_state **samplers =
-      (const struct pipe_sampler_state **) ilo->sampler[shader_type].states;
-   const struct pipe_sampler_view **views =
+   const struct ilo_sampler_cso * const *samplers =
+      ilo->sampler[shader_type].cso;
+   const struct pipe_sampler_view * const *views =
       (const struct pipe_sampler_view **) ilo->view[shader_type].states;
    const int num_samplers = ilo->sampler[shader_type].count;
    const int num_views = ilo->view[shader_type].count;
@@ -1177,7 +1194,7 @@ gen6_pipeline_state_samplers(struct ilo_3d_pipeline *p,
       for (i = 0; i < num_samplers; i++) {
          border_color_state[i] = (samplers[i]) ?
             p->gen6_SAMPLER_BORDER_COLOR_STATE(p->dev,
-                  &samplers[i]->border_color, p->cp) : 0;
+                  samplers[i], p->cp) : 0;
       }
    }
 
@@ -1299,14 +1316,27 @@ gen6_pipeline_prepare(const struct ilo_3d_pipeline *p,
 
    if (session->hw_ctx_changed) {
       /* these should be enough to make everything uploaded */
+      session->batch_bo_changed = true;
       session->state_bo_changed = true;
-      session->instruction_bo_changed = true;
+      session->kernel_bo_changed = true;
       session->prim_changed = true;
    }
    else {
+      /*
+       * Any state that involves resources needs to be re-emitted when the
+       * batch bo changed.  This is because we do not pin the resources and
+       * their offsets (or existence) may change between batch buffers.
+       *
+       * Since we messed around with ILO_3D_PIPELINE_INVALIDATE_BATCH_BO in
+       * handle_invalid_batch_bo(), use ILO_3D_PIPELINE_INVALIDATE_STATE_BO as
+       * a temporary workaround.
+       */
+      session->batch_bo_changed =
+         (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_STATE_BO);
+
       session->state_bo_changed =
          (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_STATE_BO);
-      session->instruction_bo_changed =
+      session->kernel_bo_changed =
          (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
       session->prim_changed = (p->state.reduced_prim != session->reduced_prim);
    }
@@ -1642,9 +1672,7 @@ ilo_3d_pipeline_init_gen6(struct ilo_3d_pipeline *p)
    GEN6_USE(p, DEPTH_STENCIL_STATE, gen6);
    GEN6_USE(p, SCISSOR_RECT, gen6);
    GEN6_USE(p, BINDING_TABLE_STATE, gen6);
-   GEN6_USE(p, surf_SURFACE_STATE, gen6);
-   GEN6_USE(p, view_SURFACE_STATE, gen6);
-   GEN6_USE(p, cbuf_SURFACE_STATE, gen6);
+   GEN6_USE(p, SURFACE_STATE, gen6);
    GEN6_USE(p, so_SURFACE_STATE, gen6);
    GEN6_USE(p, SAMPLER_STATE, gen6);
    GEN6_USE(p, SAMPLER_BORDER_COLOR_STATE, gen6);