i965: Convert upload_default_color to genxml.
authorRafael Antognolli <rafael.antognolli@intel.com>
Tue, 30 May 2017 22:08:18 +0000 (15:08 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Thu, 22 Jun 2017 23:51:51 +0000 (16:51 -0700)
This function was moved to genX_state_upload.c but was still not using genxml.
By converting it to genxml, we make some things simpler, like setting
haswell's border color state, but others are more complex, since the structs
used by each gen are different.

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/mesa/drivers/dri/i965/genX_state_upload.c

index 64e34e5737ba206047620bb2b5bc8c9935459435..3f8a7265db9b052377535a199607dab27e5b5d6f 100644 (file)
@@ -4249,7 +4249,7 @@ genX(emit_sampler_state_pointers_xs)(struct brw_context *brw,
 #endif
 }
 
-static bool
+UNUSED static bool
 has_component(mesa_format format, int i)
 {
    if (_mesa_is_format_color_format(format))
@@ -4263,11 +4263,11 @@ has_component(mesa_format format, int i)
  * Upload SAMPLER_BORDER_COLOR_STATE.
  */
 static void
-upload_default_color(struct brw_context *brw,
-                     const struct gl_sampler_object *sampler,
-                     mesa_format format, GLenum base_format,
-                     bool is_integer_format, bool is_stencil_sampling,
-                     uint32_t *sdc_offset)
+genX(upload_default_color)(struct brw_context *brw,
+                           const struct gl_sampler_object *sampler,
+                           mesa_format format, GLenum base_format,
+                           bool is_integer_format, bool is_stencil_sampling,
+                           uint32_t *sdc_offset)
 {
    union gl_color_union color;
 
@@ -4321,27 +4321,49 @@ upload_default_color(struct brw_context *brw,
    if (base_format == GL_RGB)
       color.ui[3] = float_as_int(1.0);
 
+   int alignment = 32;
    if (brw->gen >= 8) {
-      /* On Broadwell, the border color is represented as four 32-bit floats,
-       * integers, or unsigned values, interpreted according to the surface
-       * format.  This matches the sampler->BorderColor union exactly; just
-       * memcpy the values.
-       */
-      uint32_t *sdc = brw_state_batch(brw, 4 * 4, 64, sdc_offset);
-      memcpy(sdc, color.ui, 4 * 4);
+      alignment = 64;
    } else if (brw->is_haswell && (is_integer_format || is_stencil_sampling)) {
-      /* Haswell's integer border color support is completely insane:
-       * SAMPLER_BORDER_COLOR_STATE is 20 DWords.  The first four are
-       * for float colors.  The next 12 DWords are MBZ and only exist to
-       * pad it out to a 64 byte cacheline boundary.  DWords 16-19 then
-       * contain integer colors; these are only used if SURFACE_STATE
-       * has the "Integer Surface Format" bit set.  Even then, the
-       * arrangement of the RGBA data devolves into madness.
-       */
-      uint32_t *sdc = brw_state_batch(brw, 20 * 4, 512, sdc_offset);
-      memset(sdc, 0, 20 * 4);
-      sdc = &sdc[16];
+      alignment = 512;
+   }
+
+   uint32_t *sdc = brw_state_batch(
+      brw, GENX(SAMPLER_BORDER_COLOR_STATE_length) * sizeof(uint32_t),
+      alignment, sdc_offset);
+
+   struct GENX(SAMPLER_BORDER_COLOR_STATE) state = { 0 };
+
+#define ASSIGN(dst, src) \
+   do {                  \
+      dst = src;         \
+   } while (0)
+
+#define ASSIGNu16(dst, src) \
+   do {                     \
+      dst = (uint16_t)src;  \
+   } while (0)
+
+#define ASSIGNu8(dst, src) \
+   do {                    \
+      dst = (uint8_t)src;  \
+   } while (0)
 
+#define BORDER_COLOR_ATTR(macro, _color_type, src)              \
+   macro(state.BorderColor ## _color_type ## Red, src[0]);   \
+   macro(state.BorderColor ## _color_type ## Green, src[1]);   \
+   macro(state.BorderColor ## _color_type ## Blue, src[2]);   \
+   macro(state.BorderColor ## _color_type ## Alpha, src[3]);
+
+#if GEN_GEN >= 8
+   /* On Broadwell, the border color is represented as four 32-bit floats,
+    * integers, or unsigned values, interpreted according to the surface
+    * format.  This matches the sampler->BorderColor union exactly; just
+    * memcpy the values.
+    */
+   BORDER_COLOR_ATTR(ASSIGN, 32bit, color.ui);
+#elif GEN_IS_HASWELL
+   if (is_integer_format || is_stencil_sampling) {
       bool stencil = format == MESA_FORMAT_S_UINT8 || is_stencil_sampling;
       const int bits_per_channel =
          _mesa_get_format_bits(format, stencil ? GL_STENCIL_BITS : GL_RED_BITS);
@@ -4361,76 +4383,61 @@ upload_default_color(struct brw_context *brw,
       switch (bits_per_channel) {
       case 8:
          /* Copy RGBA in order. */
-         for (int i = 0; i < 4; i++)
-            ((uint8_t *) sdc)[i] = c[i];
+         BORDER_COLOR_ATTR(ASSIGNu8, 8bit, c);
          break;
       case 10:
          /* R10G10B10A2_UINT is treated like a 16-bit format. */
       case 16:
-         ((uint16_t *) sdc)[0] = c[0]; /* R -> DWord 0, bits 15:0  */
-         ((uint16_t *) sdc)[1] = c[1]; /* G -> DWord 0, bits 31:16 */
-         /* DWord 1 is Reserved/MBZ! */
-         ((uint16_t *) sdc)[4] = c[2]; /* B -> DWord 2, bits 15:0  */
-         ((uint16_t *) sdc)[5] = c[3]; /* A -> DWord 3, bits 31:16 */
+         BORDER_COLOR_ATTR(ASSIGNu16, 16bit, c);
          break;
       case 32:
          if (base_format == GL_RG) {
             /* Careful inspection of the tables reveals that for RG32 formats,
              * the green channel needs to go where blue normally belongs.
              */
-            sdc[0] = c[0];
-            sdc[2] = c[1];
-            sdc[3] = 1;
+            state.BorderColor32bitRed = c[0];
+            state.BorderColor32bitBlue = c[1];
+            state.BorderColor32bitAlpha = 1;
          } else {
             /* Copy RGBA in order. */
-            for (int i = 0; i < 4; i++)
-               sdc[i] = c[i];
+            BORDER_COLOR_ATTR(ASSIGN, 32bit, c);
          }
          break;
       default:
          assert(!"Invalid number of bits per channel in integer format.");
          break;
       }
-   } else if (brw->gen == 5 || brw->gen == 6) {
-      struct gen5_sampler_default_color *sdc;
-
-      sdc = brw_state_batch(brw, sizeof(*sdc), 32, sdc_offset);
-
-      memset(sdc, 0, sizeof(*sdc));
-
-      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color.f[0]);
-      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color.f[1]);
-      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color.f[2]);
-      UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color.f[3]);
-
-      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color.f[0]);
-      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color.f[1]);
-      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color.f[2]);
-      UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color.f[3]);
-
-      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color.f[0]);
-      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color.f[1]);
-      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color.f[2]);
-      UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color.f[3]);
-
-      sdc->hf[0] = _mesa_float_to_half(color.f[0]);
-      sdc->hf[1] = _mesa_float_to_half(color.f[1]);
-      sdc->hf[2] = _mesa_float_to_half(color.f[2]);
-      sdc->hf[3] = _mesa_float_to_half(color.f[3]);
-
-      sdc->b[0] = sdc->s[0] >> 8;
-      sdc->b[1] = sdc->s[1] >> 8;
-      sdc->b[2] = sdc->s[2] >> 8;
-      sdc->b[3] = sdc->s[3] >> 8;
-
-      sdc->f[0] = color.f[0];
-      sdc->f[1] = color.f[1];
-      sdc->f[2] = color.f[2];
-      sdc->f[3] = color.f[3];
    } else {
-      float *sdc = brw_state_batch(brw, 4 * 4, 32, sdc_offset);
-      memcpy(sdc, color.f, 4 * 4);
+      BORDER_COLOR_ATTR(ASSIGN, Float, color.f);
    }
+#elif GEN_GEN == 5 || GEN_GEN == 6
+   BORDER_COLOR_ATTR(UNCLAMPED_FLOAT_TO_UBYTE, Unorm, color.f);
+   BORDER_COLOR_ATTR(UNCLAMPED_FLOAT_TO_USHORT, Unorm16, color.f);
+   BORDER_COLOR_ATTR(UNCLAMPED_FLOAT_TO_SHORT, Snorm16, color.f);
+
+#define MESA_FLOAT_TO_HALF(dst, src) \
+   dst = _mesa_float_to_half(src);
+
+   BORDER_COLOR_ATTR(MESA_FLOAT_TO_HALF, Float16, color.f);
+
+#undef MESA_FLOAT_TO_HALF
+
+   state.BorderColorSnorm8Red   = state.BorderColorSnorm16Red >> 8;
+   state.BorderColorSnorm8Green = state.BorderColorSnorm16Green >> 8;
+   state.BorderColorSnorm8Blue  = state.BorderColorSnorm16Blue >> 8;
+   state.BorderColorSnorm8Alpha = state.BorderColorSnorm16Alpha >> 8;
+
+   BORDER_COLOR_ATTR(ASSIGN, Float, color.f);
+#elif GEN_GEN == 4
+   BORDER_COLOR_ATTR(ASSIGN, , color.f);
+#else
+   BORDER_COLOR_ATTR(ASSIGN, Float, color.f);
+#endif
+
+#undef ASSIGN
+#undef BORDER_COLOR_ATTR
+
+   GENX(SAMPLER_BORDER_COLOR_STATE_pack)(brw, sdc, &state);
 }
 
 static uint32_t
@@ -4639,9 +4646,10 @@ genX(update_sampler_state)(struct brw_context *brw,
    if (wrap_mode_needs_border_color(wrap_s) ||
        wrap_mode_needs_border_color(wrap_t) ||
        wrap_mode_needs_border_color(wrap_r)) {
-      upload_default_color(brw, sampler, format, base_format,
-                           texObj->_IsIntegerFormat, texObj->StencilSampling,
-                           &border_color_offset);
+      genX(upload_default_color)(brw, sampler, format, base_format,
+                                 texObj->_IsIntegerFormat,
+                                 texObj->StencilSampling,
+                                 &border_color_offset);
    }
 
    samp_st.BorderColorPointer = border_color_offset;