vk: Use compute pipeline layout when binding compute sets
[mesa.git] / src / vulkan / image.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 "private.h"
31
32 static const uint8_t anv_halign[] = {
33 [4] = HALIGN4,
34 [8] = HALIGN8,
35 [16] = HALIGN16,
36 };
37
38 static const uint8_t anv_valign[] = {
39 [4] = VALIGN4,
40 [8] = VALIGN8,
41 [16] = VALIGN16,
42 };
43
44 static const struct anv_tile_info {
45 uint32_t width;
46 uint32_t height;
47
48 /**
49 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
50 *
51 * To simplify calculations, the alignments defined in the table are
52 * sometimes larger than required. For example, Skylake requires that X and
53 * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
54 * alignment. We choose 4K to accomodate both chipsets. The alignment of
55 * a linear buffer depends on its element type and usage. Linear depth
56 * buffers have the largest alignment, 64B, so we choose that for all linear
57 * buffers.
58 */
59 uint32_t surface_alignment;
60 } anv_tile_info_table[] = {
61 [LINEAR] = { 1, 1, 64 },
62 [XMAJOR] = { 512, 8, 4096 },
63 [YMAJOR] = { 128, 32, 4096 },
64 [WMAJOR] = { 128, 32, 4096 },
65 };
66
67 static uint32_t
68 anv_image_choose_tile_mode(const VkImageCreateInfo *vk_info,
69 const struct anv_image_create_info *anv_info)
70 {
71 if (anv_info)
72 return anv_info->tile_mode;
73
74 switch (vk_info->tiling) {
75 case VK_IMAGE_TILING_LINEAR:
76 if (unlikely(vk_info->format == VK_FORMAT_S8_UINT)) {
77 anv_abortf("requested linear stencil buffer");
78 }
79 return LINEAR;
80 case VK_IMAGE_TILING_OPTIMAL:
81 if (unlikely(vk_info->format == VK_FORMAT_S8_UINT)) {
82 return WMAJOR;
83 } else {
84 return YMAJOR;
85 }
86 default:
87 assert(!"bad VKImageTiling");
88 return LINEAR;
89 }
90 }
91
92 VkResult anv_image_create(
93 VkDevice _device,
94 const VkImageCreateInfo* pCreateInfo,
95 const struct anv_image_create_info * extra,
96 VkImage* pImage)
97 {
98 struct anv_device *device = (struct anv_device *) _device;
99 struct anv_image *image;
100 const struct anv_format *info;
101 int32_t aligned_height;
102 uint32_t stencil_size;
103
104 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
105
106 image = anv_device_alloc(device, sizeof(*image), 8,
107 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
108 if (image == NULL)
109 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
110
111 /* XXX: We don't handle any of these */
112 anv_assert(pCreateInfo->imageType == VK_IMAGE_TYPE_2D);
113 anv_assert(pCreateInfo->mipLevels == 1);
114 anv_assert(pCreateInfo->arraySize == 1);
115 anv_assert(pCreateInfo->samples == 1);
116 anv_assert(pCreateInfo->extent.depth == 1);
117
118 image->bo = NULL;
119 image->offset = 0;
120 image->type = pCreateInfo->imageType;
121 image->format = pCreateInfo->format;
122 image->extent = pCreateInfo->extent;
123 image->swap_chain = NULL;
124 image->tile_mode = anv_image_choose_tile_mode(pCreateInfo, extra);
125
126 assert(image->extent.width > 0);
127 assert(image->extent.height > 0);
128 assert(image->extent.depth > 0);
129
130 const struct anv_tile_info *tile_info =
131 &anv_tile_info_table[image->tile_mode];
132
133 image->alignment = tile_info->surface_alignment;
134
135 /* FINISHME: Stop hardcoding miptree image alignment */
136 image->h_align = 4;
137 image->v_align = 4;
138
139 info = anv_format_for_vk_format(pCreateInfo->format);
140 assert(info->cpp > 0 || info->has_stencil);
141
142 if (info->cpp > 0) {
143 image->stride = ALIGN_I32(image->extent.width * info->cpp,
144 tile_info->width);
145 aligned_height = ALIGN_I32(image->extent.height, tile_info->height);
146 image->size = image->stride * aligned_height;
147 } else {
148 image->size = 0;
149 image->stride = 0;
150 }
151
152 if (info->has_stencil && pCreateInfo->format != VK_FORMAT_S8_UINT) {
153 const struct anv_tile_info *w_info = &anv_tile_info_table[WMAJOR];
154 image->stencil_offset = ALIGN_U32(image->size, w_info->surface_alignment);
155 image->stencil_stride = ALIGN_I32(image->extent.width, w_info->width);
156 aligned_height = ALIGN_I32(image->extent.height, w_info->height);
157 stencil_size = image->stencil_stride * aligned_height;
158 image->size = image->stencil_offset + stencil_size;
159 } else {
160 image->stencil_offset = 0;
161 image->stencil_stride = 0;
162 }
163
164 *pImage = (VkImage) image;
165
166 return VK_SUCCESS;
167 }
168
169 VkResult anv_CreateImage(
170 VkDevice device,
171 const VkImageCreateInfo* pCreateInfo,
172 VkImage* pImage)
173 {
174 return anv_image_create(device, pCreateInfo, NULL, pImage);
175 }
176
177 VkResult anv_GetImageSubresourceInfo(
178 VkDevice device,
179 VkImage image,
180 const VkImageSubresource* pSubresource,
181 VkSubresourceInfoType infoType,
182 size_t* pDataSize,
183 void* pData)
184 {
185 stub_return(VK_UNSUPPORTED);
186 }
187
188 void
189 anv_surface_view_destroy(struct anv_device *device,
190 struct anv_object *obj, VkObjectType obj_type)
191 {
192 struct anv_surface_view *view = (struct anv_surface_view *)obj;
193
194 assert(obj_type == VK_OBJECT_TYPE_BUFFER_VIEW ||
195 obj_type == VK_OBJECT_TYPE_IMAGE_VIEW ||
196 obj_type == VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW);
197
198 anv_state_pool_free(&device->surface_state_pool, view->surface_state);
199
200 anv_device_free(device, view);
201 }
202
203 void
204 anv_image_view_init(struct anv_surface_view *view,
205 struct anv_device *device,
206 const VkImageViewCreateInfo* pCreateInfo,
207 struct anv_cmd_buffer *cmd_buffer)
208 {
209 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
210 const struct anv_format *info =
211 anv_format_for_vk_format(pCreateInfo->format);
212 uint32_t tile_mode, format;
213
214 /* XXX: We don't handle any of these */
215 anv_assert(pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_2D);
216 anv_assert(pCreateInfo->subresourceRange.baseMipLevel == 0);
217 anv_assert(pCreateInfo->subresourceRange.mipLevels == 1);
218 anv_assert(pCreateInfo->subresourceRange.baseArraySlice == 0);
219 anv_assert(pCreateInfo->subresourceRange.arraySize == 1);
220
221 view->bo = image->bo;
222 switch (pCreateInfo->subresourceRange.aspect) {
223 case VK_IMAGE_ASPECT_STENCIL:
224 /* FIXME: How is stencil texturing formed? */
225 view->offset = image->offset + image->stencil_offset;
226 tile_mode = WMAJOR;
227 format = R8_UINT;
228 break;
229 case VK_IMAGE_ASPECT_DEPTH:
230 case VK_IMAGE_ASPECT_COLOR:
231 view->offset = image->offset;
232 tile_mode = image->tile_mode;
233 format = info->format;
234 break;
235 default:
236 unreachable("");
237 break;
238 }
239
240 /* TODO: Miplevels */
241 view->extent = image->extent;
242
243 static const uint32_t vk_to_gen_swizzle[] = {
244 [VK_CHANNEL_SWIZZLE_ZERO] = SCS_ZERO,
245 [VK_CHANNEL_SWIZZLE_ONE] = SCS_ONE,
246 [VK_CHANNEL_SWIZZLE_R] = SCS_RED,
247 [VK_CHANNEL_SWIZZLE_G] = SCS_GREEN,
248 [VK_CHANNEL_SWIZZLE_B] = SCS_BLUE,
249 [VK_CHANNEL_SWIZZLE_A] = SCS_ALPHA
250 };
251
252 struct GEN8_RENDER_SURFACE_STATE surface_state = {
253 .SurfaceType = SURFTYPE_2D,
254 .SurfaceArray = false,
255 .SurfaceFormat = format,
256 .SurfaceVerticalAlignment = anv_valign[image->v_align],
257 .SurfaceHorizontalAlignment = anv_halign[image->h_align],
258 .TileMode = tile_mode,
259 .VerticalLineStride = 0,
260 .VerticalLineStrideOffset = 0,
261 .SamplerL2BypassModeDisable = true,
262 .RenderCacheReadWriteMode = WriteOnlyCache,
263 .MemoryObjectControlState = GEN8_MOCS,
264 .BaseMipLevel = 0.0,
265 .SurfaceQPitch = 0,
266 .Height = image->extent.height - 1,
267 .Width = image->extent.width - 1,
268 .Depth = image->extent.depth - 1,
269 .SurfacePitch = image->stride - 1,
270 .MinimumArrayElement = 0,
271 .NumberofMultisamples = MULTISAMPLECOUNT_1,
272 .XOffset = 0,
273 .YOffset = 0,
274 .SurfaceMinLOD = 0,
275 .MIPCountLOD = 0,
276 .AuxiliarySurfaceMode = AUX_NONE,
277 .RedClearColor = 0,
278 .GreenClearColor = 0,
279 .BlueClearColor = 0,
280 .AlphaClearColor = 0,
281 .ShaderChannelSelectRed = vk_to_gen_swizzle[pCreateInfo->channels.r],
282 .ShaderChannelSelectGreen = vk_to_gen_swizzle[pCreateInfo->channels.g],
283 .ShaderChannelSelectBlue = vk_to_gen_swizzle[pCreateInfo->channels.b],
284 .ShaderChannelSelectAlpha = vk_to_gen_swizzle[pCreateInfo->channels.a],
285 .ResourceMinLOD = 0.0,
286 .SurfaceBaseAddress = { NULL, view->offset },
287 };
288
289 if (cmd_buffer)
290 view->surface_state =
291 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
292 else
293 view->surface_state =
294 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
295
296 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
297 }
298
299 VkResult anv_CreateImageView(
300 VkDevice _device,
301 const VkImageViewCreateInfo* pCreateInfo,
302 VkImageView* pView)
303 {
304 struct anv_device *device = (struct anv_device *) _device;
305 struct anv_surface_view *view;
306
307 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
308
309 view = anv_device_alloc(device, sizeof(*view), 8,
310 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
311 if (view == NULL)
312 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
313
314 anv_image_view_init(view, device, pCreateInfo, NULL);
315
316 view->base.destructor = anv_surface_view_destroy;
317
318 *pView = (VkImageView) view;
319
320 return VK_SUCCESS;
321 }
322
323 void
324 anv_color_attachment_view_init(struct anv_surface_view *view,
325 struct anv_device *device,
326 const VkColorAttachmentViewCreateInfo* pCreateInfo,
327 struct anv_cmd_buffer *cmd_buffer)
328 {
329 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
330 const struct anv_format *format =
331 anv_format_for_vk_format(pCreateInfo->format);
332
333 /* XXX: We don't handle any of these */
334 anv_assert(pCreateInfo->mipLevel == 0);
335 anv_assert(pCreateInfo->baseArraySlice == 0);
336 anv_assert(pCreateInfo->arraySize == 1);
337 anv_assert(pCreateInfo->msaaResolveImage == 0);
338
339 view->bo = image->bo;
340 view->offset = image->offset;
341 view->extent = image->extent;
342 view->format = pCreateInfo->format;
343
344 if (cmd_buffer)
345 view->surface_state =
346 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
347 else
348 view->surface_state =
349 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
350
351 struct GEN8_RENDER_SURFACE_STATE surface_state = {
352 .SurfaceType = SURFTYPE_2D,
353 .SurfaceArray = false,
354 .SurfaceFormat = format->format,
355 .SurfaceVerticalAlignment = anv_valign[image->v_align],
356 .SurfaceHorizontalAlignment = anv_halign[image->h_align],
357 .TileMode = image->tile_mode,
358 .VerticalLineStride = 0,
359 .VerticalLineStrideOffset = 0,
360 .SamplerL2BypassModeDisable = true,
361 .RenderCacheReadWriteMode = WriteOnlyCache,
362 .MemoryObjectControlState = GEN8_MOCS,
363 .BaseMipLevel = 0.0,
364 .SurfaceQPitch = 0,
365 .Height = image->extent.height - 1,
366 .Width = image->extent.width - 1,
367 .Depth = image->extent.depth - 1,
368 .SurfacePitch = image->stride - 1,
369 .MinimumArrayElement = 0,
370 .NumberofMultisamples = MULTISAMPLECOUNT_1,
371 .XOffset = 0,
372 .YOffset = 0,
373 .SurfaceMinLOD = 0,
374 .MIPCountLOD = 0,
375 .AuxiliarySurfaceMode = AUX_NONE,
376 .RedClearColor = 0,
377 .GreenClearColor = 0,
378 .BlueClearColor = 0,
379 .AlphaClearColor = 0,
380 .ShaderChannelSelectRed = SCS_RED,
381 .ShaderChannelSelectGreen = SCS_GREEN,
382 .ShaderChannelSelectBlue = SCS_BLUE,
383 .ShaderChannelSelectAlpha = SCS_ALPHA,
384 .ResourceMinLOD = 0.0,
385 .SurfaceBaseAddress = { NULL, view->offset },
386 };
387
388 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
389 }
390
391 VkResult anv_CreateColorAttachmentView(
392 VkDevice _device,
393 const VkColorAttachmentViewCreateInfo* pCreateInfo,
394 VkColorAttachmentView* pView)
395 {
396 struct anv_device *device = (struct anv_device *) _device;
397 struct anv_surface_view *view;
398
399 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO);
400
401 view = anv_device_alloc(device, sizeof(*view), 8,
402 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
403 if (view == NULL)
404 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
405
406 anv_color_attachment_view_init(view, device, pCreateInfo, NULL);
407
408 view->base.destructor = anv_surface_view_destroy;
409
410 *pView = (VkColorAttachmentView) view;
411
412 return VK_SUCCESS;
413 }
414
415 VkResult anv_CreateDepthStencilView(
416 VkDevice _device,
417 const VkDepthStencilViewCreateInfo* pCreateInfo,
418 VkDepthStencilView* pView)
419 {
420 struct anv_device *device = (struct anv_device *) _device;
421 struct anv_depth_stencil_view *view;
422 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
423 const struct anv_format *format =
424 anv_format_for_vk_format(image->format);
425
426 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO);
427
428 view = anv_device_alloc(device, sizeof(*view), 8,
429 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
430 if (view == NULL)
431 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
432
433 /* XXX: We don't handle any of these */
434 anv_assert(pCreateInfo->mipLevel == 0);
435 anv_assert(pCreateInfo->baseArraySlice == 0);
436 anv_assert(pCreateInfo->arraySize == 1);
437 anv_assert(pCreateInfo->msaaResolveImage == 0);
438
439 view->bo = image->bo;
440
441 view->depth_stride = image->stride;
442 view->depth_offset = image->offset;
443 view->depth_format = format->format;
444
445 view->stencil_stride = image->stencil_stride;
446 view->stencil_offset = image->offset + image->stencil_offset;
447
448 *pView = (VkDepthStencilView) view;
449
450 return VK_SUCCESS;
451 }