nir_variable *v_dst_offset;
nir_variable *v_src_inv_size;
- /* gl_FragCoord */
- nir_variable *frag_coord;
-
/* gl_FragColor */
nir_variable *color_out;
};
#undef LOAD_INPUT
- v->frag_coord = nir_variable_create(b->shader, nir_var_shader_in,
- glsl_vec4_type(), "gl_FragCoord");
- v->frag_coord->data.location = VARYING_SLOT_POS;
-
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;
const struct brw_blorp_blit_prog_key *key,
struct brw_blorp_blit_vars *v)
{
- nir_ssa_def *coord = nir_f2i32(b, nir_load_var(b, v->frag_coord));
+ nir_ssa_def *coord = nir_f2i32(b, nir_load_frag_coord(b));
/* Account for destination surface intratile offset
*
return nir_load_var(b, color);
}
-static inline nir_ssa_def *
-nir_imm_vec2(nir_builder *build, float x, float y)
-{
- nir_const_value v;
-
- memset(&v, 0, sizeof(v));
- v.f32[0] = x;
- v.f32[1] = y;
-
- return nir_build_imm(build, 4, 32, v);
-}
-
static nir_ssa_def *
blorp_nir_manual_blend_bilinear(nir_builder *b, nir_ssa_def *pos,
unsigned tex_samples,
color = bit_cast_color(&b, color, key);
} else if (key->dst_format) {
color = convert_color(&b, color, key);
+ } else if (key->uint32_to_sint) {
+ /* Normally the hardware will take care of converting values from/to
+ * the source and destination formats. But a few cases need help.
+ *
+ * The Skylake PRM, volume 07, page 658 has a programming note:
+ *
+ * "When using SINT or UINT rendertarget surface formats, Blending
+ * must be DISABLED. The Pre-Blend Color Clamp Enable and Color
+ * Clamp Range fields are ignored, and an implied clamp to the
+ * rendertarget surface format is performed."
+ *
+ * For UINT to SINT blits, our sample operation gives us a uint32_t,
+ * but our render target write expects a signed int32_t number. If we
+ * simply passed the value along, the hardware would interpret a value
+ * with bit 31 set as a negative value, clamping it to the largest
+ * negative number the destination format could represent. But the
+ * actual source value is a positive number, so we want to clamp it
+ * to INT_MAX. To fix this, we explicitly take min(color, INT_MAX).
+ */
+ color = nir_umin(&b, color, nir_imm_int(&b, INT32_MAX));
+ } else if (key->sint32_to_uint) {
+ /* Similar to above, but clamping negative numbers to zero. */
+ color = nir_imax(&b, color, nir_imm_int(&b, 0));
}
if (key->dst_rgb) {
struct brw_wm_prog_key wm_key;
brw_blorp_init_wm_prog_key(&wm_key);
- wm_key.tex.compressed_multisample_layout_mask =
+ wm_key.base.tex.compressed_multisample_layout_mask =
prog_key->tex_aux_usage == ISL_AUX_USAGE_MCS;
- wm_key.tex.msaa_16 = prog_key->tex_samples == 16;
+ wm_key.base.tex.msaa_16 = prog_key->tex_samples == 16;
wm_key.multisample_fbo = prog_key->rt_samples > 1;
program = blorp_compile_fs(blorp, mem_ctx, nir, &wm_key, false,
info->z_offset = 0;
}
-static void
-surf_fake_interleaved_msaa(const struct isl_device *isl_dev,
- struct brw_blorp_surface_info *info)
+void
+blorp_surf_fake_interleaved_msaa(const struct isl_device *isl_dev,
+ struct brw_blorp_surface_info *info)
{
assert(info->surf.msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED);
info->surf.msaa_layout = ISL_MSAA_LAYOUT_NONE;
}
-static void
-surf_retile_w_to_y(const struct isl_device *isl_dev,
- struct brw_blorp_surface_info *info)
+void
+blorp_surf_retile_w_to_y(const struct isl_device *isl_dev,
+ struct brw_blorp_surface_info *info)
{
assert(info->surf.tiling == ISL_TILING_W);
*/
if (isl_dev->info->gen > 6 &&
info->surf.msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED) {
- surf_fake_interleaved_msaa(isl_dev, info);
+ blorp_surf_fake_interleaved_msaa(isl_dev, info);
}
if (isl_dev->info->gen == 6) {
params->x1 = ALIGN(params->x1, 2) * px_size_sa.width;
params->y1 = ALIGN(params->y1, 2) * px_size_sa.height;
- surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms->dst);
+ blorp_surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms->dst);
wm_prog_key->use_kill = true;
wm_prog_key->need_dst_offset = true;
params->y1 = ALIGN(params->y1, y_align) / 2;
/* Retile the surface to Y-tiled */
- surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms->dst);
+ blorp_surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms->dst);
wm_prog_key->dst_tiled_w = true;
wm_prog_key->use_kill = true;
*
* TODO: what if this makes the texture size too large?
*/
- surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms->src);
+ blorp_surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms->src);
wm_prog_key->src_tiled_w = true;
wm_prog_key->need_src_offset = true;
params.src.view.swizzle = src_swizzle;
params.dst.view.swizzle = dst_swizzle;
+ const struct isl_format_layout *src_fmtl =
+ isl_format_get_layout(params.src.view.format);
+
struct brw_blorp_blit_prog_key wm_prog_key = {
.shader_type = BLORP_SHADER_TYPE_BLIT,
.filter = filter,
+ .sint32_to_uint = src_fmtl->channels.r.bits == 32 &&
+ isl_format_has_sint_channel(params.src.view.format) &&
+ isl_format_has_uint_channel(params.dst.view.format),
+ .uint32_to_sint = src_fmtl->channels.r.bits == 32 &&
+ isl_format_has_uint_channel(params.src.view.format) &&
+ isl_format_has_sint_channel(params.dst.view.format),
};
/* Scaling factors used for bilinear filtering in multisample scaled
*y /= fmtl->bh;
}
- info->surf.logical_level0_px.width =
- DIV_ROUND_UP(info->surf.logical_level0_px.width, fmtl->bw);
- info->surf.logical_level0_px.height =
- DIV_ROUND_UP(info->surf.logical_level0_px.height, fmtl->bh);
-
- assert(info->surf.phys_level0_sa.width % fmtl->bw == 0);
- assert(info->surf.phys_level0_sa.height % fmtl->bh == 0);
- info->surf.phys_level0_sa.width /= fmtl->bw;
- info->surf.phys_level0_sa.height /= fmtl->bh;
+ info->surf.logical_level0_px = isl_surf_get_logical_level0_el(&info->surf);
+ info->surf.phys_level0_sa = isl_surf_get_phys_level0_el(&info->surf);
assert(info->tile_x_sa % fmtl->bw == 0);
assert(info->tile_y_sa % fmtl->bh == 0);