2 * Copyright © 2015 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 #include "anv_private.h"
32 #include "genxml/gen8_pack.h"
33 #include "genxml/gen9_pack.h"
35 #include "genX_state_util.h"
38 genX(init_device_state
)(struct anv_device
*device
)
40 struct anv_batch batch
;
43 batch
.start
= batch
.next
= cmds
;
44 batch
.end
= (void *) cmds
+ sizeof(cmds
);
46 anv_batch_emit(&batch
, GENX(PIPELINE_SELECT
),
50 .PipelineSelection
= _3D
);
52 anv_batch_emit(&batch
, GENX(3DSTATE_VF_STATISTICS
),
53 .StatisticsEnable
= true);
54 anv_batch_emit(&batch
, GENX(3DSTATE_HS
), .Enable
= false);
55 anv_batch_emit(&batch
, GENX(3DSTATE_TE
), .TEEnable
= false);
56 anv_batch_emit(&batch
, GENX(3DSTATE_DS
), .FunctionEnable
= false);
57 anv_batch_emit(&batch
, GENX(3DSTATE_STREAMOUT
), .SOFunctionEnable
= false);
58 anv_batch_emit(&batch
, GENX(3DSTATE_WM_CHROMAKEY
),
59 .ChromaKeyKillEnable
= false);
60 anv_batch_emit(&batch
, GENX(3DSTATE_AA_LINE_PARAMETERS
));
62 /* See the Vulkan 1.0 spec Table 24.1 "Standard sample locations" and
63 * VkPhysicalDeviceFeatures::standardSampleLocations.
65 anv_batch_emit(&batch
, GENX(3DSTATE_SAMPLE_PATTERN
),
66 ._1xSample0XOffset
= 0.5,
67 ._1xSample0YOffset
= 0.5,
68 ._2xSample0XOffset
= 0.25,
69 ._2xSample0YOffset
= 0.25,
70 ._2xSample1XOffset
= 0.75,
71 ._2xSample1YOffset
= 0.75,
72 ._4xSample0XOffset
= 0.375,
73 ._4xSample0YOffset
= 0.125,
74 ._4xSample1XOffset
= 0.875,
75 ._4xSample1YOffset
= 0.375,
76 ._4xSample2XOffset
= 0.125,
77 ._4xSample2YOffset
= 0.625,
78 ._4xSample3XOffset
= 0.625,
79 ._4xSample3YOffset
= 0.875,
80 ._8xSample0XOffset
= 0.5625,
81 ._8xSample0YOffset
= 0.3125,
82 ._8xSample1XOffset
= 0.4375,
83 ._8xSample1YOffset
= 0.6875,
84 ._8xSample2XOffset
= 0.8125,
85 ._8xSample2YOffset
= 0.5625,
86 ._8xSample3XOffset
= 0.3125,
87 ._8xSample3YOffset
= 0.1875,
88 ._8xSample4XOffset
= 0.1875,
89 ._8xSample4YOffset
= 0.8125,
90 ._8xSample5XOffset
= 0.0625,
91 ._8xSample5YOffset
= 0.4375,
92 ._8xSample6XOffset
= 0.6875,
93 ._8xSample6YOffset
= 0.9375,
94 ._8xSample7XOffset
= 0.9375,
95 ._8xSample7YOffset
= 0.0625,
97 ._16xSample0XOffset
= 0.5625,
98 ._16xSample0YOffset
= 0.5625,
99 ._16xSample1XOffset
= 0.4375,
100 ._16xSample1YOffset
= 0.3125,
101 ._16xSample2XOffset
= 0.3125,
102 ._16xSample2YOffset
= 0.6250,
103 ._16xSample3XOffset
= 0.7500,
104 ._16xSample3YOffset
= 0.4375,
105 ._16xSample4XOffset
= 0.1875,
106 ._16xSample4YOffset
= 0.3750,
107 ._16xSample5XOffset
= 0.6250,
108 ._16xSample5YOffset
= 0.8125,
109 ._16xSample6XOffset
= 0.8125,
110 ._16xSample6YOffset
= 0.6875,
111 ._16xSample7XOffset
= 0.6875,
112 ._16xSample7YOffset
= 0.1875,
113 ._16xSample8XOffset
= 0.3750,
114 ._16xSample8YOffset
= 0.8750,
115 ._16xSample9XOffset
= 0.5000,
116 ._16xSample9YOffset
= 0.0625,
117 ._16xSample10XOffset
= 0.2500,
118 ._16xSample10YOffset
= 0.1250,
119 ._16xSample11XOffset
= 0.1250,
120 ._16xSample11YOffset
= 0.7500,
121 ._16xSample12XOffset
= 0.0000,
122 ._16xSample12YOffset
= 0.5000,
123 ._16xSample13XOffset
= 0.9375,
124 ._16xSample13YOffset
= 0.2500,
125 ._16xSample14XOffset
= 0.8750,
126 ._16xSample14YOffset
= 0.9375,
127 ._16xSample15XOffset
= 0.0625,
128 ._16xSample15YOffset
= 0.0000,
132 anv_batch_emit(&batch
, GENX(MI_BATCH_BUFFER_END
));
134 assert(batch
.next
<= batch
.end
);
136 return anv_device_submit_simple_batch(device
, &batch
);
139 static const uint32_t
140 isl_to_gen_multisample_layout
[] = {
141 [ISL_MSAA_LAYOUT_NONE
] = MSS
,
142 [ISL_MSAA_LAYOUT_INTERLEAVED
] = DEPTH_STENCIL
,
143 [ISL_MSAA_LAYOUT_ARRAY
] = MSS
,
147 genX(fill_buffer_surface_state
)(void *state
, enum isl_format format
,
148 uint32_t offset
, uint32_t range
, uint32_t stride
)
150 uint32_t num_elements
= range
/ stride
;
152 struct GENX(RENDER_SURFACE_STATE
) surface_state
= {
153 .SurfaceType
= SURFTYPE_BUFFER
,
154 .SurfaceArray
= false,
155 .SurfaceFormat
= format
,
156 .SurfaceVerticalAlignment
= VALIGN4
,
157 .SurfaceHorizontalAlignment
= HALIGN4
,
159 .SamplerL2BypassModeDisable
= true,
160 .RenderCacheReadWriteMode
= WriteOnlyCache
,
161 .MemoryObjectControlState
= GENX(MOCS
),
162 .Height
= ((num_elements
- 1) >> 7) & 0x3fff,
163 .Width
= (num_elements
- 1) & 0x7f,
164 .Depth
= ((num_elements
- 1) >> 21) & 0x3f,
165 .SurfacePitch
= stride
- 1,
166 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
167 .ShaderChannelSelectRed
= SCS_RED
,
168 .ShaderChannelSelectGreen
= SCS_GREEN
,
169 .ShaderChannelSelectBlue
= SCS_BLUE
,
170 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
171 /* FIXME: We assume that the image must be bound at this time. */
172 .SurfaceBaseAddress
= { NULL
, offset
},
175 GENX(RENDER_SURFACE_STATE_pack
)(NULL
, state
, &surface_state
);
178 static const uint8_t anv_halign
[] = {
184 static const uint8_t anv_valign
[] = {
191 * Get the values to pack into RENDER_SUFFACE_STATE.SurfaceHorizontalAlignment
192 * and SurfaceVerticalAlignment.
195 get_halign_valign(const struct isl_surf
*surf
, uint32_t *halign
, uint32_t *valign
)
198 if (isl_tiling_is_std_y(surf
->tiling
) ||
199 surf
->dim_layout
== ISL_DIM_LAYOUT_GEN9_1D
) {
200 /* The hardware ignores the alignment values. Anyway, the surface's
201 * true alignment is likely outside the enum range of HALIGN* and
207 /* In Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in units
208 * of surface elements (not pixels nor samples). For compressed formats,
209 * a "surface element" is defined as a compression block. For example,
210 * if SurfaceVerticalAlignment is VALIGN_4 and SurfaceFormat is an ETC2
211 * format (ETC2 has a block height of 4), then the vertical alignment is
212 * 4 compression blocks or, equivalently, 16 pixels.
214 struct isl_extent3d image_align_el
215 = isl_surf_get_image_alignment_el(surf
);
217 *halign
= anv_halign
[image_align_el
.width
];
218 *valign
= anv_valign
[image_align_el
.height
];
221 /* Pre-Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in
222 * units of surface samples. For example, if SurfaceVerticalAlignment
223 * is VALIGN_4 and the surface is singlesampled, then for any surface
224 * format (compressed or not) the vertical alignment is
227 struct isl_extent3d image_align_sa
228 = isl_surf_get_image_alignment_sa(surf
);
230 *halign
= anv_halign
[image_align_sa
.width
];
231 *valign
= anv_valign
[image_align_sa
.height
];
236 get_qpitch(const struct isl_surf
*surf
)
240 unreachable(!"bad isl_surf_dim");
241 case ISL_SURF_DIM_1D
:
243 /* QPitch is usually expressed as rows of surface elements (where
244 * a surface element is an compression block or a single surface
245 * sample). Skylake 1D is an outlier.
247 * From the Skylake BSpec >> Memory Views >> Common Surface
248 * Formats >> Surface Layout and Tiling >> 1D Surfaces:
250 * Surface QPitch specifies the distance in pixels between array
253 return isl_surf_get_array_pitch_el(surf
);
255 return isl_surf_get_array_pitch_el_rows(surf
);
257 case ISL_SURF_DIM_2D
:
258 case ISL_SURF_DIM_3D
:
260 return isl_surf_get_array_pitch_el_rows(surf
);
262 /* From the Broadwell PRM for RENDER_SURFACE_STATE.QPitch
264 * "This field must be set to an integer multiple of the Surface
265 * Vertical Alignment. For compressed textures (BC*, FXT1,
266 * ETC*, and EAC* Surface Formats), this field is in units of
267 * rows in the uncompressed surface, and must be set to an
268 * integer multiple of the vertical alignment parameter "j"
269 * defined in the Common Surface Formats section."
271 return isl_surf_get_array_pitch_sa_rows(surf
);
277 genX(fill_image_surface_state
)(struct anv_device
*device
, void *state_map
,
278 struct anv_image_view
*iview
,
279 const VkImageViewCreateInfo
*pCreateInfo
,
280 VkImageUsageFlagBits usage
)
282 assert(usage
& (VK_IMAGE_USAGE_SAMPLED_BIT
|
283 VK_IMAGE_USAGE_STORAGE_BIT
|
284 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
));
285 assert(util_is_power_of_two(usage
));
287 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
288 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
289 bool is_storage
= (usage
== VK_IMAGE_USAGE_STORAGE_BIT
);
290 struct anv_surface
*surface
=
291 anv_image_get_surface_for_aspect_mask(image
, range
->aspectMask
);
293 static const uint8_t isl_to_gen_tiling
[] = {
294 [ISL_TILING_LINEAR
] = LINEAR
,
295 [ISL_TILING_X
] = XMAJOR
,
296 [ISL_TILING_Y0
] = YMAJOR
,
297 [ISL_TILING_Yf
] = YMAJOR
,
298 [ISL_TILING_Ys
] = YMAJOR
,
299 [ISL_TILING_W
] = WMAJOR
,
302 uint32_t halign
, valign
;
303 get_halign_valign(&surface
->isl
, &halign
, &valign
);
305 struct GENX(RENDER_SURFACE_STATE
) template = {
306 .SurfaceType
= anv_surftype(image
, pCreateInfo
->viewType
, is_storage
),
307 .SurfaceArray
= image
->array_size
> 1,
308 .SurfaceFormat
= anv_surface_format(device
, iview
->format
, is_storage
),
309 .SurfaceVerticalAlignment
= valign
,
310 .SurfaceHorizontalAlignment
= halign
,
311 .TileMode
= isl_to_gen_tiling
[surface
->isl
.tiling
],
312 .VerticalLineStride
= 0,
313 .VerticalLineStrideOffset
= 0,
314 .SamplerL2BypassModeDisable
= true,
315 .RenderCacheReadWriteMode
= WriteOnlyCache
,
316 .CubeFaceEnablePositiveZ
= 1,
317 .CubeFaceEnableNegativeZ
= 1,
318 .CubeFaceEnablePositiveY
= 1,
319 .CubeFaceEnableNegativeY
= 1,
320 .CubeFaceEnablePositiveX
= 1,
321 .CubeFaceEnableNegativeX
= 1,
322 .MemoryObjectControlState
= GENX(MOCS
),
324 /* The driver sets BaseMipLevel in SAMPLER_STATE, not here in
325 * RENDER_SURFACE_STATE. The Broadwell PRM says "it is illegal to have
326 * both Base Mip Level fields nonzero".
330 .SurfaceQPitch
= get_qpitch(&surface
->isl
) >> 2,
331 .Height
= iview
->level_0_extent
.height
- 1,
332 .Width
= iview
->level_0_extent
.width
- 1,
333 .Depth
= 0, /* TEMPLATE */
334 .SurfacePitch
= surface
->isl
.row_pitch
- 1,
335 .RenderTargetViewExtent
= 0, /* TEMPLATE */
336 .MinimumArrayElement
= 0, /* TEMPLATE */
337 .MultisampledSurfaceStorageFormat
=
338 isl_to_gen_multisample_layout
[surface
->isl
.msaa_layout
],
339 .NumberofMultisamples
= ffs(surface
->isl
.samples
) - 1,
340 .MultisamplePositionPaletteIndex
= 0, /* UNUSED */
344 .MIPCountLOD
= 0, /* TEMPLATE */
345 .SurfaceMinLOD
= 0, /* TEMPLATE */
347 .AuxiliarySurfaceMode
= AUX_NONE
,
349 .GreenClearColor
= 0,
351 .AlphaClearColor
= 0,
352 .ShaderChannelSelectRed
= vk_to_gen_swizzle
[iview
->swizzle
.r
],
353 .ShaderChannelSelectGreen
= vk_to_gen_swizzle
[iview
->swizzle
.g
],
354 .ShaderChannelSelectBlue
= vk_to_gen_swizzle
[iview
->swizzle
.b
],
355 .ShaderChannelSelectAlpha
= vk_to_gen_swizzle
[iview
->swizzle
.a
],
356 .ResourceMinLOD
= 0.0,
357 .SurfaceBaseAddress
= { NULL
, iview
->offset
},
360 switch (template.SurfaceType
) {
363 template.MinimumArrayElement
= range
->baseArrayLayer
;
365 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
367 * For SURFTYPE_1D, 2D, and CUBE: The range of this field is reduced
368 * by one for each increase from zero of Minimum Array Element. For
369 * example, if Minimum Array Element is set to 1024 on a 2D surface,
370 * the range of this field is reduced to [0,1023].
372 * In other words, 'Depth' is the number of array layers.
374 template.Depth
= range
->layerCount
- 1;
376 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
378 * For Render Target and Typed Dataport 1D and 2D Surfaces:
379 * This field must be set to the same value as the Depth field.
381 template.RenderTargetViewExtent
= template.Depth
;
384 template.MinimumArrayElement
= range
->baseArrayLayer
;
385 /* Same as SURFTYPE_2D, but divided by 6 */
386 template.Depth
= range
->layerCount
/ 6 - 1;
387 template.RenderTargetViewExtent
= template.Depth
;
390 template.MinimumArrayElement
= range
->baseArrayLayer
;
392 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
394 * If the volume texture is MIP-mapped, this field specifies the
395 * depth of the base MIP level.
397 template.Depth
= image
->extent
.depth
- 1;
399 /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
401 * For Render Target and Typed Dataport 3D Surfaces: This field
402 * indicates the extent of the accessible 'R' coordinates minus 1 on
403 * the LOD currently being rendered to.
405 template.RenderTargetViewExtent
= iview
->extent
.depth
- 1;
408 unreachable(!"bad SurfaceType");
411 if (usage
== VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) {
412 /* For render target surfaces, the hardware interprets field
413 * MIPCount/LOD as LOD. The Broadwell PRM says:
415 * MIPCountLOD defines the LOD that will be rendered into.
416 * SurfaceMinLOD is ignored.
418 template.MIPCountLOD
= range
->baseMipLevel
;
419 template.SurfaceMinLOD
= 0;
421 /* For non render target surfaces, the hardware interprets field
422 * MIPCount/LOD as MIPCount. The range of levels accessible by the
423 * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
425 template.SurfaceMinLOD
= range
->baseMipLevel
;
426 template.MIPCountLOD
= MAX2(range
->levelCount
, 1) - 1;
429 GENX(RENDER_SURFACE_STATE_pack
)(NULL
, state_map
, &template);
432 VkResult
genX(CreateSampler
)(
434 const VkSamplerCreateInfo
* pCreateInfo
,
435 const VkAllocationCallbacks
* pAllocator
,
438 ANV_FROM_HANDLE(anv_device
, device
, _device
);
439 struct anv_sampler
*sampler
;
441 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
443 sampler
= anv_alloc2(&device
->alloc
, pAllocator
, sizeof(*sampler
), 8,
444 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
446 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
448 uint32_t border_color_offset
= device
->border_colors
.offset
+
449 pCreateInfo
->borderColor
* 64;
451 struct GENX(SAMPLER_STATE
) sampler_state
= {
452 .SamplerDisable
= false,
453 .TextureBorderColorMode
= DX10OGL
,
454 .LODPreClampMode
= CLAMP_MODE_OGL
,
458 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipmapMode
],
459 .MagModeFilter
= vk_to_gen_tex_filter(pCreateInfo
->magFilter
, pCreateInfo
->anisotropyEnable
),
460 .MinModeFilter
= vk_to_gen_tex_filter(pCreateInfo
->minFilter
, pCreateInfo
->anisotropyEnable
),
461 .TextureLODBias
= anv_clamp_f(pCreateInfo
->mipLodBias
, -16, 15.996),
462 .AnisotropicAlgorithm
= EWAApproximation
,
463 .MinLOD
= anv_clamp_f(pCreateInfo
->minLod
, 0, 14),
464 .MaxLOD
= anv_clamp_f(pCreateInfo
->maxLod
, 0, 14),
465 .ChromaKeyEnable
= 0,
468 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
469 .CubeSurfaceControlMode
= OVERRIDE
,
471 .IndirectStatePointer
= border_color_offset
>> 6,
473 .LODClampMagnificationMode
= MIPNONE
,
474 .MaximumAnisotropy
= vk_to_gen_max_anisotropy(pCreateInfo
->maxAnisotropy
),
475 .RAddressMinFilterRoundingEnable
= 0,
476 .RAddressMagFilterRoundingEnable
= 0,
477 .VAddressMinFilterRoundingEnable
= 0,
478 .VAddressMagFilterRoundingEnable
= 0,
479 .UAddressMinFilterRoundingEnable
= 0,
480 .UAddressMagFilterRoundingEnable
= 0,
481 .TrilinearFilterQuality
= 0,
482 .NonnormalizedCoordinateEnable
= pCreateInfo
->unnormalizedCoordinates
,
483 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeU
],
484 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeV
],
485 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressModeW
],
488 GENX(SAMPLER_STATE_pack
)(NULL
, sampler
->state
, &sampler_state
);
490 *pSampler
= anv_sampler_to_handle(sampler
);