Esempio n. 1
0
uint32_t
brw_depthbuffer_format(struct brw_context *brw)
{
   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;

   if (!drb &&
       (srb = intel_get_renderbuffer(fb, BUFFER_STENCIL)) &&
       !srb->mt->stencil_mt &&
       (intel_rb_format(srb) == MESA_FORMAT_Z24_UNORM_S8_UINT ||
	intel_rb_format(srb) == MESA_FORMAT_Z32_FLOAT_S8X24_UINT)) {
      drb = srb;
   }

   if (!drb)
      return BRW_DEPTHFORMAT_D32_FLOAT;

   return brw_depth_format(brw, drb->mt->format);
}
Esempio n. 2
0
/**
 * Emit packets to perform a depth/HiZ resolve or fast depth/stencil clear.
 *
 * See the "Optimized Depth Buffer Clear and/or Stencil Buffer Clear" section
 * of the hardware documentation for details.
 */
void
gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
              unsigned int level, unsigned int layer, enum gen6_hiz_op op)
{
   if (op == GEN6_HIZ_OP_NONE)
      return;

   assert(mt->first_level == 0);
   assert(mt->logical_depth0 >= 1);

   /* The basic algorithm is:
    * - If needed, emit 3DSTATE_{DEPTH,HIER_DEPTH,STENCIL}_BUFFER and
    *   3DSTATE_CLEAR_PARAMS packets to set up the relevant buffers.
    * - If needed, emit 3DSTATE_DRAWING_RECTANGLE.
    * - Emit 3DSTATE_WM_HZ_OP with a bit set for the particular operation.
    * - Do a special PIPE_CONTROL to trigger an implicit rectangle primitive.
    * - Emit 3DSTATE_WM_HZ_OP with no bits set to return to normal rendering.
    */
   emit_depth_packets(brw, mt,
                      brw_depth_format(brw, mt->format),
                      BRW_SURFACE_2D,
                      true, /* depth writes */
                      NULL, false, 0, /* no stencil for now */
                      true, /* hiz */
                      mt->logical_width0,
                      mt->logical_height0,
                      mt->logical_depth0,
                      level,
                      layer); /* min_array_element */

   unsigned rect_width = minify(mt->logical_width0, level);
   unsigned rect_height = minify(mt->logical_height0, level);

   BEGIN_BATCH(4);
   OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2));
   OUT_BATCH(0);
   OUT_BATCH(((rect_width - 1) & 0xffff) | ((rect_height - 1) << 16));
   OUT_BATCH(0);
   ADVANCE_BATCH();

   /* Emit 3DSTATE_WM_HZ_OP to override pipeline state for the particular
    * resolve or clear operation we want to perform.
    */
   uint32_t dw1 = 0;

   switch (op) {
   case GEN6_HIZ_OP_DEPTH_RESOLVE:
      dw1 |= GEN8_WM_HZ_DEPTH_RESOLVE;
      break;
   case GEN6_HIZ_OP_HIZ_RESOLVE:
      dw1 |= GEN8_WM_HZ_HIZ_RESOLVE;
      break;
   case GEN6_HIZ_OP_DEPTH_CLEAR:
      dw1 |= GEN8_WM_HZ_DEPTH_CLEAR;
      break;
   case GEN6_HIZ_OP_NONE:
      assert(!"Should not get here.");
   }

   if (mt->num_samples > 0)
      dw1 |= SET_FIELD(ffs(mt->num_samples) - 1, GEN8_WM_HZ_NUM_SAMPLES);

   BEGIN_BATCH(5);
   OUT_BATCH(_3DSTATE_WM_HZ_OP << 16 | (5 - 2));
   OUT_BATCH(dw1);
   OUT_BATCH(0);
   OUT_BATCH(SET_FIELD(rect_width, GEN8_WM_HZ_CLEAR_RECTANGLE_X_MAX) |
             SET_FIELD(rect_height, GEN8_WM_HZ_CLEAR_RECTANGLE_Y_MAX));
   OUT_BATCH(SET_FIELD(0xFFFF, GEN8_WM_HZ_SAMPLE_MASK));
   ADVANCE_BATCH();

   /* Emit a PIPE_CONTROL with "Post-Sync Operation" set to "Write Immediate
    * Data", and no other bits set.  This causes 3DSTATE_WM_HZ_OP's state to
    * take effect, and spawns a rectangle primitive.
    */
   brw_emit_pipe_control_write(brw,
                               PIPE_CONTROL_WRITE_IMMEDIATE,
                               brw->batch.workaround_bo, 0, 0, 0);

   /* Emit 3DSTATE_WM_HZ_OP again to disable the state overrides. */
   BEGIN_BATCH(5);
   OUT_BATCH(_3DSTATE_WM_HZ_OP << 16 | (5 - 2));
   OUT_BATCH(0);
   OUT_BATCH(0);
   OUT_BATCH(0);
   OUT_BATCH(0);
   ADVANCE_BATCH();

   /* Mark this buffer as needing a TC flush, as we've rendered to it. */
   brw_render_cache_set_add_bo(brw, mt->region->bo);

   /* We've clobbered all of the depth packets, and the drawing rectangle,
    * so we need to ensure those packets are re-emitted before the next
    * primitive.
    *
    * Setting _NEW_DEPTH and _NEW_BUFFERS covers it, but is rather overkill.
    */
   brw->state.dirty.mesa |= _NEW_DEPTH | _NEW_BUFFERS;
}