vk/0.170.2: Rename VkTexAddress to VkTexAddressMode
[mesa.git] / src / vulkan / gen7_state.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "anv_private.h"
31
32 void
33 gen7_fill_buffer_surface_state(void *state, const struct anv_format *format,
34 uint32_t offset, uint32_t range)
35 {
36 /* This assumes RGBA float format. */
37
38 uint32_t stride = 16; /* Depends on whether accessing shader is simd8 or
39 * vec4. Will need one of each for buffers that are
40 * used in both vec4 and simd8. */
41
42 uint32_t num_elements = range / stride;
43
44 struct GEN7_RENDER_SURFACE_STATE surface_state = {
45 .SurfaceType = SURFTYPE_BUFFER,
46 .SurfaceFormat = format->surface_format,
47 .SurfaceVerticalAlignment = VALIGN_4,
48 .SurfaceHorizontalAlignment = HALIGN_4,
49 .TiledSurface = false,
50 .RenderCacheReadWriteMode = false,
51 .SurfaceObjectControlState = GEN7_MOCS,
52 .Height = (num_elements >> 7) & 0x3fff,
53 .Width = num_elements & 0x7f,
54 .Depth = (num_elements >> 21) & 0x3f,
55 .SurfacePitch = stride - 1,
56 .SurfaceBaseAddress = { NULL, offset },
57 };
58
59 GEN7_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
60 }
61
62 VkResult gen7_CreateBufferView(
63 VkDevice _device,
64 const VkBufferViewCreateInfo* pCreateInfo,
65 VkBufferView* pView)
66 {
67 ANV_FROM_HANDLE(anv_device, device, _device);
68 struct anv_buffer_view *bview;
69 VkResult result;
70
71 result = anv_buffer_view_create(device, pCreateInfo, &bview);
72 if (result != VK_SUCCESS)
73 return result;
74
75 const struct anv_format *format =
76 anv_format_for_vk_format(pCreateInfo->format);
77
78 gen7_fill_buffer_surface_state(bview->surface_state.map, format,
79 bview->offset, pCreateInfo->range);
80
81 *pView = anv_buffer_view_to_handle(bview);
82
83 return VK_SUCCESS;
84 }
85
86 static const uint32_t vk_to_gen_tex_filter[] = {
87 [VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
88 [VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
89 };
90
91 static const uint32_t vk_to_gen_mipmap_mode[] = {
92 [VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
93 [VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
94 [VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
95 };
96
97 static const uint32_t vk_to_gen_tex_address[] = {
98 [VK_TEX_ADDRESS_MODE_WRAP] = TCM_WRAP,
99 [VK_TEX_ADDRESS_MODE_MIRROR] = TCM_MIRROR,
100 [VK_TEX_ADDRESS_MODE_CLAMP] = TCM_CLAMP,
101 [VK_TEX_ADDRESS_MODE_MIRROR_ONCE] = TCM_MIRROR_ONCE,
102 [VK_TEX_ADDRESS_MODE_CLAMP_BORDER] = TCM_CLAMP_BORDER,
103 };
104
105 static const uint32_t vk_to_gen_compare_op[] = {
106 [VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
107 [VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
108 [VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
109 [VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
110 [VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
111 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
112 [VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
113 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
114 };
115
116 VkResult gen7_CreateSampler(
117 VkDevice _device,
118 const VkSamplerCreateInfo* pCreateInfo,
119 VkSampler* pSampler)
120 {
121 ANV_FROM_HANDLE(anv_device, device, _device);
122 struct anv_sampler *sampler;
123 uint32_t mag_filter, min_filter, max_anisotropy;
124
125 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
126
127 sampler = anv_device_alloc(device, sizeof(*sampler), 8,
128 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
129 if (!sampler)
130 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
131
132 if (pCreateInfo->maxAnisotropy > 1) {
133 mag_filter = MAPFILTER_ANISOTROPIC;
134 min_filter = MAPFILTER_ANISOTROPIC;
135 max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
136 } else {
137 mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
138 min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
139 max_anisotropy = RATIO21;
140 }
141
142 struct GEN7_SAMPLER_STATE sampler_state = {
143 .SamplerDisable = false,
144 .TextureBorderColorMode = DX10OGL,
145 .BaseMipLevel = 0.0,
146 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
147 .MagModeFilter = mag_filter,
148 .MinModeFilter = min_filter,
149 .TextureLODBias = pCreateInfo->mipLodBias * 256,
150 .AnisotropicAlgorithm = EWAApproximation,
151 .MinLOD = pCreateInfo->minLod,
152 .MaxLOD = pCreateInfo->maxLod,
153 .ChromaKeyEnable = 0,
154 .ChromaKeyIndex = 0,
155 .ChromaKeyMode = 0,
156 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
157 .CubeSurfaceControlMode = 0,
158
159 .BorderColorPointer =
160 device->border_colors.offset +
161 pCreateInfo->borderColor * sizeof(float) * 4,
162
163 .MaximumAnisotropy = max_anisotropy,
164 .RAddressMinFilterRoundingEnable = 0,
165 .RAddressMagFilterRoundingEnable = 0,
166 .VAddressMinFilterRoundingEnable = 0,
167 .VAddressMagFilterRoundingEnable = 0,
168 .UAddressMinFilterRoundingEnable = 0,
169 .UAddressMagFilterRoundingEnable = 0,
170 .TrilinearFilterQuality = 0,
171 .NonnormalizedCoordinateEnable = 0,
172 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeU],
173 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeV],
174 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
175 };
176
177 GEN7_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
178
179 *pSampler = anv_sampler_to_handle(sampler);
180
181 return VK_SUCCESS;
182 }
183 VkResult gen7_CreateDynamicRasterState(
184 VkDevice _device,
185 const VkDynamicRasterStateCreateInfo* pCreateInfo,
186 VkDynamicRasterState* pState)
187 {
188 ANV_FROM_HANDLE(anv_device, device, _device);
189 struct anv_dynamic_rs_state *state;
190
191 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO);
192
193 state = anv_device_alloc(device, sizeof(*state), 8,
194 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
195 if (state == NULL)
196 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
197
198 bool enable_bias = pCreateInfo->depthBias != 0.0f ||
199 pCreateInfo->slopeScaledDepthBias != 0.0f;
200
201 struct GEN7_3DSTATE_SF sf = {
202 GEN7_3DSTATE_SF_header,
203 .LineWidth = pCreateInfo->lineWidth,
204 .GlobalDepthOffsetEnableSolid = enable_bias,
205 .GlobalDepthOffsetEnableWireframe = enable_bias,
206 .GlobalDepthOffsetEnablePoint = enable_bias,
207 .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
208 .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
209 .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
210 };
211
212 GEN7_3DSTATE_SF_pack(NULL, state->gen7.sf, &sf);
213
214 *pState = anv_dynamic_rs_state_to_handle(state);
215
216 return VK_SUCCESS;
217 }
218
219 VkResult gen7_CreateDynamicDepthStencilState(
220 VkDevice _device,
221 const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
222 VkDynamicDepthStencilState* pState)
223 {
224 ANV_FROM_HANDLE(anv_device, device, _device);
225 struct anv_dynamic_ds_state *state;
226
227 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO);
228
229 state = anv_device_alloc(device, sizeof(*state), 8,
230 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
231 if (state == NULL)
232 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
233
234 struct GEN7_DEPTH_STENCIL_STATE depth_stencil_state = {
235 .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
236 .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
237 .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
238 .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
239 };
240
241 GEN7_DEPTH_STENCIL_STATE_pack(NULL, state->gen7.depth_stencil_state,
242 &depth_stencil_state);
243
244 struct GEN7_COLOR_CALC_STATE color_calc_state = {
245 .StencilReferenceValue = pCreateInfo->stencilFrontRef,
246 .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
247 };
248
249 GEN7_COLOR_CALC_STATE_pack(NULL, state->gen7.color_calc_state, &color_calc_state);
250
251 *pState = anv_dynamic_ds_state_to_handle(state);
252
253 return VK_SUCCESS;
254 }
255
256 static const uint8_t anv_halign[] = {
257 [4] = HALIGN_4,
258 [8] = HALIGN_8,
259 };
260
261 static const uint8_t anv_valign[] = {
262 [2] = VALIGN_2,
263 [4] = VALIGN_4,
264 };
265
266 void
267 gen7_image_view_init(struct anv_image_view *iview,
268 struct anv_device *device,
269 const VkImageViewCreateInfo* pCreateInfo,
270 struct anv_cmd_buffer *cmd_buffer)
271 {
272 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
273
274 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
275 struct anv_surface *surface =
276 anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
277
278 const struct anv_format *format =
279 anv_format_for_vk_format(pCreateInfo->format);
280
281 const struct anv_image_view_info view_type_info =
282 anv_image_view_info_for_vk_image_view_type(pCreateInfo->viewType);
283
284 if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
285 anv_finishme("non-2D image views");
286
287 iview->bo = image->bo;
288 iview->offset = image->offset + surface->offset;
289 iview->format = anv_format_for_vk_format(pCreateInfo->format);
290
291 iview->extent = (VkExtent3D) {
292 .width = anv_minify(image->extent.width, range->baseMipLevel),
293 .height = anv_minify(image->extent.height, range->baseMipLevel),
294 .depth = anv_minify(image->extent.depth, range->baseMipLevel),
295 };
296
297 uint32_t depth = 1;
298 if (range->arraySize > 1) {
299 depth = range->arraySize;
300 } else if (image->extent.depth > 1) {
301 depth = image->extent.depth;
302 }
303
304 struct GEN7_RENDER_SURFACE_STATE surface_state = {
305 .SurfaceType = view_type_info.surface_type,
306 .SurfaceArray = image->array_size > 1,
307 .SurfaceFormat = format->surface_format,
308 .SurfaceVerticalAlignment = anv_valign[surface->v_align],
309 .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
310
311 /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
312 * Tiled Surface is False."
313 */
314 .TiledSurface = surface->tile_mode > LINEAR,
315 .TileWalk = surface->tile_mode == YMAJOR ? TILEWALK_YMAJOR : TILEWALK_XMAJOR,
316
317 .VerticalLineStride = 0,
318 .VerticalLineStrideOffset = 0,
319 .RenderCacheReadWriteMode = false,
320
321 .Height = image->extent.height - 1,
322 .Width = image->extent.width - 1,
323 .Depth = depth - 1,
324 .SurfacePitch = surface->stride - 1,
325 .MinimumArrayElement = range->baseArraySlice,
326 .NumberofMultisamples = MULTISAMPLECOUNT_1,
327 .XOffset = 0,
328 .YOffset = 0,
329
330 .SurfaceObjectControlState = GEN7_MOCS,
331
332 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
333 * LOD. The Broadwell PRM says:
334 *
335 * MIPCountLOD defines the LOD that will be rendered into.
336 * SurfaceMinLOD is ignored.
337 */
338 .MIPCountLOD = range->mipLevels - 1,
339 .SurfaceMinLOD = range->baseMipLevel,
340
341 .MCSEnable = false,
342 .RedClearColor = 0,
343 .GreenClearColor = 0,
344 .BlueClearColor = 0,
345 .AlphaClearColor = 0,
346 .ResourceMinLOD = 0.0,
347 .SurfaceBaseAddress = { NULL, iview->offset },
348 };
349
350 if (cmd_buffer) {
351 iview->surface_state =
352 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
353 } else {
354 iview->surface_state =
355 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
356 }
357
358 GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->surface_state.map,
359 &surface_state);
360 }
361
362 void
363 gen7_color_attachment_view_init(struct anv_attachment_view *aview,
364 struct anv_device *device,
365 const VkAttachmentViewCreateInfo* pCreateInfo,
366 struct anv_cmd_buffer *cmd_buffer)
367 {
368 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
369 struct anv_image_view *iview = &aview->image_view;
370 struct anv_surface *surface =
371 anv_image_get_surface_for_color_attachment(image);
372
373 aview->attachment_type = ANV_ATTACHMENT_VIEW_TYPE_COLOR;
374
375 anv_assert(pCreateInfo->arraySize > 0);
376 anv_assert(pCreateInfo->mipLevel < image->levels);
377 anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size);
378
379 iview->bo = image->bo;
380 iview->offset = image->offset + surface->offset;
381 iview->format = anv_format_for_vk_format(pCreateInfo->format);
382
383 iview->extent = (VkExtent3D) {
384 .width = anv_minify(image->extent.width, pCreateInfo->mipLevel),
385 .height = anv_minify(image->extent.height, pCreateInfo->mipLevel),
386 .depth = anv_minify(image->extent.depth, pCreateInfo->mipLevel),
387 };
388
389 uint32_t depth = 1;
390 if (pCreateInfo->arraySize > 1) {
391 depth = pCreateInfo->arraySize;
392 } else if (image->extent.depth > 1) {
393 depth = image->extent.depth;
394 }
395
396 if (cmd_buffer) {
397 iview->surface_state =
398 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
399 } else {
400 iview->surface_state =
401 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
402 }
403
404 struct GEN7_RENDER_SURFACE_STATE surface_state = {
405 .SurfaceType = SURFTYPE_2D,
406 .SurfaceArray = image->array_size > 1,
407 .SurfaceFormat = iview->format->surface_format,
408 .SurfaceVerticalAlignment = anv_valign[surface->v_align],
409 .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
410
411 /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
412 * Tiled Surface is False."
413 */
414 .TiledSurface = surface->tile_mode > LINEAR,
415 .TileWalk = surface->tile_mode == YMAJOR ? TILEWALK_YMAJOR : TILEWALK_XMAJOR,
416
417 .VerticalLineStride = 0,
418 .VerticalLineStrideOffset = 0,
419 .RenderCacheReadWriteMode = WriteOnlyCache,
420
421 .Height = image->extent.height - 1,
422 .Width = image->extent.width - 1,
423 .Depth = depth - 1,
424 .SurfacePitch = surface->stride - 1,
425 .MinimumArrayElement = pCreateInfo->baseArraySlice,
426 .NumberofMultisamples = MULTISAMPLECOUNT_1,
427 .XOffset = 0,
428 .YOffset = 0,
429
430 .SurfaceObjectControlState = GEN7_MOCS,
431
432 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
433 * LOD. The Broadwell PRM says:
434 *
435 * MIPCountLOD defines the LOD that will be rendered into.
436 * SurfaceMinLOD is ignored.
437 */
438 .SurfaceMinLOD = 0,
439 .MIPCountLOD = pCreateInfo->mipLevel,
440
441 .MCSEnable = false,
442 .RedClearColor = 0,
443 .GreenClearColor = 0,
444 .BlueClearColor = 0,
445 .AlphaClearColor = 0,
446 .ResourceMinLOD = 0.0,
447 .SurfaceBaseAddress = { NULL, iview->offset },
448
449 };
450
451 GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->surface_state.map,
452 &surface_state);
453 }