Esempio n. 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);
}
Esempio n. 2
0
/**
 * \copydoc gen6_blorp_exec()
 */
void
gen7_blorp_exec(struct brw_context *brw,
                const struct brw_blorp_params *params)
{
    if (brw->gen >= 8)
        return;

    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;

    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);
    gen7_blorp_emit_urb_config(brw);
    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);
        gen7_blorp_emit_blend_state_pointer(brw, cc_blend_state_offset);
        gen7_blorp_emit_cc_state_pointer(brw, cc_state_offset);
    }
    depthstencil_offset = gen6_blorp_emit_depth_stencil_state(brw, params);
    gen7_blorp_emit_depth_stencil_state_pointers(brw, depthstencil_offset);
    if (brw->use_resource_streamer)
        gen7_disable_hw_binding_tables(brw);
    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 =
            gen7_blorp_emit_surface_state(brw, &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->src,
                                              I915_GEM_DOMAIN_SAMPLER, 0,
                                              false /* is_render_target */);
        }
        wm_bind_bo_offset =
            gen6_blorp_emit_binding_table(brw,
                                          wm_surf_offset_renderbuffer,
                                          wm_surf_offset_texture);
    }
    gen7_blorp_emit_vs_disable(brw);
    gen7_blorp_emit_hs_disable(brw);
    gen7_blorp_emit_te_disable(brw);
    gen7_blorp_emit_ds_disable(brw);
    gen7_blorp_emit_gs_disable(brw);
    gen7_blorp_emit_streamout_disable(brw);
    gen6_blorp_emit_clip_disable(brw);
    gen7_blorp_emit_sf_config(brw, params);
    gen7_blorp_emit_wm_config(brw, params);
    if (params->wm_prog_data) {
        gen7_blorp_emit_binding_table_pointers_ps(brw, wm_bind_bo_offset);
        gen7_blorp_emit_constant_ps(brw, wm_push_const_offset);
    } else {
        gen7_blorp_emit_constant_ps_disable(brw);
    }

    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);
    }

    gen7_blorp_emit_ps_config(brw, params);
    gen7_blorp_emit_cc_viewport(brw);

    if (params->depth.mt)
        gen7_blorp_emit_depth_stencil_config(brw, params);
    else
        gen7_blorp_emit_depth_disable(brw);
    gen7_blorp_emit_clear_params(brw, params);
    gen6_blorp_emit_drawing_rectangle(brw, params);
    gen7_blorp_emit_primitive(brw, params);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
static inline void
brw_upload_pipeline_state(struct brw_context *brw,
                          enum brw_pipeline pipeline)
{
   struct gl_context *ctx = &brw->ctx;
   int i;
   static int dirty_count = 0;
   struct brw_state_flags state = brw->state.pipelines[pipeline];
   unsigned int fb_samples = _mesa_geometric_samples(ctx->DrawBuffer);

   brw_select_pipeline(brw, pipeline);

   if (0) {
      /* Always re-emit all state. */
      brw->NewGLState = ~0;
      ctx->NewDriverState = ~0ull;
   }

   if (pipeline == BRW_RENDER_PIPELINE) {
      if (brw->fragment_program != ctx->FragmentProgram._Current) {
         brw->fragment_program = ctx->FragmentProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM;
      }

      if (brw->tess_eval_program != ctx->TessEvalProgram._Current) {
         brw->tess_eval_program = ctx->TessEvalProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_TESS_PROGRAMS;
      }

      if (brw->tess_ctrl_program != ctx->TessCtrlProgram._Current) {
         brw->tess_ctrl_program = ctx->TessCtrlProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_TESS_PROGRAMS;
      }

      if (brw->geometry_program != ctx->GeometryProgram._Current) {
         brw->geometry_program = ctx->GeometryProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_GEOMETRY_PROGRAM;
      }

      if (brw->vertex_program != ctx->VertexProgram._Current) {
         brw->vertex_program = ctx->VertexProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_VERTEX_PROGRAM;
      }
   }

   if (brw->compute_program != ctx->ComputeProgram._Current) {
      brw->compute_program = ctx->ComputeProgram._Current;
      brw->ctx.NewDriverState |= BRW_NEW_COMPUTE_PROGRAM;
   }

   if (brw->meta_in_progress != _mesa_meta_in_progress(ctx)) {
      brw->meta_in_progress = _mesa_meta_in_progress(ctx);
      brw->ctx.NewDriverState |= BRW_NEW_META_IN_PROGRESS;
   }

   if (brw->num_samples != fb_samples) {
      brw->num_samples = fb_samples;
      brw->ctx.NewDriverState |= BRW_NEW_NUM_SAMPLES;
   }

   /* Exit early if no state is flagged as dirty */
   merge_ctx_state(brw, &state);
   if ((state.mesa | state.brw) == 0)
      return;

   /* Emit Sandybridge workaround flushes on every primitive, for safety. */
   if (brw->gen == 6)
      brw_emit_post_sync_nonzero_flush(brw);

   brw_upload_programs(brw, pipeline);
   merge_ctx_state(brw, &state);

   brw_upload_state_base_address(brw);

   const struct brw_tracked_state *atoms =
      brw_get_pipeline_atoms(brw, pipeline);
   const int num_atoms = brw->num_atoms[pipeline];

   if (unlikely(INTEL_DEBUG)) {
      /* Debug version which enforces various sanity checks on the
       * state flags which are generated and checked to help ensure
       * state atoms are ordered correctly in the list.
       */
      struct brw_state_flags examined, prev;
      memset(&examined, 0, sizeof(examined));
      prev = state;

      for (i = 0; i < num_atoms; i++) {
	 const struct brw_tracked_state *atom = &atoms[i];
	 struct brw_state_flags generated;

         check_and_emit_atom(brw, &state, atom);

	 accumulate_state(&examined, &atom->dirty);

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, &state);
	 assert(!check_state(&examined, &generated));
	 prev = state;
      }
   }
   else {
      for (i = 0; i < num_atoms; i++) {
	 const struct brw_tracked_state *atom = &atoms[i];

         check_and_emit_atom(brw, &state, atom);
      }
   }

   if (unlikely(INTEL_DEBUG & DEBUG_STATE)) {
      STATIC_ASSERT(ARRAY_SIZE(brw_bits) == BRW_NUM_STATE_BITS + 1);

      brw_update_dirty_count(mesa_bits, state.mesa);
      brw_update_dirty_count(brw_bits, state.brw);
      if (dirty_count++ % 1000 == 0) {
	 brw_print_dirty_count(mesa_bits);
	 brw_print_dirty_count(brw_bits);
	 fprintf(stderr, "\n");
      }
   }
}