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
32 static const uint8_t anv_halign
[] = {
38 static const uint8_t anv_valign
[] = {
44 static const struct anv_tile_info
{
49 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
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
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 },
68 anv_image_choose_tile_mode(const VkImageCreateInfo
*vk_info
,
69 const struct anv_image_create_info
*anv_info
)
72 return anv_info
->tile_mode
;
74 switch (vk_info
->tiling
) {
75 case VK_IMAGE_TILING_LINEAR
:
77 case VK_IMAGE_TILING_OPTIMAL
:
80 assert(!"bad VKImageTiling");
85 VkResult
anv_image_create(
87 const VkImageCreateInfo
* pCreateInfo
,
88 const struct anv_image_create_info
* extra
,
91 struct anv_device
*device
= (struct anv_device
*) _device
;
92 struct anv_image
*image
;
93 const struct anv_format
*info
;
94 int32_t aligned_height
;
95 uint32_t stencil_size
;
97 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
99 image
= anv_device_alloc(device
, sizeof(*image
), 8,
100 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
102 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
104 /* XXX: We don't handle any of these */
105 anv_assert(pCreateInfo
->imageType
== VK_IMAGE_TYPE_2D
);
106 anv_assert(pCreateInfo
->mipLevels
== 1);
107 anv_assert(pCreateInfo
->arraySize
== 1);
108 anv_assert(pCreateInfo
->samples
== 1);
109 anv_assert(pCreateInfo
->extent
.depth
== 1);
113 image
->type
= pCreateInfo
->imageType
;
114 image
->format
= pCreateInfo
->format
;
115 image
->extent
= pCreateInfo
->extent
;
116 image
->swap_chain
= NULL
;
117 image
->tile_mode
= anv_image_choose_tile_mode(pCreateInfo
, extra
);
119 assert(image
->extent
.width
> 0);
120 assert(image
->extent
.height
> 0);
121 assert(image
->extent
.depth
> 0);
123 const struct anv_tile_info
*tile_info
=
124 &anv_tile_info_table
[image
->tile_mode
];
126 image
->alignment
= tile_info
->surface_alignment
;
128 /* FINISHME: Stop hardcoding miptree image alignment */
132 info
= anv_format_for_vk_format(pCreateInfo
->format
);
133 assert(info
->cpp
> 0 || info
->has_stencil
);
135 /* First allocate space for the color or depth buffer. info->cpp gives us
136 * the cpp of the color or depth in case of depth/stencil formats. Stencil
137 * only (VK_FORMAT_S8_UINT) has info->cpp == 0 and doesn't allocate
141 image
->stride
= ALIGN_I32(image
->extent
.width
* info
->cpp
,
143 aligned_height
= ALIGN_I32(image
->extent
.height
, tile_info
->height
);
144 image
->size
= image
->stride
* aligned_height
;
150 /* Formats with a stencil buffer (either combined depth/stencil or
151 * VK_FORMAT_S8_UINT) have info->has_stencil == true. The stencil buffer is
152 * placed after the depth buffer and is a separate buffer from the GPU
153 * point of view, but as far as the API is concerned, depth and stencil are
156 if (info
->has_stencil
) {
157 const struct anv_tile_info
*w_info
= &anv_tile_info_table
[WMAJOR
];
158 image
->stencil_offset
= ALIGN_U32(image
->size
, w_info
->surface_alignment
);
159 image
->stencil_stride
= ALIGN_I32(image
->extent
.width
, w_info
->width
);
160 aligned_height
= ALIGN_I32(image
->extent
.height
, w_info
->height
);
161 stencil_size
= image
->stencil_stride
* aligned_height
;
162 image
->size
= image
->stencil_offset
+ stencil_size
;
164 image
->stencil_offset
= 0;
165 image
->stencil_stride
= 0;
168 *pImage
= (VkImage
) image
;
173 VkResult
anv_CreateImage(
175 const VkImageCreateInfo
* pCreateInfo
,
178 return anv_image_create(device
, pCreateInfo
, NULL
, pImage
);
181 VkResult
anv_GetImageSubresourceInfo(
184 const VkImageSubresource
* pSubresource
,
185 VkSubresourceInfoType infoType
,
189 stub_return(VK_UNSUPPORTED
);
193 anv_surface_view_destroy(struct anv_device
*device
,
194 struct anv_object
*obj
, VkObjectType obj_type
)
196 struct anv_surface_view
*view
= (struct anv_surface_view
*)obj
;
198 assert(obj_type
== VK_OBJECT_TYPE_BUFFER_VIEW
||
199 obj_type
== VK_OBJECT_TYPE_IMAGE_VIEW
||
200 obj_type
== VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW
);
202 anv_state_pool_free(&device
->surface_state_pool
, view
->surface_state
);
204 anv_device_free(device
, view
);
208 anv_image_view_init(struct anv_surface_view
*view
,
209 struct anv_device
*device
,
210 const VkImageViewCreateInfo
* pCreateInfo
,
211 struct anv_cmd_buffer
*cmd_buffer
)
213 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
214 const struct anv_format
*info
=
215 anv_format_for_vk_format(pCreateInfo
->format
);
216 uint32_t tile_mode
, format
;
218 /* XXX: We don't handle any of these */
219 anv_assert(pCreateInfo
->viewType
== VK_IMAGE_VIEW_TYPE_2D
);
220 anv_assert(pCreateInfo
->subresourceRange
.baseMipLevel
== 0);
221 anv_assert(pCreateInfo
->subresourceRange
.mipLevels
== 1);
222 anv_assert(pCreateInfo
->subresourceRange
.baseArraySlice
== 0);
223 anv_assert(pCreateInfo
->subresourceRange
.arraySize
== 1);
225 view
->bo
= image
->bo
;
226 switch (pCreateInfo
->subresourceRange
.aspect
) {
227 case VK_IMAGE_ASPECT_STENCIL
:
228 /* FIXME: How is stencil texturing formed? */
229 view
->offset
= image
->offset
+ image
->stencil_offset
;
233 case VK_IMAGE_ASPECT_DEPTH
:
234 case VK_IMAGE_ASPECT_COLOR
:
235 view
->offset
= image
->offset
;
236 tile_mode
= image
->tile_mode
;
237 format
= info
->format
;
244 /* TODO: Miplevels */
245 view
->extent
= image
->extent
;
247 static const uint32_t vk_to_gen_swizzle
[] = {
248 [VK_CHANNEL_SWIZZLE_ZERO
] = SCS_ZERO
,
249 [VK_CHANNEL_SWIZZLE_ONE
] = SCS_ONE
,
250 [VK_CHANNEL_SWIZZLE_R
] = SCS_RED
,
251 [VK_CHANNEL_SWIZZLE_G
] = SCS_GREEN
,
252 [VK_CHANNEL_SWIZZLE_B
] = SCS_BLUE
,
253 [VK_CHANNEL_SWIZZLE_A
] = SCS_ALPHA
256 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
257 .SurfaceType
= SURFTYPE_2D
,
258 .SurfaceArray
= false,
259 .SurfaceFormat
= format
,
260 .SurfaceVerticalAlignment
= anv_valign
[image
->v_align
],
261 .SurfaceHorizontalAlignment
= anv_halign
[image
->h_align
],
262 .TileMode
= tile_mode
,
263 .VerticalLineStride
= 0,
264 .VerticalLineStrideOffset
= 0,
265 .SamplerL2BypassModeDisable
= true,
266 .RenderCacheReadWriteMode
= WriteOnlyCache
,
267 .MemoryObjectControlState
= GEN8_MOCS
,
270 .Height
= image
->extent
.height
- 1,
271 .Width
= image
->extent
.width
- 1,
272 .Depth
= image
->extent
.depth
- 1,
273 .SurfacePitch
= image
->stride
- 1,
274 .MinimumArrayElement
= 0,
275 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
280 .AuxiliarySurfaceMode
= AUX_NONE
,
282 .GreenClearColor
= 0,
284 .AlphaClearColor
= 0,
285 .ShaderChannelSelectRed
= vk_to_gen_swizzle
[pCreateInfo
->channels
.r
],
286 .ShaderChannelSelectGreen
= vk_to_gen_swizzle
[pCreateInfo
->channels
.g
],
287 .ShaderChannelSelectBlue
= vk_to_gen_swizzle
[pCreateInfo
->channels
.b
],
288 .ShaderChannelSelectAlpha
= vk_to_gen_swizzle
[pCreateInfo
->channels
.a
],
289 .ResourceMinLOD
= 0.0,
290 .SurfaceBaseAddress
= { NULL
, view
->offset
},
294 view
->surface_state
=
295 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
297 view
->surface_state
=
298 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
300 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
303 VkResult
anv_CreateImageView(
305 const VkImageViewCreateInfo
* pCreateInfo
,
308 struct anv_device
*device
= (struct anv_device
*) _device
;
309 struct anv_surface_view
*view
;
311 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
);
313 view
= anv_device_alloc(device
, sizeof(*view
), 8,
314 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
316 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
318 anv_image_view_init(view
, device
, pCreateInfo
, NULL
);
320 view
->base
.destructor
= anv_surface_view_destroy
;
322 *pView
= (VkImageView
) view
;
328 anv_color_attachment_view_init(struct anv_surface_view
*view
,
329 struct anv_device
*device
,
330 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
331 struct anv_cmd_buffer
*cmd_buffer
)
333 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
334 const struct anv_format
*format
=
335 anv_format_for_vk_format(pCreateInfo
->format
);
337 /* XXX: We don't handle any of these */
338 anv_assert(pCreateInfo
->mipLevel
== 0);
339 anv_assert(pCreateInfo
->baseArraySlice
== 0);
340 anv_assert(pCreateInfo
->arraySize
== 1);
341 anv_assert(pCreateInfo
->msaaResolveImage
== 0);
343 view
->bo
= image
->bo
;
344 view
->offset
= image
->offset
;
345 view
->extent
= image
->extent
;
346 view
->format
= pCreateInfo
->format
;
349 view
->surface_state
=
350 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
352 view
->surface_state
=
353 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
355 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
356 .SurfaceType
= SURFTYPE_2D
,
357 .SurfaceArray
= false,
358 .SurfaceFormat
= format
->format
,
359 .SurfaceVerticalAlignment
= anv_valign
[image
->v_align
],
360 .SurfaceHorizontalAlignment
= anv_halign
[image
->h_align
],
361 .TileMode
= image
->tile_mode
,
362 .VerticalLineStride
= 0,
363 .VerticalLineStrideOffset
= 0,
364 .SamplerL2BypassModeDisable
= true,
365 .RenderCacheReadWriteMode
= WriteOnlyCache
,
366 .MemoryObjectControlState
= GEN8_MOCS
,
369 .Height
= image
->extent
.height
- 1,
370 .Width
= image
->extent
.width
- 1,
371 .Depth
= image
->extent
.depth
- 1,
372 .SurfacePitch
= image
->stride
- 1,
373 .MinimumArrayElement
= 0,
374 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
379 .AuxiliarySurfaceMode
= AUX_NONE
,
381 .GreenClearColor
= 0,
383 .AlphaClearColor
= 0,
384 .ShaderChannelSelectRed
= SCS_RED
,
385 .ShaderChannelSelectGreen
= SCS_GREEN
,
386 .ShaderChannelSelectBlue
= SCS_BLUE
,
387 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
388 .ResourceMinLOD
= 0.0,
389 .SurfaceBaseAddress
= { NULL
, view
->offset
},
392 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
395 VkResult
anv_CreateColorAttachmentView(
397 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
398 VkColorAttachmentView
* pView
)
400 struct anv_device
*device
= (struct anv_device
*) _device
;
401 struct anv_surface_view
*view
;
403 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
);
405 view
= anv_device_alloc(device
, sizeof(*view
), 8,
406 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
408 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
410 anv_color_attachment_view_init(view
, device
, pCreateInfo
, NULL
);
412 view
->base
.destructor
= anv_surface_view_destroy
;
414 *pView
= (VkColorAttachmentView
) view
;
419 VkResult
anv_CreateDepthStencilView(
421 const VkDepthStencilViewCreateInfo
* pCreateInfo
,
422 VkDepthStencilView
* pView
)
424 struct anv_device
*device
= (struct anv_device
*) _device
;
425 struct anv_depth_stencil_view
*view
;
426 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
427 const struct anv_format
*format
=
428 anv_format_for_vk_format(image
->format
);
430 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO
);
432 view
= anv_device_alloc(device
, sizeof(*view
), 8,
433 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
435 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
437 /* XXX: We don't handle any of these */
438 anv_assert(pCreateInfo
->mipLevel
== 0);
439 anv_assert(pCreateInfo
->baseArraySlice
== 0);
440 anv_assert(pCreateInfo
->arraySize
== 1);
441 anv_assert(pCreateInfo
->msaaResolveImage
== 0);
443 view
->bo
= image
->bo
;
445 view
->depth_stride
= image
->stride
;
446 view
->depth_offset
= image
->offset
;
447 view
->depth_format
= format
->format
;
449 view
->stencil_stride
= image
->stencil_stride
;
450 view
->stencil_offset
= image
->offset
+ image
->stencil_offset
;
452 *pView
= (VkDepthStencilView
) view
;