vk: Indent tables to align '=' at column 48
[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 // Image functions
33
34 static const struct anv_tile_mode_info {
35 int32_t tile_width;
36 int32_t tile_height;
37 } tile_mode_info[] = {
38 [LINEAR] = { 1, 1 },
39 [XMAJOR] = { 512, 8 },
40 [YMAJOR] = { 128, 32 },
41 [WMAJOR] = { 128, 32 }
42 };
43
44 VkResult anv_image_create(
45 VkDevice _device,
46 const VkImageCreateInfo* pCreateInfo,
47 const struct anv_image_create_info * extra,
48 VkImage* pImage)
49 {
50 struct anv_device *device = (struct anv_device *) _device;
51 struct anv_image *image;
52 const struct anv_format *info;
53 int32_t aligned_height;
54 uint32_t stencil_size;
55
56 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
57
58 image = anv_device_alloc(device, sizeof(*image), 8,
59 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
60 if (image == NULL)
61 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
62
63 image->bo = NULL;
64 image->offset = 0;
65 image->type = pCreateInfo->imageType;
66 image->format = pCreateInfo->format;
67 image->extent = pCreateInfo->extent;
68 image->swap_chain = NULL;
69
70 assert(image->extent.width > 0);
71 assert(image->extent.height > 0);
72 assert(image->extent.depth > 0);
73
74 switch (pCreateInfo->tiling) {
75 case VK_IMAGE_TILING_LINEAR:
76 image->tile_mode = LINEAR;
77 break;
78 case VK_IMAGE_TILING_OPTIMAL:
79 image->tile_mode = YMAJOR;
80 break;
81 default:
82 assert(!"bad VKImageTiling");
83 break;
84 }
85
86 if (extra)
87 image->tile_mode = extra->tile_mode;
88
89 if (image->tile_mode == LINEAR) {
90 /* Linear depth buffers must be 64 byte aligned, which is the strictest
91 * requirement for all kinds of linear surfaces.
92 */
93 image->alignment = 64;
94 } else {
95 image->alignment = 4096;
96 }
97
98 info = anv_format_for_vk_format(pCreateInfo->format);
99 assert(info->cpp > 0 || info->has_stencil);
100
101 if (info->cpp > 0) {
102 image->stride = ALIGN_I32(image->extent.width * info->cpp,
103 tile_mode_info[image->tile_mode].tile_width);
104 aligned_height = ALIGN_I32(image->extent.height,
105 tile_mode_info[image->tile_mode].tile_height);
106 image->size = image->stride * aligned_height;
107 } else {
108 image->size = 0;
109 image->stride = 0;
110 }
111
112 if (info->has_stencil) {
113 image->stencil_offset = ALIGN_U32(image->size, 4096);
114 image->stencil_stride = ALIGN_I32(image->extent.width,
115 tile_mode_info[WMAJOR].tile_width);
116 aligned_height = ALIGN_I32(image->extent.height,
117 tile_mode_info[WMAJOR].tile_height);
118 stencil_size = image->stencil_stride * aligned_height;
119 image->size = image->stencil_offset + stencil_size;
120 } else {
121 image->stencil_offset = 0;
122 image->stencil_stride = 0;
123 }
124
125 *pImage = (VkImage) image;
126
127 return VK_SUCCESS;
128 }
129
130 VkResult anv_CreateImage(
131 VkDevice device,
132 const VkImageCreateInfo* pCreateInfo,
133 VkImage* pImage)
134 {
135 return anv_image_create(device, pCreateInfo, NULL, pImage);
136 }
137
138 VkResult anv_GetImageSubresourceInfo(
139 VkDevice device,
140 VkImage image,
141 const VkImageSubresource* pSubresource,
142 VkSubresourceInfoType infoType,
143 size_t* pDataSize,
144 void* pData)
145 {
146 stub_return(VK_UNSUPPORTED);
147 }
148
149 void
150 anv_image_view_init(struct anv_surface_view *view,
151 struct anv_device *device,
152 const VkImageViewCreateInfo* pCreateInfo,
153 struct anv_cmd_buffer *cmd_buffer)
154 {
155 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
156 const struct anv_format *info =
157 anv_format_for_vk_format(pCreateInfo->format);
158 uint32_t tile_mode, format;
159
160 view->bo = image->bo;
161 switch (pCreateInfo->subresourceRange.aspect) {
162 case VK_IMAGE_ASPECT_STENCIL:
163 /* FIXME: How is stencil texturing formed? */
164 view->offset = image->offset + image->stencil_offset;
165 tile_mode = WMAJOR;
166 format = R8_UINT;
167 break;
168 case VK_IMAGE_ASPECT_DEPTH:
169 case VK_IMAGE_ASPECT_COLOR:
170 view->offset = image->offset;
171 tile_mode = image->tile_mode;
172 format = info->format;
173 break;
174 default:
175 assert(0);
176 break;
177 }
178
179 /* TODO: Miplevels */
180 view->extent = image->extent;
181
182 static const uint32_t vk_to_gen_swizzle[] = {
183 [VK_CHANNEL_SWIZZLE_ZERO] = SCS_ZERO,
184 [VK_CHANNEL_SWIZZLE_ONE] = SCS_ONE,
185 [VK_CHANNEL_SWIZZLE_R] = SCS_RED,
186 [VK_CHANNEL_SWIZZLE_G] = SCS_GREEN,
187 [VK_CHANNEL_SWIZZLE_B] = SCS_BLUE,
188 [VK_CHANNEL_SWIZZLE_A] = SCS_ALPHA
189 };
190
191 struct GEN8_RENDER_SURFACE_STATE surface_state = {
192 .SurfaceType = SURFTYPE_2D,
193 .SurfaceArray = false,
194 .SurfaceFormat = format,
195 .SurfaceVerticalAlignment = VALIGN4,
196 .SurfaceHorizontalAlignment = HALIGN4,
197 .TileMode = tile_mode,
198 .VerticalLineStride = 0,
199 .VerticalLineStrideOffset = 0,
200 .SamplerL2BypassModeDisable = true,
201 .RenderCacheReadWriteMode = WriteOnlyCache,
202 .MemoryObjectControlState = GEN8_MOCS,
203 .BaseMipLevel = 0,
204 .SurfaceQPitch = 0,
205 .Height = image->extent.height - 1,
206 .Width = image->extent.width - 1,
207 .Depth = image->extent.depth - 1,
208 .SurfacePitch = image->stride - 1,
209 .MinimumArrayElement = 0,
210 .NumberofMultisamples = MULTISAMPLECOUNT_1,
211 .XOffset = 0,
212 .YOffset = 0,
213 .SurfaceMinLOD = 0,
214 .MIPCountLOD = 0,
215 .AuxiliarySurfaceMode = AUX_NONE,
216 .RedClearColor = 0,
217 .GreenClearColor = 0,
218 .BlueClearColor = 0,
219 .AlphaClearColor = 0,
220 .ShaderChannelSelectRed = vk_to_gen_swizzle[pCreateInfo->channels.r],
221 .ShaderChannelSelectGreen = vk_to_gen_swizzle[pCreateInfo->channels.g],
222 .ShaderChannelSelectBlue = vk_to_gen_swizzle[pCreateInfo->channels.b],
223 .ShaderChannelSelectAlpha = vk_to_gen_swizzle[pCreateInfo->channels.a],
224 .ResourceMinLOD = 0,
225 .SurfaceBaseAddress = { NULL, view->offset },
226 };
227
228 if (cmd_buffer)
229 view->surface_state =
230 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
231 else
232 view->surface_state =
233 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
234
235 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
236 }
237
238 VkResult anv_CreateImageView(
239 VkDevice _device,
240 const VkImageViewCreateInfo* pCreateInfo,
241 VkImageView* pView)
242 {
243 struct anv_device *device = (struct anv_device *) _device;
244 struct anv_surface_view *view;
245
246 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
247
248 view = anv_device_alloc(device, sizeof(*view), 8,
249 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
250 if (view == NULL)
251 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
252
253 anv_image_view_init(view, device, pCreateInfo, NULL);
254
255 *pView = (VkImageView) view;
256
257 return VK_SUCCESS;
258 }
259
260 void
261 anv_color_attachment_view_init(struct anv_surface_view *view,
262 struct anv_device *device,
263 const VkColorAttachmentViewCreateInfo* pCreateInfo,
264 struct anv_cmd_buffer *cmd_buffer)
265 {
266 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
267 const struct anv_format *format =
268 anv_format_for_vk_format(pCreateInfo->format);
269
270 view->bo = image->bo;
271 view->offset = image->offset;
272 view->extent = image->extent;
273 view->format = pCreateInfo->format;
274
275 if (cmd_buffer)
276 view->surface_state =
277 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
278 else
279 view->surface_state =
280 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
281
282 struct GEN8_RENDER_SURFACE_STATE surface_state = {
283 .SurfaceType = SURFTYPE_2D,
284 .SurfaceArray = false,
285 .SurfaceFormat = format->format,
286 .SurfaceVerticalAlignment = VALIGN4,
287 .SurfaceHorizontalAlignment = HALIGN4,
288 .TileMode = image->tile_mode,
289 .VerticalLineStride = 0,
290 .VerticalLineStrideOffset = 0,
291 .SamplerL2BypassModeDisable = true,
292 .RenderCacheReadWriteMode = WriteOnlyCache,
293 .MemoryObjectControlState = GEN8_MOCS,
294 .BaseMipLevel = 0,
295 .SurfaceQPitch = 0,
296 .Height = image->extent.height - 1,
297 .Width = image->extent.width - 1,
298 .Depth = image->extent.depth - 1,
299 .SurfacePitch = image->stride - 1,
300 .MinimumArrayElement = 0,
301 .NumberofMultisamples = MULTISAMPLECOUNT_1,
302 .XOffset = 0,
303 .YOffset = 0,
304 .SurfaceMinLOD = 0,
305 .MIPCountLOD = 0,
306 .AuxiliarySurfaceMode = AUX_NONE,
307 .RedClearColor = 0,
308 .GreenClearColor = 0,
309 .BlueClearColor = 0,
310 .AlphaClearColor = 0,
311 .ShaderChannelSelectRed = SCS_RED,
312 .ShaderChannelSelectGreen = SCS_GREEN,
313 .ShaderChannelSelectBlue = SCS_BLUE,
314 .ShaderChannelSelectAlpha = SCS_ALPHA,
315 .ResourceMinLOD = 0,
316 .SurfaceBaseAddress = { NULL, view->offset },
317 };
318
319 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
320 }
321
322 VkResult anv_CreateColorAttachmentView(
323 VkDevice _device,
324 const VkColorAttachmentViewCreateInfo* pCreateInfo,
325 VkColorAttachmentView* pView)
326 {
327 struct anv_device *device = (struct anv_device *) _device;
328 struct anv_surface_view *view;
329
330 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO);
331
332 view = anv_device_alloc(device, sizeof(*view), 8,
333 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
334 if (view == NULL)
335 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
336
337 anv_color_attachment_view_init(view, device, pCreateInfo, NULL);
338
339 *pView = (VkColorAttachmentView) view;
340
341 return VK_SUCCESS;
342 }
343
344 VkResult anv_CreateDepthStencilView(
345 VkDevice _device,
346 const VkDepthStencilViewCreateInfo* pCreateInfo,
347 VkDepthStencilView* pView)
348 {
349 struct anv_device *device = (struct anv_device *) _device;
350 struct anv_depth_stencil_view *view;
351 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
352 const struct anv_format *format =
353 anv_format_for_vk_format(image->format);
354
355 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO);
356
357 view = anv_device_alloc(device, sizeof(*view), 8,
358 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
359 if (view == NULL)
360 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
361
362 view->bo = image->bo;
363
364 view->depth_stride = image->stride;
365 view->depth_offset = image->offset;
366 view->depth_format = format->format;
367
368 view->stencil_stride = image->stencil_stride;
369 view->stencil_offset = image->offset + image->stencil_offset;
370
371 *pView = (VkDepthStencilView) view;
372
373 return VK_SUCCESS;
374 }