[Mesa-dev,13/37] i965/gen6/gs: Implement GS_OPCODE_SET_DWORD_2.

Submitted by Iago Toral Quiroga on Aug. 14, 2014, 11:11 a.m.

Details

Message ID 1408014729-12708-14-git-send-email-itoral@igalia.com
State Accepted
Headers show

Not browsing as part of any series.

Commit Message

Iago Toral Quiroga Aug. 14, 2014, 11:11 a.m.
We have GS_OPCODE_SET_DWORD_2_IMMED but this requires its source argument to be
an immediate. In gen6 we need to set dword 2 of the URB write message header
from values stored in separate register, so we need something more flexible.
---
 src/mesa/drivers/dri/i965/brw_defines.h          |  8 ++++++++
 src/mesa/drivers/dri/i965/brw_shader.cpp         |  2 ++
 src/mesa/drivers/dri/i965/brw_vec4.h             |  1 +
 src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 15 +++++++++++++++
 4 files changed, 26 insertions(+)

Patch hide | download patch | download mbox

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index a2b40fb..f6bdaeb 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -979,6 +979,14 @@  enum opcode {
    GS_OPCODE_SET_DWORD_2_IMMED,
 
    /**
+    * Same as above but can take the DWORD 2 value from any general purpose
+    * register, not necessarily an immediate. Used by geometry shaders in gen6
+    * which need to set DWORD 2 of the URB write message header with vertex
+    * flags that we have buffered in a separate register.
+    */
+   GS_OPCODE_SET_DWORD_2,
+
+   /**
     * Prepare the dst register for storage in the "Channel Mask" fields of a
     * URB_WRITE message header.
     *
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 69d16a7..b927601 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -524,6 +524,8 @@  brw_instruction_name(enum opcode op)
       return "set_vertex_count";
    case GS_OPCODE_SET_DWORD_2_IMMED:
       return "set_dword_2_immed";
+   case GS_OPCODE_SET_DWORD_2:
+      return "set_dword_2";
    case GS_OPCODE_PREPARE_CHANNEL_MASKS:
       return "prepare_channel_masks";
    case GS_OPCODE_SET_CHANNEL_MASKS:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index c1daf54..5403f5a 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -657,6 +657,7 @@  private:
    void generate_gs_set_vertex_count(struct brw_reg dst,
                                      struct brw_reg src);
    void generate_gs_set_dword_2_immed(struct brw_reg dst, struct brw_reg src);
+   void generate_gs_set_dword_2(struct brw_reg dst, struct brw_reg src);
    void generate_gs_prepare_channel_masks(struct brw_reg dst);
    void generate_gs_set_channel_masks(struct brw_reg dst, struct brw_reg src);
    void generate_gs_get_instance_id(struct brw_reg dst);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
index 9cb47b2..2bf2b67 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
@@ -550,6 +550,17 @@  vec4_generator::generate_gs_set_dword_2_immed(struct brw_reg dst,
 }
 
 void
+vec4_generator::generate_gs_set_dword_2(struct brw_reg dst, struct brw_reg src)
+{
+   brw_push_insn_state(p);
+   brw_set_default_access_mode(p, BRW_ALIGN_1);
+   brw_set_default_mask_control(p, BRW_MASK_DISABLE);
+   brw_MOV(p, suboffset(vec1(dst), 2), suboffset(vec1(src), 0));
+   brw_set_default_access_mode(p, BRW_ALIGN_16);
+   brw_pop_insn_state(p);
+}
+
+void
 vec4_generator::generate_gs_prepare_channel_masks(struct brw_reg dst)
 {
    /* We want to left shift just DWORD 4 (the x component belonging to the
@@ -1252,6 +1263,10 @@  vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
       generate_gs_set_dword_2_immed(dst, src[0]);
       break;
 
+   case GS_OPCODE_SET_DWORD_2:
+      generate_gs_set_dword_2(dst, src[0]);
+      break;
+
    case GS_OPCODE_PREPARE_CHANNEL_MASKS:
       generate_gs_prepare_channel_masks(dst);
       break;

Comments

On Thursday, August 14, 2014 01:11:45 PM Iago Toral Quiroga wrote:
> We have GS_OPCODE_SET_DWORD_2_IMMED but this requires its source argument to be
> an immediate. In gen6 we need to set dword 2 of the URB write message header
> from values stored in separate register, so we need something more flexible.
> ---
>  src/mesa/drivers/dri/i965/brw_defines.h          |  8 ++++++++
>  src/mesa/drivers/dri/i965/brw_shader.cpp         |  2 ++
>  src/mesa/drivers/dri/i965/brw_vec4.h             |  1 +
>  src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 15 +++++++++++++++
>  4 files changed, 26 insertions(+)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
> index a2b40fb..f6bdaeb 100644
> --- a/src/mesa/drivers/dri/i965/brw_defines.h
> +++ b/src/mesa/drivers/dri/i965/brw_defines.h
> @@ -979,6 +979,14 @@ enum opcode {
>     GS_OPCODE_SET_DWORD_2_IMMED,
>  
>     /**
> +    * Same as above but can take the DWORD 2 value from any general purpose
> +    * register, not necessarily an immediate. Used by geometry shaders in gen6
> +    * which need to set DWORD 2 of the URB write message header with vertex
> +    * flags that we have buffered in a separate register.
> +    */
> +   GS_OPCODE_SET_DWORD_2,
> +
> +   /**
>      * Prepare the dst register for storage in the "Channel Mask" fields of a
>      * URB_WRITE message header.
>      *
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
> index 69d16a7..b927601 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> @@ -524,6 +524,8 @@ brw_instruction_name(enum opcode op)
>        return "set_vertex_count";
>     case GS_OPCODE_SET_DWORD_2_IMMED:
>        return "set_dword_2_immed";
> +   case GS_OPCODE_SET_DWORD_2:
> +      return "set_dword_2";
>     case GS_OPCODE_PREPARE_CHANNEL_MASKS:
>        return "prepare_channel_masks";
>     case GS_OPCODE_SET_CHANNEL_MASKS:
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
> index c1daf54..5403f5a 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.h
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.h
> @@ -657,6 +657,7 @@ private:
>     void generate_gs_set_vertex_count(struct brw_reg dst,
>                                       struct brw_reg src);
>     void generate_gs_set_dword_2_immed(struct brw_reg dst, struct brw_reg src);
> +   void generate_gs_set_dword_2(struct brw_reg dst, struct brw_reg src);
>     void generate_gs_prepare_channel_masks(struct brw_reg dst);
>     void generate_gs_set_channel_masks(struct brw_reg dst, struct brw_reg src);
>     void generate_gs_get_instance_id(struct brw_reg dst);
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> index 9cb47b2..2bf2b67 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> @@ -550,6 +550,17 @@ vec4_generator::generate_gs_set_dword_2_immed(struct brw_reg dst,
>  }
>  
>  void
> +vec4_generator::generate_gs_set_dword_2(struct brw_reg dst, struct brw_reg src)
> +{
> +   brw_push_insn_state(p);
> +   brw_set_default_access_mode(p, BRW_ALIGN_1);
> +   brw_set_default_mask_control(p, BRW_MASK_DISABLE);
> +   brw_MOV(p, suboffset(vec1(dst), 2), suboffset(vec1(src), 0));
> +   brw_set_default_access_mode(p, BRW_ALIGN_16);
> +   brw_pop_insn_state(p);
> +}
> +
> +void
>  vec4_generator::generate_gs_prepare_channel_masks(struct brw_reg dst)
>  {
>     /* We want to left shift just DWORD 4 (the x component belonging to the
> @@ -1252,6 +1263,10 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction,
>        generate_gs_set_dword_2_immed(dst, src[0]);
>        break;
>  
> +   case GS_OPCODE_SET_DWORD_2:
> +      generate_gs_set_dword_2(dst, src[0]);
> +      break;
> +
>     case GS_OPCODE_PREPARE_CHANNEL_MASKS:
>        generate_gs_prepare_channel_masks(dst);
>        break;

It seems like we should just replace GS_OPCODE_SET_DWORD_2_IMMED with your new GS_OPCODE_SET_DWORD_2 opcode.  It's strictly more powerful, and the IMMED version doesn't take advantage of it being an immediate at all...it's just that Paul didn't need anything fancier at the time.