fprintf(stderr, "%s:%d: FINISHME: %s\n", file, line, buf);
}
+static void
+isl_device_setup_mocs(struct isl_device *dev)
+{
+ if (dev->info->gen >= 12) {
+ /* TODO: Set PTE to MOCS 61 when the kernel is ready */
+ /* TC=1/LLC Only, LeCC=1/Uncacheable, LRUM=0, L3CC=1/Uncacheable */
+ dev->mocs.external = 3 << 1;
+ /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */
+ dev->mocs.internal = 2 << 1;
+ } else if (dev->info->gen >= 9) {
+ /* TC=LLC/eLLC, LeCC=PTE, LRUM=3, L3CC=WB */
+ dev->mocs.external = 1 << 1;
+ /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */
+ dev->mocs.internal = 2 << 1;
+ } else if (dev->info->gen >= 8) {
+ /* MEMORY_OBJECT_CONTROL_STATE:
+ * .MemoryTypeLLCeLLCCacheabilityControl = UCwithFenceifcoherentcycle,
+ * .TargetCache = L3DefertoPATforLLCeLLCselection,
+ * .AgeforQUADLRU = 0
+ */
+ dev->mocs.external = 0x18;
+ /* MEMORY_OBJECT_CONTROL_STATE:
+ * .MemoryTypeLLCeLLCCacheabilityControl = WB,
+ * .TargetCache = L3DefertoPATforLLCeLLCselection,
+ * .AgeforQUADLRU = 0
+ */
+ dev->mocs.internal = 0x78;
+ } else if (dev->info->gen >= 7) {
+ if (dev->info->is_haswell) {
+ /* MEMORY_OBJECT_CONTROL_STATE:
+ * .LLCeLLCCacheabilityControlLLCCC = 0,
+ * .L3CacheabilityControlL3CC = 1,
+ */
+ dev->mocs.internal = 1;
+ dev->mocs.external = 1;
+ } else {
+ /* MEMORY_OBJECT_CONTROL_STATE:
+ * .GraphicsDataTypeGFDT = 0,
+ * .LLCCacheabilityControlLLCCC = 0,
+ * .L3CacheabilityControlL3CC = 1,
+ */
+ dev->mocs.internal = 1;
+ dev->mocs.external = 1;
+ }
+ } else {
+ dev->mocs.internal = 0;
+ dev->mocs.external = 0;
+ }
+}
+
void
isl_device_init(struct isl_device *dev,
const struct gen_device_info *info,
dev->ds.stencil_offset = 0;
dev->ds.hiz_offset = 0;
}
+
+ isl_device_setup_mocs(dev);
}
/**
}
static uint32_t
-isl_calc_row_pitch_alignment(const struct isl_surf_init_info *surf_info,
+isl_calc_row_pitch_alignment(const struct isl_device *dev,
+ const struct isl_surf_init_info *surf_info,
const struct isl_tile_info *tile_info)
{
- if (tile_info->tiling != ISL_TILING_LINEAR)
+ if (tile_info->tiling != ISL_TILING_LINEAR) {
+ /* According to BSpec: 44930, Gen12's CCS-compressed surface pitches must
+ * be 512B-aligned. CCS is only support on Y tilings.
+ */
+ if (ISL_DEV_GEN(dev) >= 12 &&
+ isl_format_supports_ccs_e(dev->info, surf_info->format) &&
+ tile_info->tiling != ISL_TILING_X) {
+ return isl_align(tile_info->phys_extent_B.width, 512);
+ }
+
return tile_info->phys_extent_B.width;
+ }
/* From the Broadwel PRM >> Volume 2d: Command Reference: Structures >>
* RENDER_SURFACE_STATE Surface Pitch (p349):
isl_align_div(phys_total_el->w * tile_el_scale,
tile_info->logical_extent_el.width);
- assert(alignment_B == tile_info->phys_extent_B.width);
- return total_w_tl * tile_info->phys_extent_B.width;
+ /* In some cases the alignment of the pitch might be > to the tile size
+ * (for example Gen12 CCS requires 512B alignment while the tile's width
+ * can be 128B), so align the row pitch to the alignment.
+ */
+ assert(alignment_B >= tile_info->phys_extent_B.width);
+ return isl_align(total_w_tl * tile_info->phys_extent_B.width, alignment_B);
}
static uint32_t
uint32_t *out_row_pitch_B)
{
uint32_t alignment_B =
- isl_calc_row_pitch_alignment(surf_info, tile_info);
+ isl_calc_row_pitch_alignment(dev, surf_info, tile_info);
const uint32_t min_row_pitch_B =
isl_calc_min_row_pitch(dev, surf_info, tile_info, phys_total_el,
}
const uint32_t row_pitch_B =
- surf_info->row_pitch_B != 0 ?
- surf_info->row_pitch_B :
- /* According to BSpec: 44930, Gen12's CCS-compressed surface pitches
- * must be 512B-aligned.
- */
- ISL_DEV_GEN(dev) >= 12 &&
- isl_format_supports_ccs_e(dev->info, surf_info->format) ?
- isl_align(min_row_pitch_B, 512) :
- /* Else */
- min_row_pitch_B;
+ surf_info->row_pitch_B != 0 ? surf_info->row_pitch_B : min_row_pitch_B;
const uint32_t row_pitch_tl = row_pitch_B / tile_info->phys_extent_B.width;
if (surf->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)
return false;
- /* Callers don't yet support this configuration. */
- if (isl_surf_usage_is_stencil(surf->usage))
+ /* Allow CCS for single-sampled stencil buffers Gen12+. */
+ if (isl_surf_usage_is_stencil(surf->usage) &&
+ (ISL_DEV_GEN(dev) < 12 || surf->samples > 1))
return false;
/* [TGL+] CCS can only be added to a non-D16-formatted depth buffer if it
return false;
}
+ /* GEN:BUG:1207137018
+ *
+ * TODO: implement following workaround currently covered by the restriction
+ * above. If following conditions are met:
+ *
+ * - RENDER_SURFACE_STATE.Surface Type == 3D
+ * - RENDER_SURFACE_STATE.Auxiliary Surface Mode != AUX_NONE
+ * - RENDER_SURFACE_STATE.Tiled ResourceMode is TYF or TYS
+ *
+ * Set the value of RENDER_SURFACE_STATE.Mip Tail Start LOD to a mip that
+ * larger than those present in the surface (i.e. 15)
+ */
+
/* TODO: More conditions where it can fail. */
/* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
if (surf->tiling != ISL_TILING_Y0)
return false;
+ /* BSpec 44930:
+ *
+ * Linear CCS is only allowed for Untyped Buffers but only via HDC
+ * Data-Port messages.
+ *
+ * We probably want to limit linear CCS to storage usage and check that
+ * the shaders actually use only untyped messages.
+ */
+ assert(surf->tiling != ISL_TILING_LINEAR);
+
switch (isl_format_get_layout(surf->format)->bpb) {
case 8: ccs_format = ISL_FORMAT_GEN12_CCS_8BPP_Y0; break;
case 16: ccs_format = ISL_FORMAT_GEN12_CCS_16BPP_Y0; break;
isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info)
{
- isl_genX_call(dev, buffer_fill_state_s, state, info);
+ isl_genX_call(dev, buffer_fill_state_s, dev, state, info);
}
void
}
}
+void
+isl_surf_get_image_range_B_tile(const struct isl_surf *surf,
+ uint32_t level,
+ uint32_t logical_array_layer,
+ uint32_t logical_z_offset_px,
+ uint32_t *start_tile_B,
+ uint32_t *end_tile_B)
+{
+ uint32_t start_x_offset_el, start_y_offset_el;
+ isl_surf_get_image_offset_el(surf, level, logical_array_layer,
+ logical_z_offset_px,
+ &start_x_offset_el,
+ &start_y_offset_el);
+
+ /* Compute the size of the subimage in surface elements */
+ const uint32_t subimage_w_sa = isl_minify(surf->phys_level0_sa.w, level);
+ const uint32_t subimage_h_sa = isl_minify(surf->phys_level0_sa.h, level);
+ const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format);
+ const uint32_t subimage_w_el = isl_align_div_npot(subimage_w_sa, fmtl->bw);
+ const uint32_t subimage_h_el = isl_align_div_npot(subimage_h_sa, fmtl->bh);
+
+ /* Find the last pixel */
+ uint32_t end_x_offset_el = start_x_offset_el + subimage_w_el - 1;
+ uint32_t end_y_offset_el = start_y_offset_el + subimage_h_el - 1;
+
+ UNUSED uint32_t x_offset_el, y_offset_el;
+ isl_tiling_get_intratile_offset_el(surf->tiling, fmtl->bpb,
+ surf->row_pitch_B,
+ start_x_offset_el,
+ start_y_offset_el,
+ start_tile_B,
+ &x_offset_el,
+ &y_offset_el);
+
+ isl_tiling_get_intratile_offset_el(surf->tiling, fmtl->bpb,
+ surf->row_pitch_B,
+ end_x_offset_el,
+ end_y_offset_el,
+ end_tile_B,
+ &x_offset_el,
+ &y_offset_el);
+
+ /* We want the range we return to be exclusive but the tile containing the
+ * last pixel (what we just calculated) is inclusive. Add one.
+ */
+ (*end_tile_B)++;
+
+ assert(*end_tile_B <= surf->size_B);
+}
+
void
isl_surf_get_image_surf(const struct isl_device *dev,
const struct isl_surf *surf,