예제 #1
0
/**
 * \brief Execute a blit or render pass operation.
 *
 * To execute the operation, this function manually constructs and emits a
 * batch to draw a rectangle primitive. The batchbuffer is flushed before
 * constructing and after emitting the batch.
 *
 * This function alters no GL state.
 */
void
gen6_blorp_exec(struct brw_context *brw,
                const struct brw_blorp_params *params)
{
   uint32_t cc_blend_state_offset = 0;
   uint32_t cc_state_offset = 0;
   uint32_t depthstencil_offset;
   uint32_t wm_push_const_offset = 0;
   uint32_t wm_bind_bo_offset = 0;

   /* Emit workaround flushes when we switch from drawing to blorping. */
   brw_emit_post_sync_nonzero_flush(brw);

   brw_upload_state_base_address(brw);

   gen6_emit_3dstate_multisample(brw, params->dst.num_samples);
   gen6_emit_3dstate_sample_mask(brw,
                                 params->dst.num_samples > 1 ?
                                 (1 << params->dst.num_samples) - 1 : 1);
   gen6_blorp_emit_vertices(brw, params);
   gen6_blorp_emit_urb_config(brw, params);
   if (params->wm_prog_data) {
      cc_blend_state_offset = gen6_blorp_emit_blend_state(brw, params);
      cc_state_offset = gen6_blorp_emit_cc_state(brw);
   }
   depthstencil_offset = gen6_blorp_emit_depth_stencil_state(brw, params);
   gen6_blorp_emit_cc_state_pointers(brw, params, cc_blend_state_offset,
                                     depthstencil_offset, cc_state_offset);
   if (params->wm_prog_data) {
      uint32_t wm_surf_offset_renderbuffer;
      uint32_t wm_surf_offset_texture = 0;
      wm_push_const_offset = gen6_blorp_emit_wm_constants(brw, params);
      intel_miptree_used_for_rendering(params->dst.mt);
      wm_surf_offset_renderbuffer =
         gen6_blorp_emit_surface_state(brw, params, &params->dst,
                                       I915_GEM_DOMAIN_RENDER,
                                       I915_GEM_DOMAIN_RENDER);
      if (params->src.mt) {
         wm_surf_offset_texture =
            gen6_blorp_emit_surface_state(brw, params, &params->src,
                                          I915_GEM_DOMAIN_SAMPLER, 0);
      }
      wm_bind_bo_offset =
         gen6_blorp_emit_binding_table(brw,
                                       wm_surf_offset_renderbuffer,
                                       wm_surf_offset_texture);
   }

   if (params->src.mt) {
      const uint32_t sampler_offset =
         gen6_blorp_emit_sampler_state(brw, BRW_MAPFILTER_LINEAR, 0, true);
      gen6_blorp_emit_sampler_state_pointers(brw, sampler_offset);
   }
   gen6_blorp_emit_vs_disable(brw, params);
   gen6_blorp_emit_gs_disable(brw, params);
   gen6_blorp_emit_clip_disable(brw);
   gen6_blorp_emit_sf_config(brw, params);
   if (params->wm_prog_data)
      gen6_blorp_emit_constant_ps(brw, params, wm_push_const_offset);
   else
      gen6_blorp_emit_constant_ps_disable(brw, params);
   gen6_blorp_emit_wm_config(brw, params);
   if (params->wm_prog_data)
      gen6_blorp_emit_binding_table_pointers(brw, wm_bind_bo_offset);
   gen6_blorp_emit_viewport_state(brw, params);

   if (params->depth.mt)
      gen6_blorp_emit_depth_stencil_config(brw, params);
   else
      gen6_blorp_emit_depth_disable(brw, params);
   gen6_blorp_emit_clear_params(brw, params);
   gen6_blorp_emit_drawing_rectangle(brw, params);
   gen6_blorp_emit_primitive(brw, params);
}
/**
 * \copydoc gen6_blorp_exec()
 */
void
gen7_blorp_exec(struct brw_context *brw,
                const brw_blorp_params *params)
{
   if (brw->gen >= 8)
      return;

   brw_blorp_prog_data *prog_data = NULL;
   uint32_t cc_blend_state_offset = 0;
   uint32_t cc_state_offset = 0;
   uint32_t depthstencil_offset;
   uint32_t wm_push_const_offset = 0;
   uint32_t wm_bind_bo_offset = 0;
   uint32_t sampler_offset = 0;

   uint32_t prog_offset = params->get_wm_prog(brw, &prog_data);
   gen6_emit_3dstate_multisample(brw, params->num_samples);
   gen6_emit_3dstate_sample_mask(brw, params->num_samples, 1.0, false, ~0u);
   gen6_blorp_emit_state_base_address(brw, params);
   gen6_blorp_emit_vertices(brw, params);
   gen7_blorp_emit_urb_config(brw, params);
   if (params->use_wm_prog) {
      cc_blend_state_offset = gen6_blorp_emit_blend_state(brw, params);
      cc_state_offset = gen6_blorp_emit_cc_state(brw, params);
      gen7_blorp_emit_blend_state_pointer(brw, params, cc_blend_state_offset);
      gen7_blorp_emit_cc_state_pointer(brw, params, cc_state_offset);
   }
   depthstencil_offset = gen6_blorp_emit_depth_stencil_state(brw, params);
   gen7_blorp_emit_depth_stencil_state_pointers(brw, params,
                                                depthstencil_offset);
   if (params->use_wm_prog) {
      uint32_t wm_surf_offset_renderbuffer;
      uint32_t wm_surf_offset_texture = 0;
      wm_push_const_offset = gen6_blorp_emit_wm_constants(brw, params);
      intel_miptree_used_for_rendering(params->dst.mt);
      wm_surf_offset_renderbuffer =
         gen7_blorp_emit_surface_state(brw, params, &params->dst,
                                       I915_GEM_DOMAIN_RENDER,
                                       I915_GEM_DOMAIN_RENDER,
                                       true /* is_render_target */);
      if (params->src.mt) {
         wm_surf_offset_texture =
            gen7_blorp_emit_surface_state(brw, params, &params->src,
                                          I915_GEM_DOMAIN_SAMPLER, 0,
                                          false /* is_render_target */);
      }
      wm_bind_bo_offset =
         gen6_blorp_emit_binding_table(brw, params,
                                       wm_surf_offset_renderbuffer,
                                       wm_surf_offset_texture);
      sampler_offset = gen7_blorp_emit_sampler_state(brw, params);
   }
   gen7_blorp_emit_vs_disable(brw, params);
   gen7_blorp_emit_hs_disable(brw, params);
   gen7_blorp_emit_te_disable(brw, params);
   gen7_blorp_emit_ds_disable(brw, params);
   gen7_blorp_emit_gs_disable(brw, params);
   gen7_blorp_emit_streamout_disable(brw, params);
   gen6_blorp_emit_clip_disable(brw, params);
   gen7_blorp_emit_sf_config(brw, params);
   gen7_blorp_emit_wm_config(brw, params, prog_data);
   if (params->use_wm_prog) {
      gen7_blorp_emit_binding_table_pointers_ps(brw, params,
                                                wm_bind_bo_offset);
      gen7_blorp_emit_sampler_state_pointers_ps(brw, params, sampler_offset);
      gen7_blorp_emit_constant_ps(brw, params, wm_push_const_offset);
   } else {
      gen7_blorp_emit_constant_ps_disable(brw, params);
   }
   gen7_blorp_emit_ps_config(brw, params, prog_offset, prog_data);
   gen7_blorp_emit_cc_viewport(brw, params);

   if (params->depth.mt)
      gen7_blorp_emit_depth_stencil_config(brw, params);
   else
      gen7_blorp_emit_depth_disable(brw, params);
   gen7_blorp_emit_clear_params(brw, params);
   gen6_blorp_emit_drawing_rectangle(brw, params);
   gen7_blorp_emit_primitive(brw, params);
}
/**
 * Sets up a surface state structure to point at the given region.
 * While it is only used for the front/back buffer currently, it should be
 * usable for further buffers when doing ARB_draw_buffer support.
 */
static void
gen6_update_renderbuffer_surface(struct brw_context *brw,
                                 struct gl_renderbuffer *rb,
                                 bool layered,
                                 unsigned int unit)
{
   struct gl_context *ctx = &brw->ctx;
   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
   struct intel_mipmap_tree *mt = irb->mt;
   uint32_t *surf;
   uint32_t format = 0;
   /* _NEW_BUFFERS */
   mesa_format rb_format = _mesa_get_render_format(ctx, intel_rb_format(irb));
   uint32_t surftype;
   int depth = MAX2(irb->layer_count, 1);
   const GLenum gl_target =
      rb->TexImage ? rb->TexImage->TexObject->Target : GL_TEXTURE_2D;

   uint32_t surf_index =
      brw->wm.prog_data->binding_table.render_target_start + unit;

   intel_miptree_used_for_rendering(irb->mt);

   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
                          &brw->wm.base.surf_offset[surf_index]);

   format = brw->render_target_format[rb_format];
   if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
      _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
                    __func__, _mesa_get_format_name(rb_format));
   }

   switch (gl_target) {
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_CUBE_MAP:
      surftype = BRW_SURFACE_2D;
      depth *= 6;
      break;
   case GL_TEXTURE_3D:
      depth = MAX2(irb->mt->logical_depth0, 1);
      /* fallthrough */
   default:
      surftype = translate_tex_target(gl_target);
      break;
   }

   const int min_array_element = layered ? 0 : irb->mt_layer;

   surf[0] = SET_FIELD(surftype, BRW_SURFACE_TYPE) |
             SET_FIELD(format, BRW_SURFACE_FORMAT);

   /* reloc */
   assert(mt->offset % mt->cpp == 0);
   surf[1] = mt->bo->offset64 + mt->offset;

   /* In the gen6 PRM Volume 1 Part 1: Graphics Core, Section 7.18.3.7.1
    * (Surface Arrays For all surfaces other than separate stencil buffer):
    *
    * "[DevSNB] Errata: Sampler MSAA Qpitch will be 4 greater than the value
    *  calculated in the equation above , for every other odd Surface Height
    *  starting from 1 i.e. 1,5,9,13"
    *
    * Since this Qpitch errata only impacts the sampler, we have to adjust the
    * input for the rendering surface to achieve the same qpitch. For the
    * affected heights, we increment the height by 1 for the rendering
    * surface.
    */
   int height0 = irb->mt->logical_height0;
   if (brw->gen == 6 && irb->mt->num_samples > 1 && (height0 % 4) == 1)
      height0++;

   surf[2] = SET_FIELD(mt->logical_width0 - 1, BRW_SURFACE_WIDTH) |
             SET_FIELD(height0 - 1, BRW_SURFACE_HEIGHT) |
             SET_FIELD(irb->mt_level - irb->mt->first_level, BRW_SURFACE_LOD);

   surf[3] = brw_get_surface_tiling_bits(mt->tiling) |
             SET_FIELD(depth - 1, BRW_SURFACE_DEPTH) |
             SET_FIELD(mt->pitch - 1, BRW_SURFACE_PITCH);

   surf[4] = brw_get_surface_num_multisamples(mt->num_samples) |
             SET_FIELD(min_array_element, BRW_SURFACE_MIN_ARRAY_ELEMENT) |
             SET_FIELD(depth - 1, BRW_SURFACE_RENDER_TARGET_VIEW_EXTENT);

   surf[5] = (mt->align_h == 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0);

   drm_intel_bo_emit_reloc(brw->batch.bo,
			   brw->wm.base.surf_offset[surf_index] + 4,
			   mt->bo,
			   surf[1] - mt->bo->offset64,
			   I915_GEM_DOMAIN_RENDER,
			   I915_GEM_DOMAIN_RENDER);
}
예제 #4
0
파일: gen8_blorp.c 프로젝트: hakzsam/mesa
static uint32_t
gen8_blorp_emit_surface_states(struct brw_context *brw,
                               const struct brw_blorp_params *params)
{
   uint32_t wm_surf_offset_renderbuffer;
   uint32_t wm_surf_offset_texture = 0;

   intel_miptree_used_for_rendering(params->dst.mt);

   wm_surf_offset_renderbuffer =
      brw_blorp_emit_surface_state(brw, &params->dst,
                                   I915_GEM_DOMAIN_RENDER,
                                   I915_GEM_DOMAIN_RENDER,
                                   true /* is_render_target */);
   if (params->src.mt) {
      const struct brw_blorp_surface_info *surface = &params->src;
      struct intel_mipmap_tree *mt = surface->mt;

      /* If src is a 2D multisample array texture on Gen7+ using
       * INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, src layer is the
       * physical layer holding sample 0.  So, for example, if mt->num_samples
       * == 4, then logical layer n corresponds to layer == 4*n.
       *
       * Multisampled depth and stencil surfaces have the samples interleaved
       * (INTEL_MSAA_LAYOUT_IMS) and therefore the layer doesn't need
       * adjustment.
       */
      const unsigned layer_divider =
         (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
          mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) ?
         MAX2(mt->num_samples, 1) : 1;

      const bool is_cube = mt->target == GL_TEXTURE_CUBE_MAP_ARRAY ||
                           mt->target == GL_TEXTURE_CUBE_MAP;
      const unsigned depth = (is_cube ? 6 : 1) * mt->logical_depth0;
      const unsigned layer = mt->target != GL_TEXTURE_3D ?
                                surface->layer / layer_divider : 0;

      struct isl_view view = {
         .format = surface->brw_surfaceformat,
         .base_level = surface->level,
         .levels = mt->last_level - surface->level + 1,
         .base_array_layer = layer,
         .array_len = depth - layer,
         .channel_select = {
            swizzle_to_scs(GET_SWZ(surface->swizzle, 0)),
            swizzle_to_scs(GET_SWZ(surface->swizzle, 1)),
            swizzle_to_scs(GET_SWZ(surface->swizzle, 2)),
            swizzle_to_scs(GET_SWZ(surface->swizzle, 3)),
         },
         .usage = ISL_SURF_USAGE_TEXTURE_BIT,
      };

      brw_emit_surface_state(brw, mt, &view,
                             brw->gen >= 9 ? SKL_MOCS_WB : BDW_MOCS_WB,
                             false, &wm_surf_offset_texture, -1,
                             I915_GEM_DOMAIN_SAMPLER, 0);
   }

   return gen6_blorp_emit_binding_table(brw,
                                        wm_surf_offset_renderbuffer,
                                        wm_surf_offset_texture);
}

/**
 * \copydoc gen6_blorp_exec()
 */
void
gen8_blorp_exec(struct brw_context *brw, const struct brw_blorp_params *params)
{
   uint32_t wm_bind_bo_offset = 0;

   brw_upload_state_base_address(brw);

   gen7_blorp_emit_cc_viewport(brw);
   gen7_l3_state.emit(brw);

   gen7_blorp_emit_urb_config(brw, params);

   const uint32_t cc_blend_state_offset =
      gen8_blorp_emit_blend_state(brw, params);
   gen7_blorp_emit_blend_state_pointer(brw, cc_blend_state_offset);

   const uint32_t cc_state_offset = gen6_blorp_emit_cc_state(brw);
   gen7_blorp_emit_cc_state_pointer(brw, cc_state_offset);

   gen8_blorp_disable_constant_state(brw, _3DSTATE_CONSTANT_VS);
   gen8_blorp_disable_constant_state(brw, _3DSTATE_CONSTANT_HS);
   gen8_blorp_disable_constant_state(brw, _3DSTATE_CONSTANT_DS);
   gen8_blorp_disable_constant_state(brw, _3DSTATE_CONSTANT_GS);
   gen8_blorp_disable_constant_state(brw, _3DSTATE_CONSTANT_PS);

   wm_bind_bo_offset = gen8_blorp_emit_surface_states(brw, params);

   gen7_blorp_emit_binding_table_pointers_ps(brw, wm_bind_bo_offset);

   if (params->src.mt) {
      const uint32_t sampler_offset =
         gen6_blorp_emit_sampler_state(brw, BRW_MAPFILTER_LINEAR, 0, true);
      gen7_blorp_emit_sampler_state_pointers_ps(brw, sampler_offset);
   }

   gen8_emit_3dstate_multisample(brw, params->dst.num_samples);
   gen6_emit_3dstate_sample_mask(brw,
                                 params->dst.num_samples > 1 ?
                                    (1 << params->dst.num_samples) - 1 : 1);

   gen8_disable_stages.emit(brw);
   gen8_blorp_emit_vs_disable(brw);
   gen8_blorp_emit_hs_disable(brw);
   gen7_blorp_emit_te_disable(brw);
   gen8_blorp_emit_ds_disable(brw);
   gen8_blorp_emit_gs_disable(brw);

   gen8_blorp_emit_streamout_disable(brw);
   gen6_blorp_emit_clip_disable(brw);
   gen8_blorp_emit_raster_state(brw);
   gen8_blorp_emit_sbe_state(brw, params);
   gen8_blorp_emit_sf_config(brw);

   gen8_blorp_emit_ps_blend(brw);
   gen8_blorp_emit_ps_extra(brw, params);

   gen8_blorp_emit_ps_config(brw, params);

   gen8_blorp_emit_depth_stencil_state(brw, params);
   gen8_blorp_emit_wm_state(brw);

   gen8_blorp_emit_depth_disable(brw);
   gen7_blorp_emit_clear_params(brw, params);
   gen6_blorp_emit_drawing_rectangle(brw, params);
   gen8_blorp_emit_vf_topology(brw);
   gen8_blorp_emit_vf_sys_gen_vals_state(brw);
   gen6_blorp_emit_vertices(brw, params);
   gen8_blorp_emit_vf_instancing_state(brw, params);
   gen8_blorp_emit_vf_state(brw);
   gen7_blorp_emit_primitive(brw, params);

   if (brw->gen < 9)
      gen8_write_pma_stall_bits(brw, 0);
}
예제 #5
0
파일: brw_blorp.c 프로젝트: Echelon9/mesa
static void
blorp_surf_for_miptree(struct brw_context *brw,
                       struct blorp_surf *surf,
                       struct intel_mipmap_tree *mt,
                       bool is_render_target,
                       uint32_t safe_aux_usage,
                       unsigned *level,
                       unsigned start_layer, unsigned num_layers,
                       struct isl_surf tmp_surfs[2])
{
   if (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
       mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
      const unsigned num_samples = MAX2(1, mt->num_samples);
      for (unsigned i = 0; i < num_layers; i++) {
         for (unsigned s = 0; s < num_samples; s++) {
            const unsigned phys_layer = (start_layer + i) * num_samples + s;
            intel_miptree_check_level_layer(mt, *level, phys_layer);
         }
      }
   } else {
      for (unsigned i = 0; i < num_layers; i++)
         intel_miptree_check_level_layer(mt, *level, start_layer + i);
   }

   intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]);
   surf->surf = &tmp_surfs[0];
   surf->addr = (struct blorp_address) {
      .buffer = mt->bo,
      .offset = mt->offset,
      .read_domains = is_render_target ? I915_GEM_DOMAIN_RENDER :
                                         I915_GEM_DOMAIN_SAMPLER,
      .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0,
   };

   if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8 &&
       mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
      /* Sandy bridge stencil and HiZ use this ALL_SLICES_AT_EACH_LOD hack in
       * order to allow for layered rendering.  The hack makes each LOD of the
       * stencil or HiZ buffer a single tightly packed array surface at some
       * offset into the surface.  Since ISL doesn't know how to deal with the
       * crazy ALL_SLICES_AT_EACH_LOD layout and since we have to do a manual
       * offset of it anyway, we might as well do the offset here and keep the
       * hacks inside the i965 driver.
       *
       * See also gen6_depth_stencil_state.c
       */
      uint32_t offset;
      apply_gen6_stencil_hiz_offset(&tmp_surfs[0], mt, *level, &offset);
      surf->addr.offset += offset;
      *level = 0;
   }

   struct isl_surf *aux_surf = &tmp_surfs[1];
   intel_miptree_get_aux_isl_surf(brw, mt, aux_surf, &surf->aux_usage);

   if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
      if (surf->aux_usage == ISL_AUX_USAGE_HIZ) {
         /* If we're not going to use it as a depth buffer, resolve HiZ */
         if (!(safe_aux_usage & (1 << ISL_AUX_USAGE_HIZ))) {
            for (unsigned i = 0; i < num_layers; i++) {
               intel_miptree_slice_resolve_depth(brw, mt, *level,
                                                 start_layer + i);

               /* If we're rendering to it then we'll need a HiZ resolve once
                * we're done before we can use it with HiZ again.
                */
               if (is_render_target)
                  intel_miptree_slice_set_needs_hiz_resolve(mt, *level,
                                                            start_layer + i);
            }
            surf->aux_usage = ISL_AUX_USAGE_NONE;
         }
      } else if (!(safe_aux_usage & (1 << surf->aux_usage))) {
         uint32_t flags = 0;
         if (safe_aux_usage & (1 << ISL_AUX_USAGE_CCS_E))
            flags |= INTEL_MIPTREE_IGNORE_CCS_E;

         intel_miptree_resolve_color(brw, mt,
                                     *level, start_layer, num_layers, flags);

         assert(!intel_miptree_has_color_unresolved(mt, *level, 1,
                                                    start_layer, num_layers));
         surf->aux_usage = ISL_AUX_USAGE_NONE;
      }
   }

   if (is_render_target)
      intel_miptree_used_for_rendering(brw, mt, *level,
                                       start_layer, num_layers);

   if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
      /* We only really need a clear color if we also have an auxiliary
       * surface.  Without one, it does nothing.
       */
      surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt);

      surf->aux_surf = aux_surf;
      surf->aux_addr = (struct blorp_address) {
         .read_domains = is_render_target ? I915_GEM_DOMAIN_RENDER :
                                            I915_GEM_DOMAIN_SAMPLER,
         .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0,
      };

      if (mt->mcs_buf) {
         surf->aux_addr.buffer = mt->mcs_buf->bo;
         surf->aux_addr.offset = mt->mcs_buf->offset;
      } else {
         assert(surf->aux_usage == ISL_AUX_USAGE_HIZ);
         struct intel_mipmap_tree *hiz_mt = mt->hiz_buf->mt;
         if (hiz_mt) {
            surf->aux_addr.buffer = hiz_mt->bo;
            if (brw->gen == 6 &&
                hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
               /* gen6 requires the HiZ buffer to be manually offset to the
                * right location.  We could fixup the surf but it doesn't
                * matter since most of those fields don't matter.
                */
               apply_gen6_stencil_hiz_offset(aux_surf, hiz_mt, *level,
                                             &surf->aux_addr.offset);
            } else {
               surf->aux_addr.offset = 0;
            }
            assert(hiz_mt->pitch == aux_surf->row_pitch);
         } else {
            surf->aux_addr.buffer = mt->hiz_buf->aux_base.bo;
            surf->aux_addr.offset = mt->hiz_buf->aux_base.offset;
         }
      }
   } else {
      surf->aux_addr = (struct blorp_address) {
         .buffer = NULL,
      };
      memset(&surf->clear_color, 0, sizeof(surf->clear_color));
   }
   assert((surf->aux_usage == ISL_AUX_USAGE_NONE) ==
          (surf->aux_addr.buffer == NULL));
}