case GL_DEPTH_STENCIL:
return INTEL_MSAA_LAYOUT_IMS;
default:
- /* Disable MCS on Broadwell for now. We can enable it once things
- * are working without it.
- */
- if (brw->gen >= 8) {
- perf_debug("Missing CMS support on Broadwell.\n");
- return INTEL_MSAA_LAYOUT_UMS;
- }
-
/* From the Ivy Bridge PRM, Vol4 Part1 p77 ("MCS Enable"):
*
* This field must be set to 0 for all SINT MSRTs when all RT channels
{
switch (mt->tiling) {
default:
- assert(!"Non-MSRT MCS requires X or Y tiling");
+ unreachable("Non-MSRT MCS requires X or Y tiling");
/* In release builds, fall through */
case I915_TILING_Y:
*width_px = 32 / mt->cpp;
struct intel_mipmap_tree *mt)
{
/* MCS support does not exist prior to Gen7 */
- if (brw->gen < 7 || brw->gen >= 8)
+ if (brw->gen < 7)
return false;
/* MCS is only supported for color buffers */
GLuint height0,
GLuint depth0,
bool for_bo,
- GLuint num_samples)
+ GLuint num_samples,
+ bool force_all_slices_at_each_lod)
{
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
if (!mt)
_mesa_get_format_name(format),
first_level, last_level, depth0, mt);
+ if (target == GL_TEXTURE_1D_ARRAY) {
+ /* For a 1D Array texture the OpenGL API will treat the height0
+ * parameter as the number of array slices. For Intel hardware, we treat
+ * the 1D array as a 2D Array with a height of 1.
+ *
+ * So, when we first come through this path to create a 1D Array
+ * texture, height0 stores the number of slices, and depth0 is 1. In
+ * this case, we want to swap height0 and depth0.
+ *
+ * Since some miptrees will be created based on the base miptree, we may
+ * come through this path and see height0 as 1 and depth0 being the
+ * number of slices. In this case we don't need to do the swap.
+ */
+ assert(height0 == 1 || depth0 == 1);
+ if (height0 > 1) {
+ depth0 = height0;
+ height0 = 1;
+ }
+ }
+
mt->target = target;
mt->format = format;
mt->first_level = first_level;
/* num_samples should already have been quantized to 0, 1, 2, 4, or
* 8.
*/
- assert(false);
+ unreachable("not reached");
}
} else {
/* Non-interleaved */
}
}
- /* array_spacing_lod0 is only used for non-IMS MSAA surfaces. TODO: can we
- * use it elsewhere?
+ /* Set array_layout to ALL_SLICES_AT_EACH_LOD when gen7+ array_spacing_lod0
+ * can be used. array_spacing_lod0 is only used for non-IMS MSAA surfaces.
+ * TODO: can we use it elsewhere?
*/
switch (mt->msaa_layout) {
case INTEL_MSAA_LAYOUT_NONE:
case INTEL_MSAA_LAYOUT_IMS:
- mt->array_spacing_lod0 = false;
+ mt->array_layout = ALL_LOD_IN_EACH_SLICE;
break;
case INTEL_MSAA_LAYOUT_UMS:
case INTEL_MSAA_LAYOUT_CMS:
- mt->array_spacing_lod0 = true;
+ mt->array_layout = ALL_SLICES_AT_EACH_LOD;
break;
}
_mesa_get_format_base_format(format) == GL_DEPTH_STENCIL &&
(brw->must_use_separate_stencil ||
(brw->has_separate_stencil && brw_is_hiz_depth_format(brw, format)))) {
+ const bool force_all_slices_at_each_lod = brw->gen == 6;
mt->stencil_mt = intel_miptree_create(brw,
mt->target,
MESA_FORMAT_S_UINT8,
mt->logical_depth0,
true,
num_samples,
- INTEL_MIPTREE_TILING_ANY);
+ INTEL_MIPTREE_TILING_ANY,
+ force_all_slices_at_each_lod);
if (!mt->stencil_mt) {
intel_miptree_release(&mt);
return NULL;
}
}
+ if (force_all_slices_at_each_lod)
+ mt->array_layout = ALL_SLICES_AT_EACH_LOD;
+
brw_miptree_layout(brw, mt);
return mt;
GLuint depth0,
bool expect_accelerated_upload,
GLuint num_samples,
- enum intel_miptree_tiling_mode requested_tiling)
+ enum intel_miptree_tiling_mode requested_tiling,
+ bool force_all_slices_at_each_lod)
{
struct intel_mipmap_tree *mt;
mesa_format tex_format = format;
mt = intel_miptree_create_layout(brw, target, format,
first_level, last_level, width0,
height0, depth0,
- false, num_samples);
+ false, num_samples,
+ force_all_slices_at_each_lod);
/*
* pitch == 0 || height == 0 indicates the null texture
*/
mt = intel_miptree_create_layout(brw, GL_TEXTURE_2D, format,
0, 0,
width, height, 1,
- true, 0 /* num_samples */);
+ true, 0, false);
if (!mt) {
free(mt);
return mt;
mt = intel_miptree_create(brw, target, format, 0, 0,
width, height, depth, true, num_samples,
- INTEL_MIPTREE_TILING_ANY);
+ INTEL_MIPTREE_TILING_ANY, false);
if (!mt)
goto fail;
switch (tiling) {
default:
- assert(false);
+ unreachable("not reached");
case I915_TILING_NONE:
*mask_x = *mask_y = 0;
break;
switch (tiling) {
default:
- assert(false);
+ unreachable("not reached");
case I915_TILING_NONE:
return y * pitch + x * cpp;
case I915_TILING_X:
*/
mesa_format format;
switch (num_samples) {
+ case 2:
case 4:
/* 8 bits/pixel are required for MCS data when using 4x MSAA (2 bits for
* each sample).
format = MESA_FORMAT_R_UINT32;
break;
default:
- assert(!"Unrecognized sample count in intel_miptree_alloc_mcs");
- return false;
+ unreachable("Unrecognized sample count in intel_miptree_alloc_mcs");
};
/* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
mt->logical_depth0,
true,
0 /* num_samples */,
- INTEL_MIPTREE_TILING_Y);
+ INTEL_MIPTREE_TILING_Y,
+ false);
/* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
*
mt->logical_depth0,
true,
0 /* num_samples */,
- INTEL_MIPTREE_TILING_Y);
+ INTEL_MIPTREE_TILING_Y,
+ false);
return mt->mcs_mt;
}
struct intel_mipmap_tree *mt)
{
assert(mt->hiz_mt == NULL);
+ const bool force_all_slices_at_each_lod = brw->gen == 6;
mt->hiz_mt = intel_miptree_create(brw,
mt->target,
mt->format,
mt->logical_depth0,
true,
mt->num_samples,
- INTEL_MIPTREE_TILING_ANY);
+ INTEL_MIPTREE_TILING_ANY,
+ force_all_slices_at_each_lod);
if (!mt->hiz_mt)
return false;
{
bool did_resolve = false;
- foreach_list_safe(node, &mt->hiz_map) {
- struct intel_resolve_map *map = (struct intel_resolve_map *)node;
-
+ foreach_list_typed_safe(struct intel_resolve_map, map, link, &mt->hiz_map) {
if (map->need != need)
continue;
case INTEL_FAST_CLEAR_STATE_CLEAR:
/* Fast color clear resolves only make sense for non-MSAA buffers. */
if (mt->msaa_layout == INTEL_MSAA_LAYOUT_NONE)
- brw_blorp_resolve_color(brw, mt);
+ brw_meta_resolve_color(brw, mt);
break;
}
}
{
if (brw->gen < 8) {
brw_blorp_blit_miptrees(brw,
- src, 0 /* level */, 0 /* layer */,
- dst, 0 /* level */, 0 /* layer */,
+ src, 0 /* level */, 0 /* layer */, src->format,
+ dst, 0 /* level */, 0 /* layer */, dst->format,
0, 0,
src->logical_width0, src->logical_height0,
0, 0,
brw_blorp_blit_miptrees(brw,
src->stencil_mt, 0 /* level */, 0 /* layer */,
+ src->stencil_mt->format,
dst->stencil_mt, 0 /* level */, 0 /* layer */,
+ dst->stencil_mt->format,
0, 0,
src->logical_width0, src->logical_height0,
0, 0,
0, 0,
map->w, map->h, 1,
false, 0,
- INTEL_MIPTREE_TILING_NONE);
+ INTEL_MIPTREE_TILING_NONE,
+ false);
if (!map->mt) {
fprintf(stderr, "Failed to allocate blit temporary\n");
goto fail;
/**
* "Map" a buffer by copying it to an untiled temporary using MOVNTDQA.
*/
+#if defined(USE_SSE41)
static void
intel_miptree_map_movntdqa(struct brw_context *brw,
struct intel_mipmap_tree *mt,
map->buffer = NULL;
map->ptr = NULL;
}
+#endif
static void
intel_miptree_map_s8(struct brw_context *brw,
x + s_image_x + map->x,
y + s_image_y + map->y,
brw->has_swizzling);
- ptrdiff_t z_offset = ((y + z_image_y) *
+ ptrdiff_t z_offset = ((y + z_image_y + map->y) *
(z_mt->pitch / 4) +
- (x + z_image_x));
+ (x + z_image_x + map->x));
if (map_z32f_x24s8) {
z_map[z_offset] = packed_map[(y * map->w + x) * 2 + 0];
mt->bo->size >= brw->max_gtt_map_object_size) {
assert(can_blit_slice(mt, level, slice));
intel_miptree_map_blit(brw, mt, map, level, slice);
+#if defined(USE_SSE41)
} else if (!(mode & GL_MAP_WRITE_BIT) && !mt->compressed && cpu_has_sse4_1) {
intel_miptree_map_movntdqa(brw, mt, map, level, slice);
+#endif
} else {
intel_miptree_map_gtt(brw, mt, map, level, slice);
}
intel_miptree_unmap_depthstencil(brw, mt, map, level, slice);
} else if (map->mt) {
intel_miptree_unmap_blit(brw, mt, map, level, slice);
+#if defined(USE_SSE41)
} else if (map->buffer && cpu_has_sse4_1) {
intel_miptree_unmap_movntdqa(brw, mt, map, level, slice);
+#endif
} else {
intel_miptree_unmap_gtt(brw, mt, map, level, slice);
}