1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2016 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <stdint.h> 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#define __gen_address_type uint64_t 27bf215546Sopenharmony_ci#define __gen_user_data void 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_cistatic uint64_t 30bf215546Sopenharmony_ci__gen_combine_address(__attribute__((unused)) void *data, 31bf215546Sopenharmony_ci __attribute__((unused)) void *loc, uint64_t addr, 32bf215546Sopenharmony_ci uint32_t delta) 33bf215546Sopenharmony_ci{ 34bf215546Sopenharmony_ci return addr + delta; 35bf215546Sopenharmony_ci} 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "genxml/gen_macros.h" 38bf215546Sopenharmony_ci#include "genxml/genX_pack.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include "isl_priv.h" 41bf215546Sopenharmony_ci#include "isl_genX_helpers.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#if GFX_VER >= 8 44bf215546Sopenharmony_cistatic const uint8_t isl_encode_tiling[] = { 45bf215546Sopenharmony_ci [ISL_TILING_LINEAR] = LINEAR, 46bf215546Sopenharmony_ci [ISL_TILING_X] = XMAJOR, 47bf215546Sopenharmony_ci#if GFX_VERx10 >= 125 48bf215546Sopenharmony_ci [ISL_TILING_4] = TILE4, 49bf215546Sopenharmony_ci [ISL_TILING_64] = TILE64, 50bf215546Sopenharmony_ci#else 51bf215546Sopenharmony_ci [ISL_TILING_Y0] = YMAJOR, 52bf215546Sopenharmony_ci [ISL_TILING_Yf] = YMAJOR, 53bf215546Sopenharmony_ci [ISL_TILING_Ys] = YMAJOR, 54bf215546Sopenharmony_ci#endif 55bf215546Sopenharmony_ci#if GFX_VER <= 11 56bf215546Sopenharmony_ci [ISL_TILING_W] = WMAJOR, 57bf215546Sopenharmony_ci#endif 58bf215546Sopenharmony_ci}; 59bf215546Sopenharmony_ci#endif 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci#if GFX_VER >= 7 62bf215546Sopenharmony_cistatic const uint32_t isl_encode_multisample_layout[] = { 63bf215546Sopenharmony_ci [ISL_MSAA_LAYOUT_NONE] = MSFMT_MSS, 64bf215546Sopenharmony_ci [ISL_MSAA_LAYOUT_INTERLEAVED] = MSFMT_DEPTH_STENCIL, 65bf215546Sopenharmony_ci [ISL_MSAA_LAYOUT_ARRAY] = MSFMT_MSS, 66bf215546Sopenharmony_ci}; 67bf215546Sopenharmony_ci#endif 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci#if GFX_VER >= 12 70bf215546Sopenharmony_cistatic const uint32_t isl_encode_aux_mode[] = { 71bf215546Sopenharmony_ci [ISL_AUX_USAGE_NONE] = AUX_NONE, 72bf215546Sopenharmony_ci [ISL_AUX_USAGE_MC] = AUX_NONE, 73bf215546Sopenharmony_ci [ISL_AUX_USAGE_MCS] = AUX_CCS_E, 74bf215546Sopenharmony_ci [ISL_AUX_USAGE_GFX12_CCS_E] = AUX_CCS_E, 75bf215546Sopenharmony_ci [ISL_AUX_USAGE_CCS_E] = AUX_CCS_E, 76bf215546Sopenharmony_ci [ISL_AUX_USAGE_HIZ_CCS_WT] = AUX_CCS_E, 77bf215546Sopenharmony_ci [ISL_AUX_USAGE_MCS_CCS] = AUX_MCS_LCE, 78bf215546Sopenharmony_ci [ISL_AUX_USAGE_STC_CCS] = AUX_CCS_E, 79bf215546Sopenharmony_ci}; 80bf215546Sopenharmony_ci#elif GFX_VER >= 9 81bf215546Sopenharmony_cistatic const uint32_t isl_encode_aux_mode[] = { 82bf215546Sopenharmony_ci [ISL_AUX_USAGE_NONE] = AUX_NONE, 83bf215546Sopenharmony_ci [ISL_AUX_USAGE_HIZ] = AUX_HIZ, 84bf215546Sopenharmony_ci [ISL_AUX_USAGE_MCS] = AUX_CCS_D, 85bf215546Sopenharmony_ci [ISL_AUX_USAGE_CCS_D] = AUX_CCS_D, 86bf215546Sopenharmony_ci [ISL_AUX_USAGE_CCS_E] = AUX_CCS_E, 87bf215546Sopenharmony_ci}; 88bf215546Sopenharmony_ci#elif GFX_VER >= 8 89bf215546Sopenharmony_cistatic const uint32_t isl_encode_aux_mode[] = { 90bf215546Sopenharmony_ci [ISL_AUX_USAGE_NONE] = AUX_NONE, 91bf215546Sopenharmony_ci [ISL_AUX_USAGE_HIZ] = AUX_HIZ, 92bf215546Sopenharmony_ci [ISL_AUX_USAGE_MCS] = AUX_MCS, 93bf215546Sopenharmony_ci [ISL_AUX_USAGE_CCS_D] = AUX_MCS, 94bf215546Sopenharmony_ci}; 95bf215546Sopenharmony_ci#endif 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_cistatic uint8_t 98bf215546Sopenharmony_ciget_surftype(enum isl_surf_dim dim, isl_surf_usage_flags_t usage) 99bf215546Sopenharmony_ci{ 100bf215546Sopenharmony_ci switch (dim) { 101bf215546Sopenharmony_ci default: 102bf215546Sopenharmony_ci unreachable("bad isl_surf_dim"); 103bf215546Sopenharmony_ci case ISL_SURF_DIM_1D: 104bf215546Sopenharmony_ci assert(!(usage & ISL_SURF_USAGE_CUBE_BIT)); 105bf215546Sopenharmony_ci return SURFTYPE_1D; 106bf215546Sopenharmony_ci case ISL_SURF_DIM_2D: 107bf215546Sopenharmony_ci if ((usage & ISL_SURF_USAGE_CUBE_BIT) && 108bf215546Sopenharmony_ci (usage & ISL_SURF_USAGE_TEXTURE_BIT)) { 109bf215546Sopenharmony_ci /* We need SURFTYPE_CUBE to make cube sampling work */ 110bf215546Sopenharmony_ci return SURFTYPE_CUBE; 111bf215546Sopenharmony_ci } else { 112bf215546Sopenharmony_ci /* Everything else (render and storage) treat cubes as plain 113bf215546Sopenharmony_ci * 2D array textures 114bf215546Sopenharmony_ci */ 115bf215546Sopenharmony_ci return SURFTYPE_2D; 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci case ISL_SURF_DIM_3D: 118bf215546Sopenharmony_ci assert(!(usage & ISL_SURF_USAGE_CUBE_BIT)); 119bf215546Sopenharmony_ci return SURFTYPE_3D; 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci} 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci#if GFX_VERx10 >= 125 124bf215546Sopenharmony_cistatic uint8_t 125bf215546Sopenharmony_ciget_media_compression_format(enum isl_format format, 126bf215546Sopenharmony_ci enum isl_format lowered_format) 127bf215546Sopenharmony_ci{ 128bf215546Sopenharmony_ci const uint32_t plane_bpb = isl_format_get_layout(lowered_format)->bpb; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci /* From Bspec 43868, Enumeration_MediaCompressionFormat: 131bf215546Sopenharmony_ci * 132bf215546Sopenharmony_ci * Luma P010 has MSB of 0 while chroma P010 has MSB of 1. 133bf215546Sopenharmony_ci * Luma P016 has MSB of 0 while chroma P016 has MSB of 1. 134bf215546Sopenharmony_ci * Luma NV12 has MSB of 0 while chroma NV12 has MSB of 1. 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_ci switch (format) { 137bf215546Sopenharmony_ci case ISL_FORMAT_PLANAR_420_8: /* NV12 */ 138bf215546Sopenharmony_ci assert(plane_bpb == 8 || plane_bpb == 16); 139bf215546Sopenharmony_ci assert((isl_format_get_aux_map_encoding(format) & 0xf0) == 0); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci /* drm_fourcc.h defines the chroma plane of NV12 as 16-bpb */ 142bf215546Sopenharmony_ci return (plane_bpb == 16) << 4 | isl_format_get_aux_map_encoding(format); 143bf215546Sopenharmony_ci case ISL_FORMAT_PLANAR_420_10: 144bf215546Sopenharmony_ci case ISL_FORMAT_PLANAR_420_12: 145bf215546Sopenharmony_ci case ISL_FORMAT_PLANAR_420_16: 146bf215546Sopenharmony_ci assert(plane_bpb == 16 || plane_bpb == 32); 147bf215546Sopenharmony_ci assert((isl_format_get_aux_map_encoding(format) & 0xf0) == 0); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci /* drm_fourcc.h defines the chroma plane of P01X as 32-bpb */ 150bf215546Sopenharmony_ci return (plane_bpb == 32) << 4 | isl_format_get_aux_map_encoding(format); 151bf215546Sopenharmony_ci default: 152bf215546Sopenharmony_ci return isl_format_get_aux_map_encoding(format); 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci#endif 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_civoid 158bf215546Sopenharmony_ciisl_genX(surf_fill_state_s)(const struct isl_device *dev, void *state, 159bf215546Sopenharmony_ci const struct isl_surf_fill_state_info *restrict info) 160bf215546Sopenharmony_ci{ 161bf215546Sopenharmony_ci struct GENX(RENDER_SURFACE_STATE) s = { 0 }; 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci s.SurfaceType = get_surftype(info->surf->dim, info->view->usage); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci if (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) 166bf215546Sopenharmony_ci assert(isl_format_supports_rendering(dev->info, info->view->format)); 167bf215546Sopenharmony_ci else if (info->view->usage & ISL_SURF_USAGE_TEXTURE_BIT) 168bf215546Sopenharmony_ci assert(isl_format_supports_sampling(dev->info, info->view->format)); 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci /* From the Sky Lake PRM Vol. 2d, RENDER_SURFACE_STATE::SurfaceFormat 171bf215546Sopenharmony_ci * 172bf215546Sopenharmony_ci * This field cannot be a compressed (BC*, DXT*, FXT*, ETC*, EAC*) 173bf215546Sopenharmony_ci * format if the Surface Type is SURFTYPE_1D 174bf215546Sopenharmony_ci */ 175bf215546Sopenharmony_ci if (info->surf->dim == ISL_SURF_DIM_1D) 176bf215546Sopenharmony_ci assert(!isl_format_is_compressed(info->view->format)); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci if (isl_format_is_compressed(info->surf->format)) { 179bf215546Sopenharmony_ci /* You're not allowed to make a view of a compressed format with any 180bf215546Sopenharmony_ci * format other than the surface format. None of the userspace APIs 181bf215546Sopenharmony_ci * allow for this directly and doing so would mess up a number of 182bf215546Sopenharmony_ci * surface parameters such as Width, Height, and alignments. Ideally, 183bf215546Sopenharmony_ci * we'd like to assert that the two formats match. However, we have an 184bf215546Sopenharmony_ci * S3TC workaround that requires us to do reinterpretation. So assert 185bf215546Sopenharmony_ci * that they're at least the same bpb and block size. 186bf215546Sopenharmony_ci */ 187bf215546Sopenharmony_ci ASSERTED const struct isl_format_layout *surf_fmtl = 188bf215546Sopenharmony_ci isl_format_get_layout(info->surf->format); 189bf215546Sopenharmony_ci ASSERTED const struct isl_format_layout *view_fmtl = 190bf215546Sopenharmony_ci isl_format_get_layout(info->surf->format); 191bf215546Sopenharmony_ci assert(surf_fmtl->bpb == view_fmtl->bpb); 192bf215546Sopenharmony_ci assert(surf_fmtl->bw == view_fmtl->bw); 193bf215546Sopenharmony_ci assert(surf_fmtl->bh == view_fmtl->bh); 194bf215546Sopenharmony_ci } 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci s.SurfaceFormat = info->view->format; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci#if GFX_VER >= 12 199bf215546Sopenharmony_ci /* The BSpec description of this field says: 200bf215546Sopenharmony_ci * 201bf215546Sopenharmony_ci * "This bit field, when set, indicates if the resource is created as 202bf215546Sopenharmony_ci * Depth/Stencil resource." 203bf215546Sopenharmony_ci * 204bf215546Sopenharmony_ci * "SW must set this bit for any resource that was created with 205bf215546Sopenharmony_ci * Depth/Stencil resource flag. Setting this bit allows HW to properly 206bf215546Sopenharmony_ci * interpret the data-layout for various cases. For any resource that's 207bf215546Sopenharmony_ci * created without Depth/Stencil resource flag, it must be reset." 208bf215546Sopenharmony_ci * 209bf215546Sopenharmony_ci * Even though the docs for this bit seem to imply that it's required for 210bf215546Sopenharmony_ci * anything which might have been used for depth/stencil, empirical 211bf215546Sopenharmony_ci * evidence suggests that it only affects CCS compression usage. There are 212bf215546Sopenharmony_ci * a few things which back this up: 213bf215546Sopenharmony_ci * 214bf215546Sopenharmony_ci * 1. The docs are also pretty clear that this bit was added as part 215bf215546Sopenharmony_ci * of enabling Gfx12 depth/stencil lossless compression. 216bf215546Sopenharmony_ci * 217bf215546Sopenharmony_ci * 2. The only new difference between depth/stencil and color images on 218bf215546Sopenharmony_ci * Gfx12 (where the bit was added) is how they treat CCS compression. 219bf215546Sopenharmony_ci * All other differences such as alignment requirements and MSAA layout 220bf215546Sopenharmony_ci * are already covered by other bits. 221bf215546Sopenharmony_ci * 222bf215546Sopenharmony_ci * Under these assumptions, it makes sense for ISL to model this bit as 223bf215546Sopenharmony_ci * being an extension of AuxiliarySurfaceMode where STC_CCS and HIZ_CCS_WT 224bf215546Sopenharmony_ci * are indicated by AuxiliarySurfaceMode == CCS_E and DepthStencilResource 225bf215546Sopenharmony_ci * == true. 226bf215546Sopenharmony_ci */ 227bf215546Sopenharmony_ci s.DepthStencilResource = info->aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT || 228bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_STC_CCS; 229bf215546Sopenharmony_ci#endif 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci#if GFX_VER <= 5 232bf215546Sopenharmony_ci s.ColorBufferComponentWriteDisables = info->write_disables; 233bf215546Sopenharmony_ci s.ColorBlendEnable = info->blend_enable; 234bf215546Sopenharmony_ci#else 235bf215546Sopenharmony_ci assert(info->write_disables == 0); 236bf215546Sopenharmony_ci#endif 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci#if GFX_VERx10 == 75 239bf215546Sopenharmony_ci s.IntegerSurfaceFormat = 240bf215546Sopenharmony_ci isl_format_has_int_channel((enum isl_format) s.SurfaceFormat); 241bf215546Sopenharmony_ci#endif 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci assert(info->surf->logical_level0_px.width > 0 && 244bf215546Sopenharmony_ci info->surf->logical_level0_px.height > 0); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci s.Width = info->surf->logical_level0_px.width - 1; 247bf215546Sopenharmony_ci s.Height = info->surf->logical_level0_px.height - 1; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci /* In the gfx6 PRM Volume 1 Part 1: Graphics Core, Section 7.18.3.7.1 250bf215546Sopenharmony_ci * (Surface Arrays For all surfaces other than separate stencil buffer): 251bf215546Sopenharmony_ci * 252bf215546Sopenharmony_ci * "[DevSNB] Errata: Sampler MSAA Qpitch will be 4 greater than the value 253bf215546Sopenharmony_ci * calculated in the equation above , for every other odd Surface Height 254bf215546Sopenharmony_ci * starting from 1 i.e. 1,5,9,13" 255bf215546Sopenharmony_ci * 256bf215546Sopenharmony_ci * Since this Qpitch errata only impacts the sampler, we have to adjust the 257bf215546Sopenharmony_ci * input for the rendering surface to achieve the same qpitch. For the 258bf215546Sopenharmony_ci * affected heights, we increment the height by 1 for the rendering 259bf215546Sopenharmony_ci * surface. 260bf215546Sopenharmony_ci */ 261bf215546Sopenharmony_ci if (GFX_VER == 6 && (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) && 262bf215546Sopenharmony_ci info->surf->samples > 1 && 263bf215546Sopenharmony_ci (info->surf->logical_level0_px.height % 4) == 1) 264bf215546Sopenharmony_ci s.Height++; 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci switch (s.SurfaceType) { 267bf215546Sopenharmony_ci case SURFTYPE_1D: 268bf215546Sopenharmony_ci case SURFTYPE_2D: 269bf215546Sopenharmony_ci /* From the Ivy Bridge PRM >> RENDER_SURFACE_STATE::MinimumArrayElement: 270bf215546Sopenharmony_ci * 271bf215546Sopenharmony_ci * "If Number of Multisamples is not MULTISAMPLECOUNT_1, this field 272bf215546Sopenharmony_ci * must be set to zero if this surface is used with sampling engine 273bf215546Sopenharmony_ci * messages." 274bf215546Sopenharmony_ci * 275bf215546Sopenharmony_ci * This restriction appears to exist only on Ivy Bridge. 276bf215546Sopenharmony_ci */ 277bf215546Sopenharmony_ci if (GFX_VERx10 == 70 && !ISL_DEV_IS_BAYTRAIL(dev) && 278bf215546Sopenharmony_ci (info->view->usage & ISL_SURF_USAGE_TEXTURE_BIT) && 279bf215546Sopenharmony_ci info->surf->samples > 1) 280bf215546Sopenharmony_ci assert(info->view->base_array_layer == 0); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci s.MinimumArrayElement = info->view->base_array_layer; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth: 285bf215546Sopenharmony_ci * 286bf215546Sopenharmony_ci * For SURFTYPE_1D, 2D, and CUBE: The range of this field is reduced 287bf215546Sopenharmony_ci * by one for each increase from zero of Minimum Array Element. For 288bf215546Sopenharmony_ci * example, if Minimum Array Element is set to 1024 on a 2D surface, 289bf215546Sopenharmony_ci * the range of this field is reduced to [0,1023]. 290bf215546Sopenharmony_ci * 291bf215546Sopenharmony_ci * In other words, 'Depth' is the number of array layers. 292bf215546Sopenharmony_ci */ 293bf215546Sopenharmony_ci s.Depth = info->view->array_len - 1; 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent: 296bf215546Sopenharmony_ci * 297bf215546Sopenharmony_ci * For Render Target and Typed Dataport 1D and 2D Surfaces: 298bf215546Sopenharmony_ci * This field must be set to the same value as the Depth field. 299bf215546Sopenharmony_ci */ 300bf215546Sopenharmony_ci if (info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT | 301bf215546Sopenharmony_ci ISL_SURF_USAGE_STORAGE_BIT)) 302bf215546Sopenharmony_ci s.RenderTargetViewExtent = s.Depth; 303bf215546Sopenharmony_ci break; 304bf215546Sopenharmony_ci case SURFTYPE_CUBE: 305bf215546Sopenharmony_ci s.MinimumArrayElement = info->view->base_array_layer; 306bf215546Sopenharmony_ci /* Same as SURFTYPE_2D, but divided by 6 */ 307bf215546Sopenharmony_ci s.Depth = info->view->array_len / 6 - 1; 308bf215546Sopenharmony_ci if (info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT | 309bf215546Sopenharmony_ci ISL_SURF_USAGE_STORAGE_BIT)) 310bf215546Sopenharmony_ci s.RenderTargetViewExtent = s.Depth; 311bf215546Sopenharmony_ci break; 312bf215546Sopenharmony_ci case SURFTYPE_3D: 313bf215546Sopenharmony_ci /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth: 314bf215546Sopenharmony_ci * 315bf215546Sopenharmony_ci * If the volume texture is MIP-mapped, this field specifies the 316bf215546Sopenharmony_ci * depth of the base MIP level. 317bf215546Sopenharmony_ci */ 318bf215546Sopenharmony_ci s.Depth = info->surf->logical_level0_px.depth - 1; 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent: 321bf215546Sopenharmony_ci * 322bf215546Sopenharmony_ci * For Render Target and Typed Dataport 3D Surfaces: This field 323bf215546Sopenharmony_ci * indicates the extent of the accessible 'R' coordinates minus 1 on 324bf215546Sopenharmony_ci * the LOD currently being rendered to. 325bf215546Sopenharmony_ci * 326bf215546Sopenharmony_ci * The docs specify that this only matters for render targets and 327bf215546Sopenharmony_ci * surfaces used with typed dataport messages. Prior to Ivy Bridge, the 328bf215546Sopenharmony_ci * Depth field has more bits than RenderTargetViewExtent so we can have 329bf215546Sopenharmony_ci * textures with more levels than we can render to. In order to prevent 330bf215546Sopenharmony_ci * assert-failures in the packing function below, we only set the field 331bf215546Sopenharmony_ci * when it's actually going to be used by the hardware. 332bf215546Sopenharmony_ci * 333bf215546Sopenharmony_ci * The MinimumArrayElement field is ignored by all hardware 334bf215546Sopenharmony_ci * prior to Sky Lake when texturing, and drivers are responsible 335bf215546Sopenharmony_ci * for validating the correctness of this parameter. 336bf215546Sopenharmony_ci * KHR_gl_texture_3D_image requires this functionality. 337bf215546Sopenharmony_ci */ 338bf215546Sopenharmony_ci s.MinimumArrayElement = info->view->base_array_layer; 339bf215546Sopenharmony_ci s.RenderTargetViewExtent = info->view->array_len - 1; 340bf215546Sopenharmony_ci break; 341bf215546Sopenharmony_ci default: 342bf215546Sopenharmony_ci unreachable("bad SurfaceType"); 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci#if GFX_VER >= 12 346bf215546Sopenharmony_ci /* Wa_1806565034: Only set SurfaceArray if arrayed surface is > 1. */ 347bf215546Sopenharmony_ci s.SurfaceArray = info->surf->dim != ISL_SURF_DIM_3D && 348bf215546Sopenharmony_ci info->view->array_len > 1; 349bf215546Sopenharmony_ci#elif GFX_VER >= 7 350bf215546Sopenharmony_ci s.SurfaceArray = info->surf->dim != ISL_SURF_DIM_3D; 351bf215546Sopenharmony_ci#endif 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci if (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) { 354bf215546Sopenharmony_ci /* For render target surfaces, the hardware interprets field 355bf215546Sopenharmony_ci * MIPCount/LOD as LOD. The Broadwell PRM says: 356bf215546Sopenharmony_ci * 357bf215546Sopenharmony_ci * MIPCountLOD defines the LOD that will be rendered into. 358bf215546Sopenharmony_ci * SurfaceMinLOD is ignored. 359bf215546Sopenharmony_ci */ 360bf215546Sopenharmony_ci s.MIPCountLOD = info->view->base_level; 361bf215546Sopenharmony_ci s.SurfaceMinLOD = 0; 362bf215546Sopenharmony_ci } else { 363bf215546Sopenharmony_ci /* For non render target surfaces, the hardware interprets field 364bf215546Sopenharmony_ci * MIPCount/LOD as MIPCount. The range of levels accessible by the 365bf215546Sopenharmony_ci * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD]. 366bf215546Sopenharmony_ci */ 367bf215546Sopenharmony_ci s.SurfaceMinLOD = info->view->base_level; 368bf215546Sopenharmony_ci s.MIPCountLOD = MAX(info->view->levels, 1) - 1; 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci#if GFX_VER >= 9 372bf215546Sopenharmony_ci /* We don't use miptails yet. The PRM recommends that you set "Mip Tail 373bf215546Sopenharmony_ci * Start LOD" to 15 to prevent the hardware from trying to use them. 374bf215546Sopenharmony_ci */ 375bf215546Sopenharmony_ci s.TiledResourceMode = NONE; 376bf215546Sopenharmony_ci s.MipTailStartLOD = 15; 377bf215546Sopenharmony_ci#endif 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci#if GFX_VER >= 6 380bf215546Sopenharmony_ci const struct isl_extent3d image_align = 381bf215546Sopenharmony_ci isl_get_image_alignment(info->surf); 382bf215546Sopenharmony_ci s.SurfaceVerticalAlignment = isl_encode_valign(image_align.height); 383bf215546Sopenharmony_ci#if GFX_VER >= 7 384bf215546Sopenharmony_ci s.SurfaceHorizontalAlignment = isl_encode_halign(image_align.width); 385bf215546Sopenharmony_ci#endif 386bf215546Sopenharmony_ci#endif 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci if (info->surf->dim_layout == ISL_DIM_LAYOUT_GFX9_1D) { 389bf215546Sopenharmony_ci /* For gfx9 1-D textures, surface pitch is ignored */ 390bf215546Sopenharmony_ci s.SurfacePitch = 0; 391bf215546Sopenharmony_ci } else { 392bf215546Sopenharmony_ci s.SurfacePitch = info->surf->row_pitch_B - 1; 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci#if GFX_VER >= 8 396bf215546Sopenharmony_ci s.SurfaceQPitch = isl_get_qpitch(info->surf) >> 2; 397bf215546Sopenharmony_ci#elif GFX_VER == 7 398bf215546Sopenharmony_ci s.SurfaceArraySpacing = info->surf->array_pitch_span == 399bf215546Sopenharmony_ci ISL_ARRAY_PITCH_SPAN_COMPACT; 400bf215546Sopenharmony_ci#endif 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci#if GFX_VER >= 8 403bf215546Sopenharmony_ci assert(GFX_VER < 12 || info->surf->tiling != ISL_TILING_W); 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci /* From the SKL+ PRMs, RENDER_SURFACE_STATE:TileMode, 406bf215546Sopenharmony_ci * 407bf215546Sopenharmony_ci * If Surface Format is ASTC*, this field must be TILEMODE_YMAJOR. 408bf215546Sopenharmony_ci */ 409bf215546Sopenharmony_ci if (isl_format_get_layout(info->view->format)->txc == ISL_TXC_ASTC) 410bf215546Sopenharmony_ci assert(info->surf->tiling == ISL_TILING_Y0); 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci s.TileMode = isl_encode_tiling[info->surf->tiling]; 413bf215546Sopenharmony_ci#else 414bf215546Sopenharmony_ci s.TiledSurface = info->surf->tiling != ISL_TILING_LINEAR, 415bf215546Sopenharmony_ci s.TileWalk = info->surf->tiling == ISL_TILING_Y0 ? TILEWALK_YMAJOR : 416bf215546Sopenharmony_ci TILEWALK_XMAJOR, 417bf215546Sopenharmony_ci#endif 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci#if GFX_VER >= 8 420bf215546Sopenharmony_ci s.RenderCacheReadWriteMode = WriteOnlyCache; 421bf215546Sopenharmony_ci#else 422bf215546Sopenharmony_ci s.RenderCacheReadWriteMode = 0; 423bf215546Sopenharmony_ci#endif 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci#if GFX_VER >= 11 426bf215546Sopenharmony_ci /* We've seen dEQP failures when enabling this bit with UINT formats, 427bf215546Sopenharmony_ci * which particularly affects blorp_copy() operations. It shouldn't 428bf215546Sopenharmony_ci * have any effect on UINT textures anyway, so disable it for them. 429bf215546Sopenharmony_ci */ 430bf215546Sopenharmony_ci s.EnableUnormPathInColorPipe = 431bf215546Sopenharmony_ci !isl_format_has_int_channel(info->view->format); 432bf215546Sopenharmony_ci#endif 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci s.CubeFaceEnablePositiveZ = 1; 435bf215546Sopenharmony_ci s.CubeFaceEnableNegativeZ = 1; 436bf215546Sopenharmony_ci s.CubeFaceEnablePositiveY = 1; 437bf215546Sopenharmony_ci s.CubeFaceEnableNegativeY = 1; 438bf215546Sopenharmony_ci s.CubeFaceEnablePositiveX = 1; 439bf215546Sopenharmony_ci s.CubeFaceEnableNegativeX = 1; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci#if GFX_VER >= 6 442bf215546Sopenharmony_ci /* From the Broadwell PRM for "Number of Multisamples": 443bf215546Sopenharmony_ci * 444bf215546Sopenharmony_ci * "If this field is any value other than MULTISAMPLECOUNT_1, Surface 445bf215546Sopenharmony_ci * Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero." 446bf215546Sopenharmony_ci * 447bf215546Sopenharmony_ci * This is fine because no 3D API allows multisampling and mipmapping at 448bf215546Sopenharmony_ci * the same time. 449bf215546Sopenharmony_ci */ 450bf215546Sopenharmony_ci if (info->surf->samples > 1) { 451bf215546Sopenharmony_ci assert(info->view->min_lod_clamp == 0); 452bf215546Sopenharmony_ci assert(info->view->base_level == 0); 453bf215546Sopenharmony_ci assert(info->view->levels == 1); 454bf215546Sopenharmony_ci } 455bf215546Sopenharmony_ci s.NumberofMultisamples = ffs(info->surf->samples) - 1; 456bf215546Sopenharmony_ci#if GFX_VER >= 7 457bf215546Sopenharmony_ci s.MultisampledSurfaceStorageFormat = 458bf215546Sopenharmony_ci isl_encode_multisample_layout[info->surf->msaa_layout]; 459bf215546Sopenharmony_ci#endif 460bf215546Sopenharmony_ci#endif 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci#if GFX_VER >= 7 463bf215546Sopenharmony_ci s.ResourceMinLOD = info->view->min_lod_clamp; 464bf215546Sopenharmony_ci#else 465bf215546Sopenharmony_ci assert(info->view->min_lod_clamp == 0); 466bf215546Sopenharmony_ci#endif 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci#if (GFX_VERx10 >= 75) 469bf215546Sopenharmony_ci if (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) 470bf215546Sopenharmony_ci assert(isl_swizzle_supports_rendering(dev->info, info->view->swizzle)); 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci s.ShaderChannelSelectRed = (enum GENX(ShaderChannelSelect)) info->view->swizzle.r; 473bf215546Sopenharmony_ci s.ShaderChannelSelectGreen = (enum GENX(ShaderChannelSelect)) info->view->swizzle.g; 474bf215546Sopenharmony_ci s.ShaderChannelSelectBlue = (enum GENX(ShaderChannelSelect)) info->view->swizzle.b; 475bf215546Sopenharmony_ci s.ShaderChannelSelectAlpha = (enum GENX(ShaderChannelSelect)) info->view->swizzle.a; 476bf215546Sopenharmony_ci#else 477bf215546Sopenharmony_ci assert(isl_swizzle_is_identity(info->view->swizzle)); 478bf215546Sopenharmony_ci#endif 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci s.SurfaceBaseAddress = info->address; 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci#if GFX_VER >= 6 483bf215546Sopenharmony_ci s.MOCS = info->mocs; 484bf215546Sopenharmony_ci#endif 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci#if GFX_VERx10 >= 45 487bf215546Sopenharmony_ci if (info->x_offset_sa != 0 || info->y_offset_sa != 0) { 488bf215546Sopenharmony_ci /* There are fairly strict rules about when the offsets can be used. 489bf215546Sopenharmony_ci * These are mostly taken from the Sky Lake PRM documentation for 490bf215546Sopenharmony_ci * RENDER_SURFACE_STATE. 491bf215546Sopenharmony_ci */ 492bf215546Sopenharmony_ci assert(info->surf->tiling != ISL_TILING_LINEAR); 493bf215546Sopenharmony_ci assert(info->surf->dim == ISL_SURF_DIM_2D); 494bf215546Sopenharmony_ci assert(isl_is_pow2(isl_format_get_layout(info->view->format)->bpb)); 495bf215546Sopenharmony_ci assert(info->surf->levels == 1); 496bf215546Sopenharmony_ci assert(info->surf->logical_level0_px.array_len == 1); 497bf215546Sopenharmony_ci assert(info->aux_usage == ISL_AUX_USAGE_NONE); 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci if (GFX_VER >= 8) { 500bf215546Sopenharmony_ci /* Broadwell added more rules. */ 501bf215546Sopenharmony_ci assert(info->surf->samples == 1); 502bf215546Sopenharmony_ci if (isl_format_get_layout(info->view->format)->bpb == 8) 503bf215546Sopenharmony_ci assert(info->x_offset_sa % 16 == 0); 504bf215546Sopenharmony_ci if (isl_format_get_layout(info->view->format)->bpb == 16) 505bf215546Sopenharmony_ci assert(info->x_offset_sa % 8 == 0); 506bf215546Sopenharmony_ci } 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci#if GFX_VER >= 7 509bf215546Sopenharmony_ci s.SurfaceArray = false; 510bf215546Sopenharmony_ci#endif 511bf215546Sopenharmony_ci } 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci const unsigned x_div = 4; 514bf215546Sopenharmony_ci const unsigned y_div = GFX_VER >= 8 ? 4 : 2; 515bf215546Sopenharmony_ci assert(info->x_offset_sa % x_div == 0); 516bf215546Sopenharmony_ci assert(info->y_offset_sa % y_div == 0); 517bf215546Sopenharmony_ci s.XOffset = info->x_offset_sa / x_div; 518bf215546Sopenharmony_ci s.YOffset = info->y_offset_sa / y_div; 519bf215546Sopenharmony_ci#else 520bf215546Sopenharmony_ci assert(info->x_offset_sa == 0); 521bf215546Sopenharmony_ci assert(info->y_offset_sa == 0); 522bf215546Sopenharmony_ci#endif 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci#if GFX_VER >= 7 525bf215546Sopenharmony_ci if (info->aux_usage != ISL_AUX_USAGE_NONE) { 526bf215546Sopenharmony_ci /* Check valid aux usages per-gen */ 527bf215546Sopenharmony_ci if (GFX_VER >= 12) { 528bf215546Sopenharmony_ci assert(info->aux_usage == ISL_AUX_USAGE_MCS || 529bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_CCS_E || 530bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_GFX12_CCS_E || 531bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_MC || 532bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT || 533bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_MCS_CCS || 534bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_STC_CCS); 535bf215546Sopenharmony_ci } else if (GFX_VER >= 9) { 536bf215546Sopenharmony_ci assert(info->aux_usage == ISL_AUX_USAGE_HIZ || 537bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_MCS || 538bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_CCS_D || 539bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_CCS_E); 540bf215546Sopenharmony_ci } else if (GFX_VER >= 8) { 541bf215546Sopenharmony_ci assert(info->aux_usage == ISL_AUX_USAGE_HIZ || 542bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_MCS || 543bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_CCS_D); 544bf215546Sopenharmony_ci } else if (GFX_VER >= 7) { 545bf215546Sopenharmony_ci assert(info->aux_usage == ISL_AUX_USAGE_MCS || 546bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_CCS_D); 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci /* The docs don't appear to say anything whatsoever about compression 550bf215546Sopenharmony_ci * and the data port. Testing seems to indicate that the data port 551bf215546Sopenharmony_ci * completely ignores the AuxiliarySurfaceMode field. 552bf215546Sopenharmony_ci * 553bf215546Sopenharmony_ci * On gfx12 HDC supports compression. 554bf215546Sopenharmony_ci */ 555bf215546Sopenharmony_ci if (GFX_VER < 12) 556bf215546Sopenharmony_ci assert(!(info->view->usage & ISL_SURF_USAGE_STORAGE_BIT)); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci if (isl_surf_usage_is_depth(info->surf->usage)) 559bf215546Sopenharmony_ci assert(isl_aux_usage_has_hiz(info->aux_usage)); 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci if (isl_surf_usage_is_stencil(info->surf->usage)) 562bf215546Sopenharmony_ci assert(info->aux_usage == ISL_AUX_USAGE_STC_CCS); 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci if (isl_aux_usage_has_hiz(info->aux_usage)) { 565bf215546Sopenharmony_ci /* For Gfx8-10, there are some restrictions around sampling from HiZ. 566bf215546Sopenharmony_ci * The Skylake PRM docs for RENDER_SURFACE_STATE::AuxiliarySurfaceMode 567bf215546Sopenharmony_ci * say: 568bf215546Sopenharmony_ci * 569bf215546Sopenharmony_ci * "If this field is set to AUX_HIZ, Number of Multisamples must 570bf215546Sopenharmony_ci * be MULTISAMPLECOUNT_1, and Surface Type cannot be SURFTYPE_3D." 571bf215546Sopenharmony_ci * 572bf215546Sopenharmony_ci * On Gfx12, the docs are a bit less obvious but the restriction is 573bf215546Sopenharmony_ci * the same. The limitation isn't called out explicitly but the docs 574bf215546Sopenharmony_ci * for the CCS_E value of RENDER_SURFACE_STATE::AuxiliarySurfaceMode 575bf215546Sopenharmony_ci * say: 576bf215546Sopenharmony_ci * 577bf215546Sopenharmony_ci * "If Number of multisamples > 1, programming this value means 578bf215546Sopenharmony_ci * MSAA compression is enabled for that surface. Auxiliary surface 579bf215546Sopenharmony_ci * is MSC with tile y." 580bf215546Sopenharmony_ci * 581bf215546Sopenharmony_ci * Since this interpretation ignores whether the surface is 582bf215546Sopenharmony_ci * depth/stencil or not and since multisampled depth buffers use 583bf215546Sopenharmony_ci * ISL_MSAA_LAYOUT_INTERLEAVED which is incompatible with MCS 584bf215546Sopenharmony_ci * compression, this means that we can't even specify MSAA depth CCS 585bf215546Sopenharmony_ci * in RENDER_SURFACE_STATE::AuxiliarySurfaceMode. 586bf215546Sopenharmony_ci */ 587bf215546Sopenharmony_ci assert(info->surf->samples == 1); 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci /* The dimension must not be 3D */ 590bf215546Sopenharmony_ci assert(info->surf->dim != ISL_SURF_DIM_3D); 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci /* The format must be one of the following: */ 593bf215546Sopenharmony_ci switch (info->view->format) { 594bf215546Sopenharmony_ci case ISL_FORMAT_R32_FLOAT: 595bf215546Sopenharmony_ci case ISL_FORMAT_R24_UNORM_X8_TYPELESS: 596bf215546Sopenharmony_ci case ISL_FORMAT_R16_UNORM: 597bf215546Sopenharmony_ci break; 598bf215546Sopenharmony_ci default: 599bf215546Sopenharmony_ci assert(!"Incompatible HiZ Sampling format"); 600bf215546Sopenharmony_ci break; 601bf215546Sopenharmony_ci } 602bf215546Sopenharmony_ci } 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci#if GFX_VERx10 >= 125 605bf215546Sopenharmony_ci if (info->aux_usage == ISL_AUX_USAGE_MC) { 606bf215546Sopenharmony_ci s.CompressionFormat = 607bf215546Sopenharmony_ci get_media_compression_format(info->mc_format, info->surf->format); 608bf215546Sopenharmony_ci } else { 609bf215546Sopenharmony_ci s.CompressionFormat = 610bf215546Sopenharmony_ci isl_get_render_compression_format(info->surf->format); 611bf215546Sopenharmony_ci } 612bf215546Sopenharmony_ci#endif 613bf215546Sopenharmony_ci#if GFX_VER >= 12 614bf215546Sopenharmony_ci s.MemoryCompressionEnable = info->aux_usage == ISL_AUX_USAGE_MC; 615bf215546Sopenharmony_ci#endif 616bf215546Sopenharmony_ci#if GFX_VER >= 9 617bf215546Sopenharmony_ci /* Some CCS aux usages have format restrictions. The Skylake PRM doc for 618bf215546Sopenharmony_ci * RENDER_SURFACE_STATE::AuxiliarySurfaceMode says: 619bf215546Sopenharmony_ci * 620bf215546Sopenharmony_ci * If Number of Multisamples is MULTISAMPLECOUNT_1, AUX_CCS_E setting 621bf215546Sopenharmony_ci * is only allowed if Surface Format is supported for Render Target 622bf215546Sopenharmony_ci * Compression. This setting enables render target compression. 623bf215546Sopenharmony_ci * 624bf215546Sopenharmony_ci * If CCS_E is in use, the format must support it. 625bf215546Sopenharmony_ci */ 626bf215546Sopenharmony_ci if (info->aux_usage == ISL_AUX_USAGE_CCS_E || 627bf215546Sopenharmony_ci info->aux_usage == ISL_AUX_USAGE_GFX12_CCS_E) 628bf215546Sopenharmony_ci assert(isl_format_supports_ccs_e(dev->info, info->view->format)); 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci /* It also says: 631bf215546Sopenharmony_ci * 632bf215546Sopenharmony_ci * If Number of Multisamples is MULTISAMPLECOUNT_1, AUX_CCS_D setting 633bf215546Sopenharmony_ci * is only allowed if Surface Format supported for Fast Clear. In 634bf215546Sopenharmony_ci * addition, if the surface is bound to the sampling engine, Surface 635bf215546Sopenharmony_ci * Format must be supported for Render Target Compression for 636bf215546Sopenharmony_ci * surfaces bound to the sampling engine. For render target surfaces, 637bf215546Sopenharmony_ci * this setting disables render target compression. For sampling 638bf215546Sopenharmony_ci * engine surfaces, this mode behaves the same as AUX_CCS_E. 639bf215546Sopenharmony_ci * 640bf215546Sopenharmony_ci * If CCS_D is in use while rendering, the format must support it. If 641bf215546Sopenharmony_ci * it's in use while sampling, the format must support CCS_E. 642bf215546Sopenharmony_ci */ 643bf215546Sopenharmony_ci if (info->aux_usage == ISL_AUX_USAGE_CCS_D) { 644bf215546Sopenharmony_ci if (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) { 645bf215546Sopenharmony_ci assert(isl_format_supports_ccs_d(dev->info, info->view->format)); 646bf215546Sopenharmony_ci } else { 647bf215546Sopenharmony_ci assert(info->view->usage & ISL_SURF_USAGE_TEXTURE_BIT); 648bf215546Sopenharmony_ci assert(isl_format_supports_ccs_e(dev->info, info->view->format)); 649bf215546Sopenharmony_ci } 650bf215546Sopenharmony_ci } 651bf215546Sopenharmony_ci#endif 652bf215546Sopenharmony_ci#if GFX_VER >= 8 653bf215546Sopenharmony_ci s.AuxiliarySurfaceMode = isl_encode_aux_mode[info->aux_usage]; 654bf215546Sopenharmony_ci#else 655bf215546Sopenharmony_ci s.MCSEnable = true; 656bf215546Sopenharmony_ci#endif 657bf215546Sopenharmony_ci } 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci /* The auxiliary buffer info is filled when it's usable by the HW. 660bf215546Sopenharmony_ci * 661bf215546Sopenharmony_ci * Starting with Gfx12, the only form of compression that can be used 662bf215546Sopenharmony_ci * with RENDER_SURFACE_STATE which requires an aux surface is MCS. 663bf215546Sopenharmony_ci * HiZ still requires a surface but the HiZ surface can only be 664bf215546Sopenharmony_ci * accessed through 3DSTATE_HIER_DEPTH_BUFFER. 665bf215546Sopenharmony_ci * 666bf215546Sopenharmony_ci * On all earlier hardware, an aux surface is required for all forms 667bf215546Sopenharmony_ci * of compression. 668bf215546Sopenharmony_ci */ 669bf215546Sopenharmony_ci if ((GFX_VER < 12 && info->aux_usage != ISL_AUX_USAGE_NONE) || 670bf215546Sopenharmony_ci (GFX_VER >= 12 && isl_aux_usage_has_mcs(info->aux_usage))) { 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci assert(info->aux_surf != NULL); 673bf215546Sopenharmony_ci 674bf215546Sopenharmony_ci struct isl_tile_info tile_info; 675bf215546Sopenharmony_ci isl_surf_get_tile_info(info->aux_surf, &tile_info); 676bf215546Sopenharmony_ci uint32_t pitch_in_tiles = 677bf215546Sopenharmony_ci info->aux_surf->row_pitch_B / tile_info.phys_extent_B.width; 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci s.AuxiliarySurfaceBaseAddress = info->aux_address; 680bf215546Sopenharmony_ci s.AuxiliarySurfacePitch = pitch_in_tiles - 1; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci#if GFX_VER >= 8 683bf215546Sopenharmony_ci /* Auxiliary surfaces in ISL have compressed formats but the hardware 684bf215546Sopenharmony_ci * doesn't expect our definition of the compression, it expects qpitch 685bf215546Sopenharmony_ci * in units of samples on the main surface. 686bf215546Sopenharmony_ci */ 687bf215546Sopenharmony_ci s.AuxiliarySurfaceQPitch = 688bf215546Sopenharmony_ci isl_surf_get_array_pitch_sa_rows(info->aux_surf) >> 2; 689bf215546Sopenharmony_ci#endif 690bf215546Sopenharmony_ci } 691bf215546Sopenharmony_ci#endif 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci#if GFX_VER >= 8 && GFX_VER < 11 694bf215546Sopenharmony_ci /* From the CHV PRM, Volume 2d, page 321 (RENDER_SURFACE_STATE dword 0 695bf215546Sopenharmony_ci * bit 9 "Sampler L2 Bypass Mode Disable" Programming Notes): 696bf215546Sopenharmony_ci * 697bf215546Sopenharmony_ci * This bit must be set for the following surface types: BC2_UNORM 698bf215546Sopenharmony_ci * BC3_UNORM BC5_UNORM BC5_SNORM BC7_UNORM 699bf215546Sopenharmony_ci */ 700bf215546Sopenharmony_ci if (GFX_VER >= 9 || dev->info->platform == INTEL_PLATFORM_CHV) { 701bf215546Sopenharmony_ci switch (info->view->format) { 702bf215546Sopenharmony_ci case ISL_FORMAT_BC2_UNORM: 703bf215546Sopenharmony_ci case ISL_FORMAT_BC3_UNORM: 704bf215546Sopenharmony_ci case ISL_FORMAT_BC5_UNORM: 705bf215546Sopenharmony_ci case ISL_FORMAT_BC5_SNORM: 706bf215546Sopenharmony_ci case ISL_FORMAT_BC7_UNORM: 707bf215546Sopenharmony_ci s.SamplerL2BypassModeDisable = true; 708bf215546Sopenharmony_ci break; 709bf215546Sopenharmony_ci default: 710bf215546Sopenharmony_ci /* From the SKL PRM, Programming Note under Sampler Output Channel 711bf215546Sopenharmony_ci * Mapping: 712bf215546Sopenharmony_ci * 713bf215546Sopenharmony_ci * If a surface has an associated HiZ Auxiliary surface, the 714bf215546Sopenharmony_ci * Sampler L2 Bypass Mode Disable field in the RENDER_SURFACE_STATE 715bf215546Sopenharmony_ci * must be set. 716bf215546Sopenharmony_ci */ 717bf215546Sopenharmony_ci if (GFX_VER >= 9 && info->aux_usage == ISL_AUX_USAGE_HIZ) 718bf215546Sopenharmony_ci s.SamplerL2BypassModeDisable = true; 719bf215546Sopenharmony_ci break; 720bf215546Sopenharmony_ci } 721bf215546Sopenharmony_ci } 722bf215546Sopenharmony_ci#endif 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci if (isl_aux_usage_has_fast_clears(info->aux_usage)) { 725bf215546Sopenharmony_ci if (info->use_clear_address) { 726bf215546Sopenharmony_ci#if GFX_VER >= 10 727bf215546Sopenharmony_ci s.ClearValueAddressEnable = true; 728bf215546Sopenharmony_ci s.ClearValueAddress = info->clear_address; 729bf215546Sopenharmony_ci#else 730bf215546Sopenharmony_ci unreachable("Gfx9 and earlier do not support indirect clear colors"); 731bf215546Sopenharmony_ci#endif 732bf215546Sopenharmony_ci } 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci#if GFX_VER == 11 735bf215546Sopenharmony_ci /* 736bf215546Sopenharmony_ci * From BXML > GT > Shared Functions > vol5c Shared Functions > 737bf215546Sopenharmony_ci * [Structure] RENDER_SURFACE_STATE [BDW+] > ClearColorConversionEnable: 738bf215546Sopenharmony_ci * 739bf215546Sopenharmony_ci * Project: Gfx11 740bf215546Sopenharmony_ci * 741bf215546Sopenharmony_ci * "Enables Pixel backend hw to convert clear values into native format 742bf215546Sopenharmony_ci * and write back to clear address, so that display and sampler can use 743bf215546Sopenharmony_ci * the converted value for resolving fast cleared RTs." 744bf215546Sopenharmony_ci * 745bf215546Sopenharmony_ci * Summary: 746bf215546Sopenharmony_ci * Clear color conversion must be enabled if the clear color is stored 747bf215546Sopenharmony_ci * indirectly and fast color clears are enabled. 748bf215546Sopenharmony_ci */ 749bf215546Sopenharmony_ci if (info->use_clear_address) { 750bf215546Sopenharmony_ci s.ClearColorConversionEnable = true; 751bf215546Sopenharmony_ci } 752bf215546Sopenharmony_ci#endif 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci#if GFX_VER >= 12 755bf215546Sopenharmony_ci assert(info->use_clear_address); 756bf215546Sopenharmony_ci#elif GFX_VER >= 9 757bf215546Sopenharmony_ci if (!info->use_clear_address) { 758bf215546Sopenharmony_ci s.RedClearColor = info->clear_color.u32[0]; 759bf215546Sopenharmony_ci s.GreenClearColor = info->clear_color.u32[1]; 760bf215546Sopenharmony_ci s.BlueClearColor = info->clear_color.u32[2]; 761bf215546Sopenharmony_ci s.AlphaClearColor = info->clear_color.u32[3]; 762bf215546Sopenharmony_ci } 763bf215546Sopenharmony_ci#elif GFX_VER >= 7 764bf215546Sopenharmony_ci /* Prior to Sky Lake, we only have one bit for the clear color which 765bf215546Sopenharmony_ci * gives us 0 or 1 in whatever the surface's format happens to be. 766bf215546Sopenharmony_ci */ 767bf215546Sopenharmony_ci if (isl_format_has_int_channel(info->view->format)) { 768bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; i++) { 769bf215546Sopenharmony_ci assert(info->clear_color.u32[i] == 0 || 770bf215546Sopenharmony_ci info->clear_color.u32[i] == 1); 771bf215546Sopenharmony_ci } 772bf215546Sopenharmony_ci s.RedClearColor = info->clear_color.u32[0] != 0; 773bf215546Sopenharmony_ci s.GreenClearColor = info->clear_color.u32[1] != 0; 774bf215546Sopenharmony_ci s.BlueClearColor = info->clear_color.u32[2] != 0; 775bf215546Sopenharmony_ci s.AlphaClearColor = info->clear_color.u32[3] != 0; 776bf215546Sopenharmony_ci } else { 777bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; i++) { 778bf215546Sopenharmony_ci assert(info->clear_color.f32[i] == 0.0f || 779bf215546Sopenharmony_ci info->clear_color.f32[i] == 1.0f); 780bf215546Sopenharmony_ci } 781bf215546Sopenharmony_ci s.RedClearColor = info->clear_color.f32[0] != 0.0f; 782bf215546Sopenharmony_ci s.GreenClearColor = info->clear_color.f32[1] != 0.0f; 783bf215546Sopenharmony_ci s.BlueClearColor = info->clear_color.f32[2] != 0.0f; 784bf215546Sopenharmony_ci s.AlphaClearColor = info->clear_color.f32[3] != 0.0f; 785bf215546Sopenharmony_ci } 786bf215546Sopenharmony_ci#endif 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci GENX(RENDER_SURFACE_STATE_pack)(NULL, state, &s); 790bf215546Sopenharmony_ci} 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_civoid 793bf215546Sopenharmony_ciisl_genX(buffer_fill_state_s)(const struct isl_device *dev, void *state, 794bf215546Sopenharmony_ci const struct isl_buffer_fill_state_info *restrict info) 795bf215546Sopenharmony_ci{ 796bf215546Sopenharmony_ci uint64_t buffer_size = info->size_B; 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci /* Uniform and Storage buffers need to have surface size not less that the 799bf215546Sopenharmony_ci * aligned 32-bit size of the buffer. To calculate the array length on 800bf215546Sopenharmony_ci * unsized arrays in StorageBuffer the last 2 bits store the padding size 801bf215546Sopenharmony_ci * added to the surface, so we can calculate latter the original buffer 802bf215546Sopenharmony_ci * size to know the number of elements. 803bf215546Sopenharmony_ci * 804bf215546Sopenharmony_ci * surface_size = isl_align(buffer_size, 4) + 805bf215546Sopenharmony_ci * (isl_align(buffer_size) - buffer_size) 806bf215546Sopenharmony_ci * 807bf215546Sopenharmony_ci * buffer_size = (surface_size & ~3) - (surface_size & 3) 808bf215546Sopenharmony_ci */ 809bf215546Sopenharmony_ci if ((info->format == ISL_FORMAT_RAW || 810bf215546Sopenharmony_ci info->stride_B < isl_format_get_layout(info->format)->bpb / 8) && 811bf215546Sopenharmony_ci !info->is_scratch) { 812bf215546Sopenharmony_ci assert(info->stride_B == 1); 813bf215546Sopenharmony_ci uint64_t aligned_size = isl_align(buffer_size, 4); 814bf215546Sopenharmony_ci buffer_size = aligned_size + (aligned_size - buffer_size); 815bf215546Sopenharmony_ci } 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci uint32_t num_elements = buffer_size / info->stride_B; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci assert(num_elements > 0); 820bf215546Sopenharmony_ci if (info->format == ISL_FORMAT_RAW) { 821bf215546Sopenharmony_ci assert(num_elements <= dev->max_buffer_size); 822bf215546Sopenharmony_ci } else { 823bf215546Sopenharmony_ci /* From the IVB PRM, SURFACE_STATE::Height, 824bf215546Sopenharmony_ci * 825bf215546Sopenharmony_ci * For typed buffer and structured buffer surfaces, the number 826bf215546Sopenharmony_ci * of entries in the buffer ranges from 1 to 2^27. 827bf215546Sopenharmony_ci */ 828bf215546Sopenharmony_ci assert(num_elements <= (1ull << 27)); 829bf215546Sopenharmony_ci } 830bf215546Sopenharmony_ci 831bf215546Sopenharmony_ci struct GENX(RENDER_SURFACE_STATE) s = { 0, }; 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci s.SurfaceFormat = info->format; 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci s.SurfaceType = SURFTYPE_BUFFER; 836bf215546Sopenharmony_ci#if GFX_VERx10 >= 125 837bf215546Sopenharmony_ci if (info->is_scratch) { 838bf215546Sopenharmony_ci /* From the BSpec: 839bf215546Sopenharmony_ci * 840bf215546Sopenharmony_ci * "For surfaces of type SURFTYPE_SCRATCH, valid range of pitch is: 841bf215546Sopenharmony_ci * [63,262143] -> [64B, 256KB]. Also, for SURFTYPE_SCRATCH, the 842bf215546Sopenharmony_ci * pitch must be a multiple of 64bytes." 843bf215546Sopenharmony_ci */ 844bf215546Sopenharmony_ci assert(info->format == ISL_FORMAT_RAW); 845bf215546Sopenharmony_ci assert(info->stride_B % 64 == 0); 846bf215546Sopenharmony_ci assert(info->stride_B <= 256 * 1024); 847bf215546Sopenharmony_ci s.SurfaceType = SURFTYPE_SCRATCH; 848bf215546Sopenharmony_ci } 849bf215546Sopenharmony_ci#else 850bf215546Sopenharmony_ci assert(!info->is_scratch); 851bf215546Sopenharmony_ci#endif 852bf215546Sopenharmony_ci 853bf215546Sopenharmony_ci s.SurfacePitch = info->stride_B - 1; 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci#if GFX_VER >= 6 856bf215546Sopenharmony_ci s.SurfaceVerticalAlignment = isl_encode_valign(4); 857bf215546Sopenharmony_ci#if GFX_VERx10 >= 125 858bf215546Sopenharmony_ci s.SurfaceHorizontalAlignment = isl_encode_halign(128); 859bf215546Sopenharmony_ci#elif GFX_VER >= 7 860bf215546Sopenharmony_ci s.SurfaceHorizontalAlignment = isl_encode_halign(4); 861bf215546Sopenharmony_ci s.SurfaceArray = false; 862bf215546Sopenharmony_ci#endif 863bf215546Sopenharmony_ci#endif 864bf215546Sopenharmony_ci 865bf215546Sopenharmony_ci#if GFX_VER >= 7 866bf215546Sopenharmony_ci s.Height = ((num_elements - 1) >> 7) & 0x3fff; 867bf215546Sopenharmony_ci s.Width = (num_elements - 1) & 0x7f; 868bf215546Sopenharmony_ci s.Depth = ((num_elements - 1) >> 21) & 0x3ff; 869bf215546Sopenharmony_ci#else 870bf215546Sopenharmony_ci s.Height = ((num_elements - 1) >> 7) & 0x1fff; 871bf215546Sopenharmony_ci s.Width = (num_elements - 1) & 0x7f; 872bf215546Sopenharmony_ci s.Depth = ((num_elements - 1) >> 20) & 0x7f; 873bf215546Sopenharmony_ci#endif 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_ci if (GFX_VER == 12 && dev->info->revision == 0) { 876bf215546Sopenharmony_ci /* TGL-LP A0 has a HW bug (fixed in later HW) which causes buffer 877bf215546Sopenharmony_ci * textures with very close base addresses (delta < 64B) to corrupt each 878bf215546Sopenharmony_ci * other. We can sort-of work around this by making small buffer 879bf215546Sopenharmony_ci * textures 1D textures instead. This doesn't fix the problem for large 880bf215546Sopenharmony_ci * buffer textures but the liklihood of large, overlapping, and very 881bf215546Sopenharmony_ci * close buffer textures is fairly low and the point is to hack around 882bf215546Sopenharmony_ci * the bug so we can run apps and tests. 883bf215546Sopenharmony_ci */ 884bf215546Sopenharmony_ci if (info->format != ISL_FORMAT_RAW && 885bf215546Sopenharmony_ci info->stride_B == isl_format_get_layout(info->format)->bpb / 8 && 886bf215546Sopenharmony_ci num_elements <= (1 << 14)) { 887bf215546Sopenharmony_ci s.SurfaceType = SURFTYPE_1D; 888bf215546Sopenharmony_ci s.Width = num_elements - 1; 889bf215546Sopenharmony_ci s.Height = 0; 890bf215546Sopenharmony_ci s.Depth = 0; 891bf215546Sopenharmony_ci } 892bf215546Sopenharmony_ci } 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci#if GFX_VER >= 6 895bf215546Sopenharmony_ci s.NumberofMultisamples = MULTISAMPLECOUNT_1; 896bf215546Sopenharmony_ci#endif 897bf215546Sopenharmony_ci 898bf215546Sopenharmony_ci#if (GFX_VER >= 8) 899bf215546Sopenharmony_ci s.TileMode = LINEAR; 900bf215546Sopenharmony_ci#else 901bf215546Sopenharmony_ci s.TiledSurface = false; 902bf215546Sopenharmony_ci#endif 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci#if (GFX_VER >= 8) 905bf215546Sopenharmony_ci s.RenderCacheReadWriteMode = WriteOnlyCache; 906bf215546Sopenharmony_ci#else 907bf215546Sopenharmony_ci s.RenderCacheReadWriteMode = 0; 908bf215546Sopenharmony_ci#endif 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci s.SurfaceBaseAddress = info->address; 911bf215546Sopenharmony_ci#if GFX_VER >= 6 912bf215546Sopenharmony_ci s.MOCS = info->mocs; 913bf215546Sopenharmony_ci#endif 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ci#if (GFX_VERx10 >= 75) 916bf215546Sopenharmony_ci s.ShaderChannelSelectRed = (enum GENX(ShaderChannelSelect)) info->swizzle.r; 917bf215546Sopenharmony_ci s.ShaderChannelSelectGreen = (enum GENX(ShaderChannelSelect)) info->swizzle.g; 918bf215546Sopenharmony_ci s.ShaderChannelSelectBlue = (enum GENX(ShaderChannelSelect)) info->swizzle.b; 919bf215546Sopenharmony_ci s.ShaderChannelSelectAlpha = (enum GENX(ShaderChannelSelect)) info->swizzle.a; 920bf215546Sopenharmony_ci#endif 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci GENX(RENDER_SURFACE_STATE_pack)(NULL, state, &s); 923bf215546Sopenharmony_ci} 924bf215546Sopenharmony_ci 925bf215546Sopenharmony_civoid 926bf215546Sopenharmony_ciisl_genX(null_fill_state)(const struct isl_device *dev, void *state, 927bf215546Sopenharmony_ci const struct isl_null_fill_state_info *restrict info) 928bf215546Sopenharmony_ci{ 929bf215546Sopenharmony_ci struct GENX(RENDER_SURFACE_STATE) s = { 930bf215546Sopenharmony_ci .SurfaceType = SURFTYPE_NULL, 931bf215546Sopenharmony_ci /* We previously had this format set to B8G8R8A8_UNORM but ran into 932bf215546Sopenharmony_ci * hangs on IVB. R32_UINT seems to work for everybody. 933bf215546Sopenharmony_ci * 934bf215546Sopenharmony_ci * https://gitlab.freedesktop.org/mesa/mesa/-/issues/1872 935bf215546Sopenharmony_ci */ 936bf215546Sopenharmony_ci .SurfaceFormat = ISL_FORMAT_R32_UINT, 937bf215546Sopenharmony_ci#if GFX_VER >= 7 938bf215546Sopenharmony_ci .SurfaceArray = info->size.depth > 1, 939bf215546Sopenharmony_ci#endif 940bf215546Sopenharmony_ci#if GFX_VERx10 >= 125 941bf215546Sopenharmony_ci .TileMode = TILE4, 942bf215546Sopenharmony_ci#elif GFX_VER >= 8 943bf215546Sopenharmony_ci .TileMode = YMAJOR, 944bf215546Sopenharmony_ci#else 945bf215546Sopenharmony_ci .TiledSurface = true, 946bf215546Sopenharmony_ci .TileWalk = TILEWALK_YMAJOR, 947bf215546Sopenharmony_ci#endif 948bf215546Sopenharmony_ci#if GFX_VER >= 6 949bf215546Sopenharmony_ci .MOCS = isl_mocs(dev, 0, false), 950bf215546Sopenharmony_ci#endif 951bf215546Sopenharmony_ci#if GFX_VER == 7 952bf215546Sopenharmony_ci /* According to PRMs: "Volume 4 Part 1: Subsystem and Cores – Shared 953bf215546Sopenharmony_ci * Functions" 954bf215546Sopenharmony_ci * 955bf215546Sopenharmony_ci * RENDER_SURFACE_STATE::Surface Vertical Alignment 956bf215546Sopenharmony_ci * 957bf215546Sopenharmony_ci * "This field must be set to VALIGN_4 for all tiled Y Render Target 958bf215546Sopenharmony_ci * surfaces." 959bf215546Sopenharmony_ci * 960bf215546Sopenharmony_ci * Affect IVB, HSW. 961bf215546Sopenharmony_ci */ 962bf215546Sopenharmony_ci .SurfaceVerticalAlignment = VALIGN_4, 963bf215546Sopenharmony_ci#endif 964bf215546Sopenharmony_ci .MIPCountLOD = info->levels, 965bf215546Sopenharmony_ci .Width = info->size.width - 1, 966bf215546Sopenharmony_ci .Height = info->size.height - 1, 967bf215546Sopenharmony_ci .Depth = info->size.depth - 1, 968bf215546Sopenharmony_ci .RenderTargetViewExtent = info->size.depth - 1, 969bf215546Sopenharmony_ci#if GFX_VER <= 5 970bf215546Sopenharmony_ci .MinimumArrayElement = info->minimum_array_element, 971bf215546Sopenharmony_ci .ColorBufferComponentWriteDisables = 0xf, 972bf215546Sopenharmony_ci#endif 973bf215546Sopenharmony_ci }; 974bf215546Sopenharmony_ci GENX(RENDER_SURFACE_STATE_pack)(NULL, state, &s); 975bf215546Sopenharmony_ci} 976