i965/fs: Add support for translating ir_triop_fma into MAD.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_misc_state.c
index 37175204f0364ec1d65c4fb51f1f2d567293a0f4..ac7f1f414fef018b61785e8308b32dbd840ddae8 100644 (file)
@@ -46,8 +46,7 @@
 /* Constant single cliprect for framebuffer object or DRI2 drawing */
 static void upload_drawing_rect(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &intel->ctx;
+   struct gl_context *ctx = &brw->ctx;
 
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2));
@@ -141,9 +140,7 @@ const struct brw_tracked_state gen6_binding_table_pointers = {
  */
 static void upload_pipelined_state_pointers(struct brw_context *brw )
 {
-   struct intel_context *intel = &brw->intel;
-
-   if (intel->gen == 5) {
+   if (brw->gen == 5) {
       /* Need to flush before changing clip max threads for errata. */
       BEGIN_BATCH(1);
       OUT_BATCH(MI_FLUSH);
@@ -199,8 +196,7 @@ const struct brw_tracked_state brw_psp_urb_cbs = {
 uint32_t
 brw_depthbuffer_format(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &intel->ctx;
+   struct gl_context *ctx = &brw->ctx;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct intel_renderbuffer *drb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
    struct intel_renderbuffer *srb;
@@ -222,7 +218,7 @@ brw_depthbuffer_format(struct brw_context *brw)
    case MESA_FORMAT_Z32_FLOAT:
       return BRW_DEPTHFORMAT_D32_FLOAT;
    case MESA_FORMAT_X8_Z24:
-      if (intel->gen >= 6) {
+      if (brw->gen >= 6) {
         return BRW_DEPTHFORMAT_D24_UNORM_X8_UINT;
       } else {
         /* Use D24_UNORM_S8, not D24_UNORM_X8.
@@ -329,8 +325,7 @@ void
 brw_workaround_depthstencil_alignment(struct brw_context *brw,
                                       GLbitfield clear_mask)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &intel->ctx;
+   struct gl_context *ctx = &brw->ctx;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    bool rebase_depth = false;
    bool rebase_stencil = false;
@@ -346,6 +341,26 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
    if (depth_irb)
       depth_mt = depth_irb->mt;
 
+   /* Initialize brw->depthstencil to 'nop' workaround state.
+    */
+   brw->depthstencil.tile_x = 0;
+   brw->depthstencil.tile_y = 0;
+   brw->depthstencil.depth_offset = 0;
+   brw->depthstencil.stencil_offset = 0;
+   brw->depthstencil.hiz_offset = 0;
+   brw->depthstencil.depth_mt = NULL;
+   brw->depthstencil.stencil_mt = NULL;
+   if (depth_irb)
+      brw->depthstencil.depth_mt = depth_mt;
+   if (stencil_irb)
+      brw->depthstencil.stencil_mt = get_stencil_miptree(stencil_irb);
+
+   /* Gen7+ doesn't require the workarounds, since we always program the
+    * surface state at the start of the whole surface.
+    */
+   if (brw->gen >= 7)
+      return;
+
    /* Check if depth buffer is in depth/stencil format.  If so, then it's only
     * safe to invalidate it if we're also clearing stencil, and both depth_irb
     * and stencil_irb point to the same miptree.
@@ -385,7 +400,7 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
          rebase_depth = true;
 
       /* We didn't even have intra-tile offsets before g45. */
-      if (intel->gen == 4 && !brw->is_g4x) {
+      if (brw->gen == 4 && !brw->is_g4x) {
          if (tile_x || tile_y)
             rebase_depth = true;
       }
@@ -444,7 +459,7 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
       if (stencil_tile_x & 7 || stencil_tile_y & 7)
          rebase_stencil = true;
 
-      if (intel->gen == 4 && !brw->is_g4x) {
+      if (brw->gen == 4 && !brw->is_g4x) {
          if (stencil_tile_x || stencil_tile_y)
             rebase_stencil = true;
       }
@@ -520,11 +535,6 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
     */
    brw->depthstencil.tile_x = tile_x;
    brw->depthstencil.tile_y = tile_y;
-   brw->depthstencil.depth_offset = 0;
-   brw->depthstencil.stencil_offset = 0;
-   brw->depthstencil.hiz_offset = 0;
-   brw->depthstencil.depth_mt = NULL;
-   brw->depthstencil.stencil_mt = NULL;
    if (depth_irb) {
       depth_mt = depth_irb->mt;
       brw->depthstencil.depth_mt = depth_mt;
@@ -561,8 +571,7 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw,
 void
 brw_emit_depthbuffer(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &intel->ctx;
+   struct gl_context *ctx = &brw->ctx;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    /* _NEW_BUFFERS */
    struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
@@ -582,7 +591,7 @@ brw_emit_depthbuffer(struct brw_context *brw)
       separate_stencil = stencil_mt->format == MESA_FORMAT_S8;
 
       /* Gen7 supports only separate stencil */
-      assert(separate_stencil || intel->gen < 7);
+      assert(separate_stencil || brw->gen < 7);
    }
 
    /* If there's a packed depth/stencil bound to stencil only, we need to
@@ -602,14 +611,14 @@ brw_emit_depthbuffer(struct brw_context *brw)
        * set to the same value. Gens after 7 implicitly always set
        * Separate_Stencil_Enable; software cannot disable it.
        */
-      if ((intel->gen < 7 && hiz) || intel->gen >= 7) {
+      if ((brw->gen < 7 && hiz) || brw->gen >= 7) {
          assert(!_mesa_is_format_packed_depth_stencil(depth_mt->format));
       }
 
       /* Prior to Gen7, if using separate stencil, hiz must be enabled. */
-      assert(intel->gen >= 7 || !separate_stencil || hiz);
+      assert(brw->gen >= 7 || !separate_stencil || hiz);
 
-      assert(intel->gen < 6 || depth_mt->region->tiling == I915_TILING_Y);
+      assert(brw->gen < 6 || depth_mt->region->tiling == I915_TILING_Y);
       assert(!hiz || depth_mt->region->tiling == I915_TILING_Y);
 
       depthbuffer_format = brw_depthbuffer_format(brw);
@@ -652,8 +661,6 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
                            uint32_t width, uint32_t height,
                            uint32_t tile_x, uint32_t tile_y)
 {
-   struct intel_context *intel = &brw->intel;
-
    /* Enable the hiz bit if we're doing separate stencil, because it and the
     * separate stencil bit must have the same value. From Section 2.11.5.6.1.1
     * 3DSTATE_DEPTH_BUFFER, Bit 1.21 "Separate Stencil Enable":
@@ -669,15 +676,15 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
    /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both
     * non-pipelined state that will need the PIPE_CONTROL workaround.
     */
-   if (intel->gen == 6) {
+   if (brw->gen == 6) {
       intel_emit_post_sync_nonzero_flush(brw);
       intel_emit_depth_stall_flushes(brw);
    }
 
    unsigned int len;
-   if (intel->gen >= 6)
+   if (brw->gen >= 6)
       len = 7;
-   else if (brw->is_g4x || intel->gen == 5)
+   else if (brw->is_g4x || brw->gen == 5)
       len = 6;
    else
       len = 5;
@@ -705,12 +712,12 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
              ((height + tile_y - 1) << 19));
    OUT_BATCH(0);
 
-   if (brw->is_g4x || intel->gen >= 5)
+   if (brw->is_g4x || brw->gen >= 5)
       OUT_BATCH(tile_x | (tile_y << 16));
    else
       assert(tile_x == 0 && tile_y == 0);
 
-   if (intel->gen >= 6)
+   if (brw->gen >= 6)
       OUT_BATCH(0);
 
    ADVANCE_BATCH();
@@ -775,8 +782,8 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
     *     3DSTATE_CLEAR_PARAMS packet must follow the DEPTH_BUFFER_STATE packet
     *     when HiZ is enabled and the DEPTH_BUFFER_STATE changes.
     */
-   if (intel->gen >= 6 || hiz) {
-      if (intel->gen == 6)
+   if (brw->gen >= 6 || hiz) {
+      if (brw->gen == 6)
         intel_emit_post_sync_nonzero_flush(brw);
 
       BEGIN_BATCH(2);
@@ -805,15 +812,14 @@ const struct brw_tracked_state brw_depthbuffer = {
 
 static void upload_polygon_stipple(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &brw->intel.ctx;
+   struct gl_context *ctx = &brw->ctx;
    GLuint i;
 
    /* _NEW_POLYGON */
    if (!ctx->Polygon.StippleFlag)
       return;
 
-   if (intel->gen == 6)
+   if (brw->gen == 6)
       intel_emit_post_sync_nonzero_flush(brw);
 
    BEGIN_BATCH(33);
@@ -854,14 +860,13 @@ const struct brw_tracked_state brw_polygon_stipple = {
 
 static void upload_polygon_stipple_offset(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &brw->intel.ctx;
+   struct gl_context *ctx = &brw->ctx;
 
    /* _NEW_POLYGON */
    if (!ctx->Polygon.StippleFlag)
       return;
 
-   if (intel->gen == 6)
+   if (brw->gen == 6)
       intel_emit_post_sync_nonzero_flush(brw);
 
    BEGIN_BATCH(2);
@@ -897,13 +902,12 @@ const struct brw_tracked_state brw_polygon_stipple_offset = {
  */
 static void upload_aa_line_parameters(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &brw->intel.ctx;
+   struct gl_context *ctx = &brw->ctx;
 
    if (!ctx->Line.SmoothFlag || !brw->has_aa_line_parameters)
       return;
 
-   if (intel->gen == 6)
+   if (brw->gen == 6)
       intel_emit_post_sync_nonzero_flush(brw);
 
    OUT_BATCH(_3DSTATE_AA_LINE_PARAMETERS << 16 | (3 - 2));
@@ -928,22 +932,21 @@ const struct brw_tracked_state brw_aa_line_parameters = {
 
 static void upload_line_stipple(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-   struct gl_context *ctx = &brw->intel.ctx;
+   struct gl_context *ctx = &brw->ctx;
    GLfloat tmp;
    GLint tmpi;
 
    if (!ctx->Line.StippleFlag)
       return;
 
-   if (intel->gen == 6)
+   if (brw->gen == 6)
       intel_emit_post_sync_nonzero_flush(brw);
 
    BEGIN_BATCH(3);
    OUT_BATCH(_3DSTATE_LINE_STIPPLE_PATTERN << 16 | (3 - 2));
    OUT_BATCH(ctx->Line.StipplePattern);
 
-   if (intel->gen >= 7) {
+   if (brw->gen >= 7) {
       /* in U1.16 */
       tmp = 1.0 / (GLfloat) ctx->Line.StippleFactor;
       tmpi = tmp * (1<<16);
@@ -976,10 +979,8 @@ const struct brw_tracked_state brw_line_stipple = {
 void
 brw_upload_invariant_state(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
-
    /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */
-   if (intel->gen == 6)
+   if (brw->gen == 6)
       intel_emit_post_sync_nonzero_flush(brw);
 
    /* Select the 3D pipeline (as opposed to media) */
@@ -987,7 +988,7 @@ brw_upload_invariant_state(struct brw_context *brw)
    OUT_BATCH(brw->CMD_PIPELINE_SELECT << 16 | 0);
    ADVANCE_BATCH();
 
-   if (intel->gen < 6) {
+   if (brw->gen < 6) {
       /* Disable depth offset clamping. */
       BEGIN_BATCH(2);
       OUT_BATCH(_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP << 16 | (2 - 2));
@@ -1027,8 +1028,6 @@ const struct brw_tracked_state brw_invariant_state = {
  */
 static void upload_state_base_address( struct brw_context *brw )
 {
-   struct intel_context *intel = &brw->intel;
-
    /* FINISHME: According to section 3.6.1 "STATE_BASE_ADDRESS" of
     * vol1a of the G45 PRM, MI_FLUSH with the ISC invalidate should be
     * programmed prior to STATE_BASE_ADDRESS.
@@ -1038,14 +1037,17 @@ static void upload_state_base_address( struct brw_context *brw )
     * maybe this isn't required for us in particular.
     */
 
-   if (intel->gen >= 6) {
-      if (intel->gen == 6)
+   if (brw->gen >= 6) {
+      uint8_t mocs = brw->gen == 7 ? GEN7_MOCS_L3 : 0;
+
+      if (brw->gen == 6)
         intel_emit_post_sync_nonzero_flush(brw);
 
        BEGIN_BATCH(10);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2));
-       /* General state base address: stateless DP read/write requests */
-       OUT_BATCH(1);
+       OUT_BATCH(mocs << 8 | /* General State Memory Object Control State */
+                 mocs << 4 | /* Stateless Data Port Access Memory Object Control State */
+                 1); /* General State Base Address Modify Enable */
        /* Surface state base address:
        * BINDING_TABLE_STATE
        * SURFACE_STATE
@@ -1078,7 +1080,7 @@ static void upload_state_base_address( struct brw_context *brw )
        OUT_BATCH(1); /* Indirect object upper bound */
        OUT_BATCH(1); /* Instruction access upper bound */
        ADVANCE_BATCH();
-   } else if (intel->gen == 5) {
+   } else if (brw->gen == 5) {
        BEGIN_BATCH(8);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
        OUT_BATCH(1); /* General state base address */