/**
 * Creates a null surface.
 *
 * This is used when the shader doesn't write to any color output.  An FB
 * write to target 0 will still be emitted, because that's how the thread is
 * terminated (and computed depth is returned), so we need to have the
 * hardware discard the target 0 color output..
 */
static void
gen7_emit_null_surface_state(struct brw_context *brw,
                             unsigned width,
                             unsigned height,
                             unsigned samples,
                             uint32_t *out_offset)
{
   /* From the Ivy bridge PRM, Vol4 Part1 p62 (Surface Type: Programming
    * Notes):
    *
    *     A null surface is used in instances where an actual surface is not
    *     bound. When a write message is generated to a null surface, no
    *     actual surface is written to. When a read message (including any
    *     sampling engine message) is generated to a null surface, the result
    *     is all zeros. Note that a null surface type is allowed to be used
    *     with all messages, even if it is not specificially indicated as
    *     supported. All of the remaining fields in surface state are ignored
    *     for null surfaces, with the following exceptions: Width, Height,
    *     Depth, LOD, and Render Target View Extent fields must match the
    *     depth buffer’s corresponding state for all render target surfaces,
    *     including null.
    */
   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32,
                                    out_offset);
   memset(surf, 0, 8 * 4);

   /* From the Ivybridge PRM, Volume 4, Part 1, page 65,
    * Tiled Surface: Programming Notes:
    * "If Surface Type is SURFTYPE_NULL, this field must be TRUE."
    */
   surf[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
             BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
             GEN7_SURFACE_TILING_Y;

   surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
             SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);

   gen7_check_surface_setup(surf, true /* is_render_target */);
}
/* SURFACE_STATE for renderbuffer or texture surface (see
 * brw_update_renderbuffer_surface and brw_update_texture_surface)
 */
static uint32_t
gen7_blorp_emit_surface_state(struct brw_context *brw,
                              const brw_blorp_params *params,
                              const brw_blorp_surface_info *surface,
                              uint32_t read_domains, uint32_t write_domain,
                              bool is_render_target)
{
   uint32_t wm_surf_offset;
   uint32_t width = surface->width;
   uint32_t height = surface->height;
   /* Note: since gen7 uses INTEL_MSAA_LAYOUT_CMS or INTEL_MSAA_LAYOUT_UMS for
    * color surfaces, width and height are measured in pixels; we don't need
    * to divide them by 2 as we do for Gen6 (see
    * gen6_blorp_emit_surface_state).
    */
   struct intel_region *region = surface->mt->region;
   uint32_t tile_x, tile_y;
   const uint8_t mocs = GEN7_MOCS_L3;

   uint32_t tiling = surface->map_stencil_as_y_tiled
      ? I915_TILING_Y : region->tiling;

   uint32_t *surf = (uint32_t *)
      brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32, &wm_surf_offset);
   memset(surf, 0, 8 * 4);

   surf[0] = BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT |
             surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT |
             gen7_surface_tiling_mode(tiling);

   if (surface->mt->align_h == 4)
      surf[0] |= GEN7_SURFACE_VALIGN_4;
   if (surface->mt->align_w == 8)
      surf[0] |= GEN7_SURFACE_HALIGN_8;

   if (surface->array_spacing_lod0)
      surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;
   else
      surf[0] |= GEN7_SURFACE_ARYSPC_FULL;

   /* reloc */
   surf[1] =
      surface->compute_tile_offsets(&tile_x, &tile_y) + region->bo->offset;

   /* Note that the low bits of these fields are missing, so
    * there's the possibility of getting in trouble.
    */
   assert(tile_x % 4 == 0);
   assert(tile_y % 2 == 0);
   surf[5] = SET_FIELD(tile_x / 4, BRW_SURFACE_X_OFFSET) |
             SET_FIELD(tile_y / 2, BRW_SURFACE_Y_OFFSET) |
             SET_FIELD(mocs, GEN7_SURFACE_MOCS);

   surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
             SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);

   uint32_t pitch_bytes = region->pitch;
   if (surface->map_stencil_as_y_tiled)
      pitch_bytes *= 2;
   surf[3] = pitch_bytes - 1;

   surf[4] = gen7_surface_msaa_bits(surface->num_samples, surface->msaa_layout);
   if (surface->mt->mcs_mt) {
      gen7_set_surface_mcs_info(brw, surf, wm_surf_offset, surface->mt->mcs_mt,
                                is_render_target);
   }

   surf[7] = surface->mt->fast_clear_color_value;

   if (brw->is_haswell) {
      surf[7] |= (SET_FIELD(HSW_SCS_RED,   GEN7_SURFACE_SCS_R) |
                  SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
                  SET_FIELD(HSW_SCS_BLUE,  GEN7_SURFACE_SCS_B) |
                  SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A));
   }

   /* Emit relocation to surface contents */
   drm_intel_bo_emit_reloc(brw->batch.bo,
                           wm_surf_offset + 4,
                           region->bo,
                           surf[1] - region->bo->offset,
                           read_domains, write_domain);

   gen7_check_surface_setup(surf, is_render_target);

   return wm_surf_offset;
}
Exemple #3
0
/* SURFACE_STATE for renderbuffer or texture surface (see
 * brw_update_renderbuffer_surface and brw_update_texture_surface)
 */
static uint32_t
gen7_blorp_emit_surface_state(struct brw_context *brw,
                              const brw_blorp_params *params,
                              const brw_blorp_surface_info *surface,
                              uint32_t read_domains, uint32_t write_domain,
                              bool is_render_target)
{
   struct intel_context *intel = &brw->intel;

   uint32_t wm_surf_offset;
   uint32_t width = surface->width;
   uint32_t height = surface->height;
   /* Note: since gen7 uses INTEL_MSAA_LAYOUT_CMS or INTEL_MSAA_LAYOUT_UMS for
    * color surfaces, width and height are measured in pixels; we don't need
    * to divide them by 2 as we do for Gen6 (see
    * gen6_blorp_emit_surface_state).
    */
   struct intel_region *region = surface->mt->region;
   uint32_t tile_x, tile_y;

   struct gen7_surface_state *surf = (struct gen7_surface_state *)
      brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, sizeof(*surf), 32,
                      &wm_surf_offset);
   memset(surf, 0, sizeof(*surf));

   if (surface->mt->align_h == 4)
      surf->ss0.vertical_alignment = 1;
   if (surface->mt->align_w == 8)
      surf->ss0.horizontal_alignment = 1;

   surf->ss0.surface_format = surface->brw_surfaceformat;
   surf->ss0.surface_type = BRW_SURFACE_2D;
   surf->ss0.surface_array_spacing = surface->array_spacing_lod0 ?
      GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL;

   /* reloc */
   surf->ss1.base_addr = surface->compute_tile_offsets(&tile_x, &tile_y);
   surf->ss1.base_addr += region->bo->offset;

   /* Note that the low bits of these fields are missing, so
    * there's the possibility of getting in trouble.
    */
   assert(tile_x % 4 == 0);
   assert(tile_y % 2 == 0);
   surf->ss5.x_offset = tile_x / 4;
   surf->ss5.y_offset = tile_y / 2;

   surf->ss2.width = width - 1;
   surf->ss2.height = height - 1;

   uint32_t tiling = surface->map_stencil_as_y_tiled
      ? I915_TILING_Y : region->tiling;
   gen7_set_surface_tiling(surf, tiling);

   uint32_t pitch_bytes = region->pitch * region->cpp;
   if (surface->map_stencil_as_y_tiled)
      pitch_bytes *= 2;
   surf->ss3.pitch = pitch_bytes - 1;

   gen7_set_surface_msaa(surf, surface->num_samples, surface->msaa_layout);
   if (surface->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
      gen7_set_surface_mcs_info(brw, surf, wm_surf_offset,
                                surface->mt->mcs_mt, is_render_target);
   }

   if (intel->is_haswell) {
      surf->ss7.shader_channel_select_r = HSW_SCS_RED;
      surf->ss7.shader_channel_select_g = HSW_SCS_GREEN;
      surf->ss7.shader_channel_select_b = HSW_SCS_BLUE;
      surf->ss7.shader_channel_select_a = HSW_SCS_ALPHA;
   }

   /* Emit relocation to surface contents */
   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
                           wm_surf_offset +
                           offsetof(struct gen7_surface_state, ss1),
                           region->bo,
                           surf->ss1.base_addr - region->bo->offset,
                           read_domains, write_domain);

   gen7_check_surface_setup(surf, is_render_target);

   return wm_surf_offset;
}
Exemple #4
0
/* SURFACE_STATE for renderbuffer or texture surface (see
 * brw_update_renderbuffer_surface and brw_update_texture_surface)
 */
static uint32_t
gen7_blorp_emit_surface_state(struct brw_context *brw,
                              const brw_blorp_params *params,
                              const brw_blorp_surface_info *surface,
                              uint32_t read_domains, uint32_t write_domain,
                              bool is_render_target)
{
    struct intel_context *intel = &brw->intel;

    uint32_t wm_surf_offset;
    uint32_t width, height;
    surface->get_miplevel_dims(&width, &height);
    if (surface->map_stencil_as_y_tiled) {
        width *= 2;
        height /= 2;
    }
    struct intel_region *region = surface->mt->region;

    struct gen7_surface_state *surf = (struct gen7_surface_state *)
                                      brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, sizeof(*surf), 32,
                                              &wm_surf_offset);
    memset(surf, 0, sizeof(*surf));

    if (surface->mt->align_h == 4)
        surf->ss0.vertical_alignment = 1;
    if (surface->mt->align_w == 8)
        surf->ss0.horizontal_alignment = 1;

    surf->ss0.surface_format = surface->brw_surfaceformat;
    surf->ss0.surface_type = BRW_SURFACE_2D;
    surf->ss0.surface_array_spacing = surface->array_spacing_lod0 ?
                                      GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL;

    /* reloc */
    surf->ss1.base_addr = region->bo->offset; /* No tile offsets needed */

    surf->ss2.width = width - 1;
    surf->ss2.height = height - 1;

    uint32_t tiling = surface->map_stencil_as_y_tiled
                      ? I915_TILING_Y : region->tiling;
    gen7_set_surface_tiling(surf, tiling);

    uint32_t pitch_bytes = region->pitch * region->cpp;
    if (surface->map_stencil_as_y_tiled)
        pitch_bytes *= 2;
    surf->ss3.pitch = pitch_bytes - 1;

    gen7_set_surface_num_multisamples(surf, surface->num_samples);

    if (intel->is_haswell) {
        surf->ss7.shader_chanel_select_r = HSW_SCS_RED;
        surf->ss7.shader_chanel_select_g = HSW_SCS_GREEN;
        surf->ss7.shader_chanel_select_b = HSW_SCS_BLUE;
        surf->ss7.shader_chanel_select_a = HSW_SCS_ALPHA;
    }

    /* Emit relocation to surface contents */
    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
                            wm_surf_offset +
                            offsetof(struct gen7_surface_state, ss1),
                            region->bo,
                            surf->ss1.base_addr - region->bo->offset,
                            read_domains, write_domain);

    gen7_check_surface_setup(surf, is_render_target);

    return wm_surf_offset;
}