/** * 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; }
/* 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; }
/* 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; }