return VK_SUCCESS;
}
-
-static const uint8_t anv_halign[] = {
- [4] = HALIGN_4,
- [8] = HALIGN_8,
-};
-
-static const uint8_t anv_valign[] = {
- [2] = VALIGN_2,
- [4] = VALIGN_4,
-};
-
-void
-genX(fill_image_surface_state)(struct anv_device *device, void *state_map,
- struct anv_image_view *iview,
- const VkImageViewCreateInfo *pCreateInfo,
- VkImageUsageFlagBits usage)
-{
- if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
- anv_finishme("non-2D image views");
-
- assert(usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT |
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
- assert(util_is_power_of_two(usage));
-
- ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
- const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
- bool is_storage = (usage == VK_IMAGE_USAGE_STORAGE_BIT);
- struct anv_surface *surface =
- anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
-
- uint32_t depth = 1;
- if (range->layerCount > 1) {
- depth = range->layerCount;
- } else if (image->extent.depth > 1) {
- depth = image->extent.depth;
- }
-
- const struct isl_extent3d image_align_sa =
- isl_surf_get_image_alignment_sa(&surface->isl);
-
- struct GENX(RENDER_SURFACE_STATE) template = {
- .SurfaceType = anv_surftype(image, pCreateInfo->viewType,
- usage == VK_IMAGE_USAGE_STORAGE_BIT),
- .SurfaceArray = image->array_size > 1,
- .SurfaceFormat = anv_surface_format(device, iview->format, is_storage),
- .SurfaceVerticalAlignment = anv_valign[image_align_sa.height],
- .SurfaceHorizontalAlignment = anv_halign[image_align_sa.width],
-
- /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
- * Tiled Surface is False."
- */
- .TiledSurface = surface->isl.tiling != ISL_TILING_LINEAR,
- .TileWalk = surface->isl.tiling == ISL_TILING_Y0 ?
- TILEWALK_YMAJOR : TILEWALK_XMAJOR,
-
- .VerticalLineStride = 0,
- .VerticalLineStrideOffset = 0,
-
- .RenderCacheReadWriteMode = 0, /* TEMPLATE */
-
- .Height = image->extent.height - 1,
- .Width = image->extent.width - 1,
- .Depth = depth - 1,
- .SurfacePitch = surface->isl.row_pitch - 1,
- .MinimumArrayElement = range->baseArrayLayer,
- .NumberofMultisamples = MULTISAMPLECOUNT_1,
- .XOffset = 0,
- .YOffset = 0,
-
- .SurfaceObjectControlState = GENX(MOCS),
-
- .MIPCountLOD = 0, /* TEMPLATE */
- .SurfaceMinLOD = 0, /* TEMPLATE */
-
- .MCSEnable = false,
-# if (GEN_IS_HASWELL)
- .ShaderChannelSelectRed = vk_to_gen_swizzle[iview->swizzle.r],
- .ShaderChannelSelectGreen = vk_to_gen_swizzle[iview->swizzle.g],
- .ShaderChannelSelectBlue = vk_to_gen_swizzle[iview->swizzle.b],
- .ShaderChannelSelectAlpha = vk_to_gen_swizzle[iview->swizzle.a],
-# else /* XXX: Seriously? */
- .RedClearColor = 0,
- .GreenClearColor = 0,
- .BlueClearColor = 0,
- .AlphaClearColor = 0,
-# endif
- .ResourceMinLOD = 0.0,
- .SurfaceBaseAddress = { NULL, iview->offset },
- };
-
- if (usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
- /* For render target surfaces, the hardware interprets field
- * MIPCount/LOD as LOD. The Broadwell PRM says:
- *
- * MIPCountLOD defines the LOD that will be rendered into.
- * SurfaceMinLOD is ignored.
- */
- template.MIPCountLOD = range->baseMipLevel;
- template.SurfaceMinLOD = 0;
- } else {
- /* For non render target surfaces, the hardware interprets field
- * MIPCount/LOD as MIPCount. The range of levels accessible by the
- * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
- */
- template.SurfaceMinLOD = range->baseMipLevel;
- template.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
- }
-
- GENX(RENDER_SURFACE_STATE_pack)(NULL, state_map, &template);
-}
return anv_device_submit_simple_batch(device, &batch);
}
-static const uint32_t
-isl_to_gen_multisample_layout[] = {
- [ISL_MSAA_LAYOUT_NONE] = MSS,
- [ISL_MSAA_LAYOUT_INTERLEAVED] = DEPTH_STENCIL,
- [ISL_MSAA_LAYOUT_ARRAY] = MSS,
-};
-
void
genX(fill_buffer_surface_state)(void *state, enum isl_format format,
uint32_t offset, uint32_t range, uint32_t stride)
GENX(RENDER_SURFACE_STATE_pack)(NULL, state, &surface_state);
}
-static const uint8_t anv_halign[] = {
- [4] = HALIGN4,
- [8] = HALIGN8,
- [16] = HALIGN16,
-};
-
-static const uint8_t anv_valign[] = {
- [4] = VALIGN4,
- [8] = VALIGN8,
- [16] = VALIGN16,
-};
-
-/**
- * Get the values to pack into RENDER_SUFFACE_STATE.SurfaceHorizontalAlignment
- * and SurfaceVerticalAlignment.
- */
-static void
-get_halign_valign(const struct isl_surf *surf, uint32_t *halign, uint32_t *valign)
-{
- #if GEN_GEN >= 9
- if (isl_tiling_is_std_y(surf->tiling) ||
- surf->dim_layout == ISL_DIM_LAYOUT_GEN9_1D) {
- /* The hardware ignores the alignment values. Anyway, the surface's
- * true alignment is likely outside the enum range of HALIGN* and
- * VALIGN*.
- */
- *halign = 0;
- *valign = 0;
- } else {
- /* In Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in units
- * of surface elements (not pixels nor samples). For compressed formats,
- * a "surface element" is defined as a compression block. For example,
- * if SurfaceVerticalAlignment is VALIGN_4 and SurfaceFormat is an ETC2
- * format (ETC2 has a block height of 4), then the vertical alignment is
- * 4 compression blocks or, equivalently, 16 pixels.
- */
- struct isl_extent3d image_align_el
- = isl_surf_get_image_alignment_el(surf);
-
- *halign = anv_halign[image_align_el.width];
- *valign = anv_valign[image_align_el.height];
- }
- #else
- /* Pre-Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in
- * units of surface samples. For example, if SurfaceVerticalAlignment
- * is VALIGN_4 and the surface is singlesampled, then for any surface
- * format (compressed or not) the vertical alignment is
- * 4 pixels.
- */
- struct isl_extent3d image_align_sa
- = isl_surf_get_image_alignment_sa(surf);
-
- *halign = anv_halign[image_align_sa.width];
- *valign = anv_valign[image_align_sa.height];
- #endif
-}
-
-static uint32_t
-get_qpitch(const struct isl_surf *surf)
-{
- switch (surf->dim) {
- default:
- unreachable(!"bad isl_surf_dim");
- case ISL_SURF_DIM_1D:
- #if GEN_GEN >= 9
- /* QPitch is usually expressed as rows of surface elements (where
- * a surface element is an compression block or a single surface
- * sample). Skylake 1D is an outlier.
- *
- * From the Skylake BSpec >> Memory Views >> Common Surface
- * Formats >> Surface Layout and Tiling >> 1D Surfaces:
- *
- * Surface QPitch specifies the distance in pixels between array
- * slices.
- */
- return isl_surf_get_array_pitch_el(surf);
- #else
- return isl_surf_get_array_pitch_el_rows(surf);
- #endif
- case ISL_SURF_DIM_2D:
- case ISL_SURF_DIM_3D:
- #if GEN_GEN >= 9
- return isl_surf_get_array_pitch_el_rows(surf);
- #else
- /* From the Broadwell PRM for RENDER_SURFACE_STATE.QPitch
- *
- * "This field must be set to an integer multiple of the Surface
- * Vertical Alignment. For compressed textures (BC*, FXT1,
- * ETC*, and EAC* Surface Formats), this field is in units of
- * rows in the uncompressed surface, and must be set to an
- * integer multiple of the vertical alignment parameter "j"
- * defined in the Common Surface Formats section."
- */
- return isl_surf_get_array_pitch_sa_rows(surf);
- #endif
- }
-}
-
-void
-genX(fill_image_surface_state)(struct anv_device *device, void *state_map,
- struct anv_image_view *iview,
- const VkImageViewCreateInfo *pCreateInfo,
- VkImageUsageFlagBits usage)
-{
- assert(usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT |
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
- assert(util_is_power_of_two(usage));
-
- ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
- const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
- bool is_storage = (usage == VK_IMAGE_USAGE_STORAGE_BIT);
- struct anv_surface *surface =
- anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
-
- static const uint8_t isl_to_gen_tiling[] = {
- [ISL_TILING_LINEAR] = LINEAR,
- [ISL_TILING_X] = XMAJOR,
- [ISL_TILING_Y0] = YMAJOR,
- [ISL_TILING_Yf] = YMAJOR,
- [ISL_TILING_Ys] = YMAJOR,
- [ISL_TILING_W] = WMAJOR,
- };
-
- uint32_t halign, valign;
- get_halign_valign(&surface->isl, &halign, &valign);
-
- struct GENX(RENDER_SURFACE_STATE) template = {
- .SurfaceType = anv_surftype(image, pCreateInfo->viewType, is_storage),
- .SurfaceArray = image->array_size > 1,
- .SurfaceFormat = anv_surface_format(device, iview->format, is_storage),
- .SurfaceVerticalAlignment = valign,
- .SurfaceHorizontalAlignment = halign,
- .TileMode = isl_to_gen_tiling[surface->isl.tiling],
- .VerticalLineStride = 0,
- .VerticalLineStrideOffset = 0,
- .SamplerL2BypassModeDisable = true,
- .RenderCacheReadWriteMode = WriteOnlyCache,
- .CubeFaceEnablePositiveZ = 1,
- .CubeFaceEnableNegativeZ = 1,
- .CubeFaceEnablePositiveY = 1,
- .CubeFaceEnableNegativeY = 1,
- .CubeFaceEnablePositiveX = 1,
- .CubeFaceEnableNegativeX = 1,
- .MemoryObjectControlState = GENX(MOCS),
-
- /* The driver sets BaseMipLevel in SAMPLER_STATE, not here in
- * RENDER_SURFACE_STATE. The Broadwell PRM says "it is illegal to have
- * both Base Mip Level fields nonzero".
- */
- .BaseMipLevel = 0.0,
-
- .SurfaceQPitch = get_qpitch(&surface->isl) >> 2,
- .Height = iview->level_0_extent.height - 1,
- .Width = iview->level_0_extent.width - 1,
- .Depth = 0, /* TEMPLATE */
- .SurfacePitch = surface->isl.row_pitch - 1,
- .RenderTargetViewExtent = 0, /* TEMPLATE */
- .MinimumArrayElement = 0, /* TEMPLATE */
- .MultisampledSurfaceStorageFormat =
- isl_to_gen_multisample_layout[surface->isl.msaa_layout],
- .NumberofMultisamples = ffs(surface->isl.samples) - 1,
- .MultisamplePositionPaletteIndex = 0, /* UNUSED */
- .XOffset = 0,
- .YOffset = 0,
-
- .MIPCountLOD = 0, /* TEMPLATE */
- .SurfaceMinLOD = 0, /* TEMPLATE */
-
- .AuxiliarySurfaceMode = AUX_NONE,
- .RedClearColor = 0,
- .GreenClearColor = 0,
- .BlueClearColor = 0,
- .AlphaClearColor = 0,
- .ShaderChannelSelectRed = vk_to_gen_swizzle[iview->swizzle.r],
- .ShaderChannelSelectGreen = vk_to_gen_swizzle[iview->swizzle.g],
- .ShaderChannelSelectBlue = vk_to_gen_swizzle[iview->swizzle.b],
- .ShaderChannelSelectAlpha = vk_to_gen_swizzle[iview->swizzle.a],
- .ResourceMinLOD = 0.0,
- .SurfaceBaseAddress = { NULL, iview->offset },
- };
-
- switch (template.SurfaceType) {
- case SURFTYPE_1D:
- case SURFTYPE_2D:
- template.MinimumArrayElement = range->baseArrayLayer;
-
- /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
- *
- * For SURFTYPE_1D, 2D, and CUBE: The range of this field is reduced
- * by one for each increase from zero of Minimum Array Element. For
- * example, if Minimum Array Element is set to 1024 on a 2D surface,
- * the range of this field is reduced to [0,1023].
- *
- * In other words, 'Depth' is the number of array layers.
- */
- template.Depth = range->layerCount - 1;
-
- /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
- *
- * For Render Target and Typed Dataport 1D and 2D Surfaces:
- * This field must be set to the same value as the Depth field.
- */
- template.RenderTargetViewExtent = template.Depth;
- break;
- case SURFTYPE_CUBE:
- template.MinimumArrayElement = range->baseArrayLayer;
- /* Same as SURFTYPE_2D, but divided by 6 */
- template.Depth = range->layerCount / 6 - 1;
- template.RenderTargetViewExtent = template.Depth;
- break;
- case SURFTYPE_3D:
- template.MinimumArrayElement = range->baseArrayLayer;
-
- /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
- *
- * If the volume texture is MIP-mapped, this field specifies the
- * depth of the base MIP level.
- */
- template.Depth = image->extent.depth - 1;
-
- /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
- *
- * For Render Target and Typed Dataport 3D Surfaces: This field
- * indicates the extent of the accessible 'R' coordinates minus 1 on
- * the LOD currently being rendered to.
- */
- template.RenderTargetViewExtent = iview->extent.depth - 1;
- break;
- default:
- unreachable(!"bad SurfaceType");
- }
-
- if (usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
- /* For render target surfaces, the hardware interprets field
- * MIPCount/LOD as LOD. The Broadwell PRM says:
- *
- * MIPCountLOD defines the LOD that will be rendered into.
- * SurfaceMinLOD is ignored.
- */
- template.MIPCountLOD = range->baseMipLevel;
- template.SurfaceMinLOD = 0;
- } else {
- /* For non render target surfaces, the hardware interprets field
- * MIPCount/LOD as MIPCount. The range of levels accessible by the
- * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
- */
- template.SurfaceMinLOD = range->baseMipLevel;
- template.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
- }
-
- GENX(RENDER_SURFACE_STATE_pack)(NULL, state_map, &template);
-}
-
VkResult genX(CreateSampler)(
VkDevice _device,
const VkSamplerCreateInfo* pCreateInfo,