/* SURFACE_STATE for renderbuffer or texture surface (see * brw_update_renderbuffer_surface and brw_update_texture_surface) */ static uint32_t gen6_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) { uint32_t wm_surf_offset; uint32_t width, height; surface->get_miplevel_dims(&width, &height); if (surface->num_samples > 1) { /* TODO: seems clumsy */ width /= 2; height /= 2; } if (surface->map_stencil_as_y_tiled) { width *= 2; height /= 2; } struct intel_region *region = surface->mt->region; uint32_t *surf = (uint32_t *) brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32, &wm_surf_offset); surf[0] = (BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT | BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT | BRW_SURFACE_CUBEFACE_ENABLES | surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT); /* reloc */ surf[1] = region->bo->offset; /* No tile offsets needed */ surf[2] = (0 << BRW_SURFACE_LOD_SHIFT | (width - 1) << BRW_SURFACE_WIDTH_SHIFT | (height - 1) << BRW_SURFACE_HEIGHT_SHIFT); uint32_t tiling = surface->map_stencil_as_y_tiled ? BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y : brw_get_surface_tiling_bits(region->tiling); uint32_t pitch_bytes = region->pitch * region->cpp; if (surface->map_stencil_as_y_tiled) pitch_bytes *= 2; surf[3] = (tiling | 0 << BRW_SURFACE_DEPTH_SHIFT | (pitch_bytes - 1) << BRW_SURFACE_PITCH_SHIFT); surf[4] = brw_get_surface_num_multisamples(surface->num_samples); surf[5] = (0 << BRW_SURFACE_X_OFFSET_SHIFT | 0 << BRW_SURFACE_Y_OFFSET_SHIFT | (surface->mt->align_h == 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0)); /* Emit relocation to surface contents */ drm_intel_bo_emit_reloc(brw->intel.batch.bo, wm_surf_offset + 4, region->bo, surf[1] - region->bo->offset, read_domains, write_domain); return wm_surf_offset; }
/* SURFACE_STATE for renderbuffer or texture surface (see * brw_update_renderbuffer_surface and brw_update_texture_surface) */ static uint32_t gen6_blorp_emit_surface_state(struct brw_context *brw, const struct brw_blorp_params *params, const struct brw_blorp_surface_info *surface, uint32_t read_domains, uint32_t write_domain) { uint32_t wm_surf_offset; uint32_t width = surface->width; uint32_t height = surface->height; if (surface->num_samples > 1) { /* Since gen6 uses INTEL_MSAA_LAYOUT_IMS, width and height are measured * in samples. But SURFACE_STATE wants them in pixels, so we need to * divide them each by 2. */ width /= 2; height /= 2; } struct intel_mipmap_tree *mt = surface->mt; uint32_t tile_x, tile_y; uint32_t *surf = (uint32_t *) brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32, &wm_surf_offset); surf[0] = (BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT | BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT | BRW_SURFACE_CUBEFACE_ENABLES | surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT); /* reloc */ surf[1] = (brw_blorp_compute_tile_offsets(surface, &tile_x, &tile_y) + mt->bo->offset64); surf[2] = (0 << BRW_SURFACE_LOD_SHIFT | (width - 1) << BRW_SURFACE_WIDTH_SHIFT | (height - 1) << BRW_SURFACE_HEIGHT_SHIFT); uint32_t tiling = surface->map_stencil_as_y_tiled ? BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y : brw_get_surface_tiling_bits(mt->tiling); uint32_t pitch_bytes = mt->pitch; if (surface->map_stencil_as_y_tiled) pitch_bytes *= 2; surf[3] = (tiling | 0 << BRW_SURFACE_DEPTH_SHIFT | (pitch_bytes - 1) << BRW_SURFACE_PITCH_SHIFT); surf[4] = brw_get_surface_num_multisamples(surface->num_samples); /* 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] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT | (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT | (surface->mt->valign == 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0)); /* Emit relocation to surface contents */ drm_intel_bo_emit_reloc(brw->batch.bo, wm_surf_offset + 4, mt->bo, surf[1] - mt->bo->offset64, read_domains, write_domain); return wm_surf_offset; }
/** * 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); }