Mesa (master): ilo: support copying constant buffer 0 to PCB

Chia-I Wu olv at kemper.freedesktop.org
Tue Aug 13 11:25:25 UTC 2013


Module: Mesa
Branch: master
Commit: 5e30ffbda6259c2bbd519c5fe092df1db1d0c94d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5e30ffbda6259c2bbd519c5fe092df1db1d0c94d

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Thu Jul 18 05:58:42 2013 +0800

ilo: support copying constant buffer 0 to PCB

Add ILO_KERNEL_PCB_CBUF0_SIZE so that a kernel can specify how many bytes of
constant buffer 0 need to be copied to PCB.

---

 src/gallium/drivers/ilo/ilo_3d_pipeline.h      |    2 +
 src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c |  100 ++++++++++++++++++++----
 src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c |   18 ++++-
 src/gallium/drivers/ilo/ilo_shader.c           |    3 +
 src/gallium/drivers/ilo/ilo_shader.h           |    1 +
 5 files changed, 105 insertions(+), 19 deletions(-)

diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline.h b/src/gallium/drivers/ilo/ilo_3d_pipeline.h
index ba3a4be..5353ae9 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline.h
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline.h
@@ -125,6 +125,8 @@ struct ilo_3d_pipeline {
          uint32_t SURFACE_STATE[ILO_MAX_WM_SURFACES];
          uint32_t SAMPLER_STATE;
          uint32_t SAMPLER_BORDER_COLOR_STATE[ILO_MAX_SAMPLERS];
+         uint32_t PUSH_CONSTANT_BUFFER;
+         int PUSH_CONSTANT_BUFFER_size;
       } wm;
    } state;
 };
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
index ce1558b..dca4931 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
@@ -653,8 +653,12 @@ gen6_pipeline_wm(struct ilo_3d_pipeline *p,
                  struct gen6_pipeline_session *session)
 {
    /* 3DSTATE_CONSTANT_PS */
-   if (session->pcb_state_fs_changed)
-      gen6_emit_3DSTATE_CONSTANT_PS(p->dev, NULL, NULL, 0, p->cp);
+   if (session->pcb_state_fs_changed) {
+      gen6_emit_3DSTATE_CONSTANT_PS(p->dev,
+            &p->state.wm.PUSH_CONSTANT_BUFFER,
+            &p->state.wm.PUSH_CONSTANT_BUFFER_size,
+            1, p->cp);
+   }
 
    /* 3DSTATE_WM */
    if (DIRTY(FS) || DIRTY(SAMPLER_FS) || DIRTY(BLEND) || DIRTY(DSA) ||
@@ -1189,27 +1193,83 @@ gen6_pipeline_state_pcb(struct ilo_3d_pipeline *p,
                         struct gen6_pipeline_session *session)
 {
    /* push constant buffer for VS */
-   if (DIRTY(VS) || DIRTY(CLIP)) {
+   if (DIRTY(VS) || DIRTY(CBUF) || DIRTY(CLIP)) {
+      const int cbuf0_size = (ilo->vs) ?
+            ilo_shader_get_kernel_param(ilo->vs,
+                  ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
       const int clip_state_size = (ilo->vs) ?
             ilo_shader_get_kernel_param(ilo->vs,
                   ILO_KERNEL_VS_PCB_UCP_SIZE) : 0;
+      const int total_size = cbuf0_size + clip_state_size;
 
-      if (clip_state_size) {
+      if (total_size) {
          void *pcb;
 
-         p->state.vs.PUSH_CONSTANT_BUFFER_size = clip_state_size;
          p->state.vs.PUSH_CONSTANT_BUFFER =
-            gen6_emit_push_constant_buffer(p->dev,
-                  p->state.vs.PUSH_CONSTANT_BUFFER_size, &pcb, p->cp);
+            gen6_emit_push_constant_buffer(p->dev, total_size, &pcb, p->cp);
+         p->state.vs.PUSH_CONSTANT_BUFFER_size = total_size;
+
+         if (cbuf0_size) {
+            const struct ilo_cbuf_state *cbuf =
+               &ilo->cbuf[PIPE_SHADER_VERTEX];
+
+            if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
+               memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
+            }
+            else {
+               memcpy(pcb, cbuf->cso[0].user_buffer,
+                     cbuf->cso[0].user_buffer_size);
+               memset(pcb + cbuf->cso[0].user_buffer_size, 0,
+                     cbuf0_size - cbuf->cso[0].user_buffer_size);
+            }
+
+            pcb += cbuf0_size;
+         }
 
-         memcpy(pcb, &ilo->clip, clip_state_size);
+         if (clip_state_size)
+            memcpy(pcb, &ilo->clip, clip_state_size);
+
+         session->pcb_state_vs_changed = true;
       }
-      else {
-         p->state.vs.PUSH_CONSTANT_BUFFER_size = 0;
+      else if (p->state.vs.PUSH_CONSTANT_BUFFER_size) {
          p->state.vs.PUSH_CONSTANT_BUFFER = 0;
+         p->state.vs.PUSH_CONSTANT_BUFFER_size = 0;
+
+         session->pcb_state_vs_changed = true;
       }
+   }
 
-      session->pcb_state_vs_changed = true;
+   /* push constant buffer for FS */
+   if (DIRTY(FS) || DIRTY(CBUF)) {
+      const int cbuf0_size = (ilo->fs) ?
+         ilo_shader_get_kernel_param(ilo->fs, ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
+
+      if (cbuf0_size) {
+         const struct ilo_cbuf_state *cbuf = &ilo->cbuf[PIPE_SHADER_FRAGMENT];
+         void *pcb;
+
+         p->state.wm.PUSH_CONSTANT_BUFFER =
+            gen6_emit_push_constant_buffer(p->dev, cbuf0_size, &pcb, p->cp);
+         p->state.wm.PUSH_CONSTANT_BUFFER_size = cbuf0_size;
+
+         if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
+            memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
+         }
+         else {
+            memcpy(pcb, cbuf->cso[0].user_buffer,
+                  cbuf->cso[0].user_buffer_size);
+            memset(pcb + cbuf->cso[0].user_buffer_size, 0,
+                  cbuf0_size - cbuf->cso[0].user_buffer_size);
+         }
+
+         session->pcb_state_fs_changed = true;
+      }
+      else if (p->state.wm.PUSH_CONSTANT_BUFFER_size) {
+         p->state.wm.PUSH_CONSTANT_BUFFER = 0;
+         p->state.wm.PUSH_CONSTANT_BUFFER_size = 0;
+
+         session->pcb_state_fs_changed = true;
+      }
    }
 }
 
@@ -1551,13 +1611,23 @@ gen6_pipeline_estimate_states(const struct ilo_3d_pipeline *p,
    }
 
    /* pcb (vs) */
-   if (ilo->vs &&
-       ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE)) {
-      const int pcb_size =
+   if (ilo->vs) {
+      const int cbuf0_size =
+         ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_PCB_CBUF0_SIZE);
+      const int ucp_size =
          ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE);
 
       size += ilo_gpe_gen6_estimate_state_size(p->dev,
-            ILO_GPE_GEN6_PUSH_CONSTANT_BUFFER, pcb_size);
+            ILO_GPE_GEN6_PUSH_CONSTANT_BUFFER, cbuf0_size + ucp_size);
+   }
+
+   /* pcb (fs) */
+   if (ilo->fs) {
+      const int cbuf0_size =
+         ilo_shader_get_kernel_param(ilo->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
+
+      size += ilo_gpe_gen6_estimate_state_size(p->dev,
+            ILO_GPE_GEN6_PUSH_CONSTANT_BUFFER, cbuf0_size);
    }
 
    return size;
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
index b489624..b395f9b 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
@@ -754,13 +754,23 @@ gen7_pipeline_estimate_states(const struct ilo_3d_pipeline *p,
    }
 
    /* pcb (vs) */
-   if (ilo->vs &&
-       ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE)) {
-      const int pcb_size =
+   if (ilo->vs) {
+      const int cbuf0_size =
+         ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_PCB_CBUF0_SIZE);
+      const int ucp_size =
          ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE);
 
       size += ilo_gpe_gen7_estimate_state_size(p->dev,
-            ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, pcb_size);
+            ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, cbuf0_size + ucp_size);
+   }
+
+   /* pcb (fs) */
+   if (ilo->fs) {
+      const int cbuf0_size =
+         ilo_shader_get_kernel_param(ilo->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
+
+      size += ilo_gpe_gen7_estimate_state_size(p->dev,
+            ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, cbuf0_size);
    }
 
    return size;
diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c
index 0db0396..b1a11a1 100644
--- a/src/gallium/drivers/ilo/ilo_shader.c
+++ b/src/gallium/drivers/ilo/ilo_shader.c
@@ -1063,6 +1063,9 @@ ilo_shader_get_kernel_param(const struct ilo_shader_state *shader,
    case ILO_KERNEL_SKIP_CBUF0_UPLOAD:
       val = false;
       break;
+   case ILO_KERNEL_PCB_CBUF0_SIZE:
+      val = 0;
+      break;
 
    case ILO_KERNEL_VS_INPUT_INSTANCEID:
       val = shader->info.has_instanceid;
diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h
index 67f190c..d12b086 100644
--- a/src/gallium/drivers/ilo/ilo_shader.h
+++ b/src/gallium/drivers/ilo/ilo_shader.h
@@ -35,6 +35,7 @@ enum ilo_kernel_param {
    ILO_KERNEL_OUTPUT_COUNT,
    ILO_KERNEL_URB_DATA_START_REG,
    ILO_KERNEL_SKIP_CBUF0_UPLOAD,
+   ILO_KERNEL_PCB_CBUF0_SIZE,
 
    ILO_KERNEL_VS_INPUT_INSTANCEID,
    ILO_KERNEL_VS_INPUT_VERTEXID,




More information about the mesa-commit mailing list