diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 5c38ba6adb6..cff57a356ac 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -59,9 +59,6 @@ struct brw_blorp_blit_vars { nir_variable *v_src_offset; nir_variable *v_dst_offset; nir_variable *v_src_inv_size; - - /* gl_FragColor */ - nir_variable *color_out; }; static void @@ -80,10 +77,6 @@ brw_blorp_blit_vars_init(nir_builder *b, struct brw_blorp_blit_vars *v, LOAD_INPUT(src_inv_size, glsl_vector_type(GLSL_TYPE_FLOAT, 2)) #undef LOAD_INPUT - - v->color_out = nir_variable_create(b->shader, nir_var_shader_out, - glsl_vec4_type(), "gl_FragColor"); - v->color_out->data.location = FRAG_RESULT_COLOR; } static nir_ssa_def * @@ -1472,7 +1465,27 @@ brw_blorp_build_nir_shader(struct blorp_context *blorp, void *mem_ctx, color = nir_vec4(&b, color_component, u, u, u); } - nir_store_var(&b, v.color_out, color, 0xf); + if (key->dst_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT) { + nir_variable *color_out = + nir_variable_create(b.shader, nir_var_shader_out, + glsl_vec4_type(), "gl_FragColor"); + color_out->data.location = FRAG_RESULT_COLOR; + nir_store_var(&b, color_out, color, 0xf); + } else if (key->dst_usage == ISL_SURF_USAGE_DEPTH_BIT) { + nir_variable *depth_out = + nir_variable_create(b.shader, nir_var_shader_out, + glsl_float_type(), "gl_FragDepth"); + depth_out->data.location = FRAG_RESULT_DEPTH; + nir_store_var(&b, depth_out, nir_channel(&b, color, 0), 0x1); + } else if (key->dst_usage == ISL_SURF_USAGE_STENCIL_BIT) { + nir_variable *stencil_out = + nir_variable_create(b.shader, nir_var_shader_out, + glsl_int_type(), "gl_FragStencilRef"); + stencil_out->data.location = FRAG_RESULT_STENCIL; + nir_store_var(&b, stencil_out, nir_channel(&b, color, 0), 0x1); + } else { + unreachable("Invalid destination usage"); + } return b.shader; } @@ -1808,6 +1821,30 @@ try_blorp_blit(struct blorp_batch *batch, { const struct gen_device_info *devinfo = batch->blorp->isl_dev->info; + if (params->dst.surf.usage & ISL_SURF_USAGE_DEPTH_BIT) { + if (devinfo->gen >= 7) { + /* We can render as depth on Gen5 but there's no real advantage since + * it doesn't support MSAA or HiZ. On Gen4, we can't always render + * to depth due to issues with depth buffers and mip-mapping. On + * Gen6, we can do everything but we have weird offsetting for HiZ + * and stencil. It's easier to just render using the color pipe + * on those platforms. + */ + wm_prog_key->dst_usage = ISL_SURF_USAGE_DEPTH_BIT; + } else { + wm_prog_key->dst_usage = ISL_SURF_USAGE_RENDER_TARGET_BIT; + } + } else if (params->dst.surf.usage & ISL_SURF_USAGE_STENCIL_BIT) { + assert(params->dst.surf.format == ISL_FORMAT_R8_UINT); + if (devinfo->gen >= 9) { + wm_prog_key->dst_usage = ISL_SURF_USAGE_STENCIL_BIT; + } else { + wm_prog_key->dst_usage = ISL_SURF_USAGE_RENDER_TARGET_BIT; + } + } else { + wm_prog_key->dst_usage = ISL_SURF_USAGE_RENDER_TARGET_BIT; + } + if (isl_format_has_sint_channel(params->src.view.format)) { wm_prog_key->texture_data_type = nir_type_int; } else if (isl_format_has_uint_channel(params->src.view.format)) { @@ -1862,6 +1899,7 @@ try_blorp_blit(struct blorp_batch *batch, } if (devinfo->gen > 6 && + !isl_surf_usage_is_depth_or_stencil(wm_prog_key->dst_usage) && params->dst.surf.msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED) { assert(params->dst.surf.samples > 1); @@ -1890,7 +1928,8 @@ try_blorp_blit(struct blorp_batch *batch, wm_prog_key->need_dst_offset = true; } - if (params->dst.surf.tiling == ISL_TILING_W) { + if (params->dst.surf.tiling == ISL_TILING_W && + wm_prog_key->dst_usage != ISL_SURF_USAGE_STENCIL_BIT) { /* We must modify the rectangle we send through the rendering pipeline * (and the size and x/y offset of the destination surface), to account * for the fact that we are mapping it as Y-tiled when it is in fact @@ -2034,7 +2073,8 @@ try_blorp_blit(struct blorp_batch *batch, /* We can handle RGBX formats easily enough by treating them as RGBA */ params->dst.view.format = isl_format_rgbx_to_rgba(params->dst.view.format); - } else if (params->dst.view.format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) { + } else if (params->dst.view.format == ISL_FORMAT_R24_UNORM_X8_TYPELESS && + wm_prog_key->dst_usage != ISL_SURF_USAGE_DEPTH_BIT) { wm_prog_key->dst_format = params->dst.view.format; params->dst.view.format = ISL_FORMAT_R32_UINT; } else if (params->dst.view.format == ISL_FORMAT_A4B4G4R4_UNORM) { @@ -2106,6 +2146,15 @@ try_blorp_blit(struct blorp_batch *batch, result |= BLIT_DST_HEIGHT_SHRINK; if (result == 0) { + if (wm_prog_key->dst_usage == ISL_SURF_USAGE_DEPTH_BIT) { + params->depth = params->dst; + memset(¶ms->dst, 0, sizeof(params->dst)); + } else if (wm_prog_key->dst_usage == ISL_SURF_USAGE_STENCIL_BIT) { + params->stencil = params->dst; + params->stencil_mask = 0xff; + memset(¶ms->dst, 0, sizeof(params->dst)); + } + batch->blorp->exec(batch, params); } @@ -2628,18 +2677,20 @@ blorp_copy(struct blorp_batch *batch, params.src.aux_usage == ISL_AUX_USAGE_MCS || params.src.aux_usage == ISL_AUX_USAGE_MCS_CCS || params.src.aux_usage == ISL_AUX_USAGE_CCS_E); - assert(params.dst.aux_usage == ISL_AUX_USAGE_NONE || - params.dst.aux_usage == ISL_AUX_USAGE_MCS || - params.dst.aux_usage == ISL_AUX_USAGE_MCS_CCS || - params.dst.aux_usage == ISL_AUX_USAGE_CCS_E); if (params.src.aux_usage == ISL_AUX_USAGE_HIZ) { - /* Depth <-> Color copies are not allowed and HiZ isn't allowed in - * destinations because we draw as color. + /* In order to use HiZ, we have to use the real format for the source. + * Depth <-> Color copies are not allowed. */ - assert(params.dst.aux_usage == ISL_AUX_USAGE_NONE); params.src.view.format = params.src.surf.format; params.dst.view.format = params.src.surf.format; + } else if ((params.dst.surf.usage & ISL_SURF_USAGE_DEPTH_BIT) && + isl_dev->info->gen >= 7) { + /* On Gen7 and higher, we use actual depth writes for blits into depth + * buffers so we need the real format. + */ + params.src.view.format = params.dst.surf.format; + params.dst.view.format = params.dst.surf.format; } else if (params.dst.aux_usage == ISL_AUX_USAGE_CCS_E) { params.dst.view.format = get_ccs_compatible_copy_format(dst_fmtl); if (params.src.aux_usage == ISL_AUX_USAGE_CCS_E) { diff --git a/src/intel/blorp/blorp_genX_exec.h b/src/intel/blorp/blorp_genX_exec.h index 50ac4489a52..a77cff3716c 100644 --- a/src/intel/blorp/blorp_genX_exec.h +++ b/src/intel/blorp/blorp_genX_exec.h @@ -902,6 +902,10 @@ blorp_emit_ps_config(struct blorp_batch *batch, psx.PixelShaderValid = true; psx.AttributeEnable = prog_data->num_varying_inputs > 0; psx.PixelShaderIsPerSample = prog_data->persample_dispatch; + psx.PixelShaderComputedDepthMode = prog_data->computed_depth_mode; +#if GEN_GEN >= 9 + psx.PixelShaderComputesStencil = prog_data->computed_stencil; +#endif } if (params->src.enabled) @@ -927,8 +931,10 @@ blorp_emit_ps_config(struct blorp_batch *batch, unreachable("not reached"); } - if (prog_data) + if (prog_data) { wm.ThreadDispatchEnable = true; + wm.PixelShaderComputedDepthMode = prog_data->computed_depth_mode; + } if (params->src.enabled) wm.PixelShaderKillsPixel = true; diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index ddd118f1349..63b0ce9a88d 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -319,6 +319,8 @@ struct brw_blorp_blit_prog_key */ bool dst_rgb; + isl_surf_usage_flags_t dst_usage; + enum blorp_filter filter; /* True if the rectangle being sent through the rendering pipeline might be