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, ¶ms->dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, true /* is_render_target */); if (params->src.mt) { const struct brw_blorp_surface_info *surface = ¶ms->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); }
/** * Note: if the src (or dst) is a 2D multisample array texture on Gen7+ using * INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, src_layer (dst_layer) is * the physical layer holding sample 0. So, for example, if * src_mt->num_samples == 4, then logical layer n corresponds to src_layer == * 4*n. */ void brw_blorp_blit_miptrees(struct brw_context *brw, struct intel_mipmap_tree *src_mt, unsigned src_level, unsigned src_layer, mesa_format src_format, int src_swizzle, struct intel_mipmap_tree *dst_mt, unsigned dst_level, unsigned dst_layer, mesa_format dst_format, float src_x0, float src_y0, float src_x1, float src_y1, float dst_x0, float dst_y0, float dst_x1, float dst_y1, GLenum filter, bool mirror_x, bool mirror_y, bool decode_srgb, bool encode_srgb) { /* Blorp operates in logical layers */ src_layer = physical_to_logical_layer(src_mt, src_layer); dst_layer = physical_to_logical_layer(dst_mt, dst_layer); DBG("%s from %dx %s mt %p %d %d (%f,%f) (%f,%f)" "to %dx %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n", __func__, src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt, src_level, src_layer, src_x0, src_y0, src_x1, src_y1, dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt, dst_level, dst_layer, dst_x0, dst_y0, dst_x1, dst_y1, mirror_x, mirror_y); if (!decode_srgb && _mesa_get_format_color_encoding(src_format) == GL_SRGB) src_format = _mesa_get_srgb_format_linear(src_format); if (!encode_srgb && _mesa_get_format_color_encoding(dst_format) == GL_SRGB) dst_format = _mesa_get_srgb_format_linear(dst_format); /* When doing a multisample resolve of a GL_LUMINANCE32F or GL_INTENSITY32F * texture, the above code configures the source format for L32_FLOAT or * I32_FLOAT, and the destination format for R32_FLOAT. On Sandy Bridge, * the SAMPLE message appears to handle multisampled L32_FLOAT and * I32_FLOAT textures incorrectly, resulting in blocky artifacts. So work * around the problem by using a source format of R32_FLOAT. This * shouldn't affect rendering correctness, since the destination format is * R32_FLOAT, so only the contents of the red channel matters. */ if (brw->gen == 6 && src_mt->num_samples > 1 && dst_mt->num_samples <= 1 && src_mt->format == dst_mt->format && (dst_format == MESA_FORMAT_L_FLOAT32 || dst_format == MESA_FORMAT_I_FLOAT32)) { src_format = dst_format = MESA_FORMAT_R_FLOAT32; } uint32_t src_usage_flags = (1 << ISL_AUX_USAGE_MCS); if (src_format == src_mt->format) src_usage_flags |= (1 << ISL_AUX_USAGE_CCS_E); uint32_t dst_usage_flags = (1 << ISL_AUX_USAGE_MCS); if (dst_format == dst_mt->format) { dst_usage_flags |= (1 << ISL_AUX_USAGE_CCS_E) | (1 << ISL_AUX_USAGE_CCS_D); } struct isl_surf tmp_surfs[4]; struct blorp_surf src_surf, dst_surf; blorp_surf_for_miptree(brw, &src_surf, src_mt, false, src_usage_flags, &src_level, src_layer, 1, &tmp_surfs[0]); blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true, dst_usage_flags, &dst_level, dst_layer, 1, &tmp_surfs[2]); struct isl_swizzle src_isl_swizzle = { .r = swizzle_to_scs(GET_SWZ(src_swizzle, 0)), .g = swizzle_to_scs(GET_SWZ(src_swizzle, 1)), .b = swizzle_to_scs(GET_SWZ(src_swizzle, 2)), .a = swizzle_to_scs(GET_SWZ(src_swizzle, 3)), }; struct blorp_batch batch; blorp_batch_init(&brw->blorp, &batch, brw, 0); blorp_blit(&batch, &src_surf, src_level, src_layer, brw_blorp_to_isl_format(brw, src_format, false), src_isl_swizzle, &dst_surf, dst_level, dst_layer, brw_blorp_to_isl_format(brw, dst_format, true), ISL_SWIZZLE_IDENTITY, src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, filter, mirror_x, mirror_y); blorp_batch_finish(&batch); } void brw_blorp_copy_miptrees(struct brw_context *brw, struct intel_mipmap_tree *src_mt, unsigned src_level, unsigned src_layer, struct intel_mipmap_tree *dst_mt, unsigned dst_level, unsigned dst_layer, unsigned src_x, unsigned src_y, unsigned dst_x, unsigned dst_y, unsigned src_width, unsigned src_height) { DBG("%s from %dx %s mt %p %d %d (%d,%d) %dx%d" "to %dx %s mt %p %d %d (%d,%d)\n", __func__, src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt, src_level, src_layer, src_x, src_y, src_width, src_height, dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt, dst_level, dst_layer, dst_x, dst_y); struct isl_surf tmp_surfs[4]; struct blorp_surf src_surf, dst_surf; blorp_surf_for_miptree(brw, &src_surf, src_mt, false, (1 << ISL_AUX_USAGE_MCS) | (1 << ISL_AUX_USAGE_CCS_E), &src_level, src_layer, 1, &tmp_surfs[0]); blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true, (1 << ISL_AUX_USAGE_MCS) | (1 << ISL_AUX_USAGE_CCS_E), &dst_level, dst_layer, 1, &tmp_surfs[2]); struct blorp_batch batch; blorp_batch_init(&brw->blorp, &batch, brw, 0); blorp_copy(&batch, &src_surf, src_level, src_layer, &dst_surf, dst_level, dst_layer, src_x, src_y, dst_x, dst_y, src_width, src_height); blorp_batch_finish(&batch); }