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 uint8_t anv_surf_type_from_image_type
[] = {
45 [VK_IMAGE_TYPE_1D
] = SURFTYPE_1D
,
46 [VK_IMAGE_TYPE_2D
] = SURFTYPE_2D
,
47 [VK_IMAGE_TYPE_3D
] = SURFTYPE_3D
,
50 static const uint8_t anv_surf_type_from_image_view_type
[] = {
51 [VK_IMAGE_VIEW_TYPE_1D
] = SURFTYPE_1D
,
52 [VK_IMAGE_VIEW_TYPE_2D
] = SURFTYPE_2D
,
53 [VK_IMAGE_VIEW_TYPE_3D
] = SURFTYPE_3D
,
54 [VK_IMAGE_VIEW_TYPE_CUBE
] = SURFTYPE_CUBE
,
57 static const struct anv_surf_type_limits
{
61 } anv_surf_type_limits
[] = {
62 [SURFTYPE_1D
] = {16384, 0, 2048},
63 [SURFTYPE_2D
] = {16384, 16384, 2048},
64 [SURFTYPE_3D
] = {2048, 2048, 2048},
65 [SURFTYPE_CUBE
] = {16384, 16384, 340},
66 [SURFTYPE_BUFFER
] = {128, 16384, 64},
67 [SURFTYPE_STRBUF
] = {128, 16384, 64},
70 static const struct anv_tile_info
{
75 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
77 * To simplify calculations, the alignments defined in the table are
78 * sometimes larger than required. For example, Skylake requires that X and
79 * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
80 * alignment. We choose 4K to accomodate both chipsets. The alignment of
81 * a linear buffer depends on its element type and usage. Linear depth
82 * buffers have the largest alignment, 64B, so we choose that for all linear
85 uint32_t surface_alignment
;
86 } anv_tile_info_table
[] = {
87 [LINEAR
] = { 1, 1, 64 },
88 [XMAJOR
] = { 512, 8, 4096 },
89 [YMAJOR
] = { 128, 32, 4096 },
90 [WMAJOR
] = { 128, 32, 4096 },
94 anv_image_choose_tile_mode(const VkImageCreateInfo
*vk_info
,
95 const struct anv_image_create_info
*anv_info
)
98 return anv_info
->tile_mode
;
100 switch (vk_info
->tiling
) {
101 case VK_IMAGE_TILING_LINEAR
:
103 case VK_IMAGE_TILING_OPTIMAL
:
106 assert(!"bad VKImageTiling");
111 VkResult
anv_image_create(
113 const VkImageCreateInfo
* pCreateInfo
,
114 const struct anv_image_create_info
* extra
,
117 struct anv_device
*device
= (struct anv_device
*) _device
;
118 struct anv_image
*image
;
119 const struct anv_format
*info
;
120 int32_t aligned_height
;
121 uint32_t stencil_size
;
123 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
125 image
= anv_device_alloc(device
, sizeof(*image
), 8,
126 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
128 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
130 /* XXX: We don't handle any of these */
131 anv_assert(pCreateInfo
->imageType
== VK_IMAGE_TYPE_2D
);
132 anv_assert(pCreateInfo
->mipLevels
== 1);
133 anv_assert(pCreateInfo
->arraySize
== 1);
134 anv_assert(pCreateInfo
->samples
== 1);
135 anv_assert(pCreateInfo
->extent
.depth
== 1);
139 image
->type
= pCreateInfo
->imageType
;
140 image
->format
= pCreateInfo
->format
;
141 image
->extent
= pCreateInfo
->extent
;
142 image
->swap_chain
= NULL
;
143 image
->tile_mode
= anv_image_choose_tile_mode(pCreateInfo
, extra
);
145 /* TODO(chadv): How should we validate inputs? */
146 image
->surf_type
= anv_surf_type_from_image_type
[pCreateInfo
->imageType
];
148 const struct anv_surf_type_limits
*limits
=
149 &anv_surf_type_limits
[image
->surf_type
];
151 assert(image
->extent
.width
> 0);
152 assert(image
->extent
.height
> 0);
153 assert(image
->extent
.depth
> 0);
155 const struct anv_tile_info
*tile_info
=
156 &anv_tile_info_table
[image
->tile_mode
];
158 if (image
->extent
.width
> limits
->width
||
159 image
->extent
.height
> limits
->height
||
160 image
->extent
.depth
> limits
->depth
) {
161 anv_loge("image extent is too large");
164 /* TODO(chadv): What is the correct error? */
165 return vk_error(VK_ERROR_INVALID_MEMORY_SIZE
);
168 image
->alignment
= tile_info
->surface_alignment
;
170 /* FINISHME: Stop hardcoding miptree image alignment */
174 info
= anv_format_for_vk_format(pCreateInfo
->format
);
175 assert(info
->cpp
> 0 || info
->has_stencil
);
177 /* First allocate space for the color or depth buffer. info->cpp gives us
178 * the cpp of the color or depth in case of depth/stencil formats. Stencil
179 * only (VK_FORMAT_S8_UINT) has info->cpp == 0 and doesn't allocate
183 image
->stride
= ALIGN_I32(image
->extent
.width
* info
->cpp
,
185 aligned_height
= ALIGN_I32(image
->extent
.height
, tile_info
->height
);
186 image
->size
= image
->stride
* aligned_height
;
192 /* Formats with a stencil buffer (either combined depth/stencil or
193 * VK_FORMAT_S8_UINT) have info->has_stencil == true. The stencil buffer is
194 * placed after the depth buffer and is a separate buffer from the GPU
195 * point of view, but as far as the API is concerned, depth and stencil are
198 if (info
->has_stencil
) {
199 const struct anv_tile_info
*w_info
= &anv_tile_info_table
[WMAJOR
];
200 image
->stencil_offset
= ALIGN_U32(image
->size
, w_info
->surface_alignment
);
201 image
->stencil_stride
= ALIGN_I32(image
->extent
.width
, w_info
->width
);
202 aligned_height
= ALIGN_I32(image
->extent
.height
, w_info
->height
);
203 stencil_size
= image
->stencil_stride
* aligned_height
;
204 image
->size
= image
->stencil_offset
+ stencil_size
;
206 image
->stencil_offset
= 0;
207 image
->stencil_stride
= 0;
210 *pImage
= (VkImage
) image
;
215 VkResult
anv_CreateImage(
217 const VkImageCreateInfo
* pCreateInfo
,
220 return anv_image_create(device
, pCreateInfo
, NULL
, pImage
);
223 VkResult
anv_GetImageSubresourceInfo(
226 const VkImageSubresource
* pSubresource
,
227 VkSubresourceInfoType infoType
,
231 stub_return(VK_UNSUPPORTED
);
235 anv_surface_view_destroy(struct anv_device
*device
,
236 struct anv_object
*obj
, VkObjectType obj_type
)
238 struct anv_surface_view
*view
= (struct anv_surface_view
*)obj
;
240 assert(obj_type
== VK_OBJECT_TYPE_BUFFER_VIEW
||
241 obj_type
== VK_OBJECT_TYPE_IMAGE_VIEW
||
242 obj_type
== VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW
);
244 anv_state_pool_free(&device
->surface_state_pool
, view
->surface_state
);
246 anv_device_free(device
, view
);
250 anv_image_view_init(struct anv_surface_view
*view
,
251 struct anv_device
*device
,
252 const VkImageViewCreateInfo
* pCreateInfo
,
253 struct anv_cmd_buffer
*cmd_buffer
)
255 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
256 const struct anv_format
*info
=
257 anv_format_for_vk_format(pCreateInfo
->format
);
258 uint32_t tile_mode
, format
;
260 /* XXX: We don't handle any of these */
261 anv_assert(pCreateInfo
->viewType
== VK_IMAGE_VIEW_TYPE_2D
);
262 anv_assert(pCreateInfo
->subresourceRange
.baseMipLevel
== 0);
263 anv_assert(pCreateInfo
->subresourceRange
.mipLevels
== 1);
264 anv_assert(pCreateInfo
->subresourceRange
.baseArraySlice
== 0);
265 anv_assert(pCreateInfo
->subresourceRange
.arraySize
== 1);
267 view
->bo
= image
->bo
;
268 switch (pCreateInfo
->subresourceRange
.aspect
) {
269 case VK_IMAGE_ASPECT_STENCIL
:
270 /* FIXME: How is stencil texturing formed? */
271 view
->offset
= image
->offset
+ image
->stencil_offset
;
275 case VK_IMAGE_ASPECT_DEPTH
:
276 case VK_IMAGE_ASPECT_COLOR
:
277 view
->offset
= image
->offset
;
278 tile_mode
= image
->tile_mode
;
279 format
= info
->format
;
286 /* TODO: Miplevels */
287 view
->extent
= image
->extent
;
289 static const uint32_t vk_to_gen_swizzle
[] = {
290 [VK_CHANNEL_SWIZZLE_ZERO
] = SCS_ZERO
,
291 [VK_CHANNEL_SWIZZLE_ONE
] = SCS_ONE
,
292 [VK_CHANNEL_SWIZZLE_R
] = SCS_RED
,
293 [VK_CHANNEL_SWIZZLE_G
] = SCS_GREEN
,
294 [VK_CHANNEL_SWIZZLE_B
] = SCS_BLUE
,
295 [VK_CHANNEL_SWIZZLE_A
] = SCS_ALPHA
298 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
299 .SurfaceType
= anv_surf_type_from_image_view_type
[pCreateInfo
->viewType
],
300 .SurfaceArray
= false,
301 .SurfaceFormat
= format
,
302 .SurfaceVerticalAlignment
= anv_valign
[image
->v_align
],
303 .SurfaceHorizontalAlignment
= anv_halign
[image
->h_align
],
304 .TileMode
= tile_mode
,
305 .VerticalLineStride
= 0,
306 .VerticalLineStrideOffset
= 0,
307 .SamplerL2BypassModeDisable
= true,
308 .RenderCacheReadWriteMode
= WriteOnlyCache
,
309 .MemoryObjectControlState
= GEN8_MOCS
,
312 .Height
= image
->extent
.height
- 1,
313 .Width
= image
->extent
.width
- 1,
314 .Depth
= image
->extent
.depth
- 1,
315 .SurfacePitch
= image
->stride
- 1,
316 .MinimumArrayElement
= 0,
317 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
322 .AuxiliarySurfaceMode
= AUX_NONE
,
324 .GreenClearColor
= 0,
326 .AlphaClearColor
= 0,
327 .ShaderChannelSelectRed
= vk_to_gen_swizzle
[pCreateInfo
->channels
.r
],
328 .ShaderChannelSelectGreen
= vk_to_gen_swizzle
[pCreateInfo
->channels
.g
],
329 .ShaderChannelSelectBlue
= vk_to_gen_swizzle
[pCreateInfo
->channels
.b
],
330 .ShaderChannelSelectAlpha
= vk_to_gen_swizzle
[pCreateInfo
->channels
.a
],
331 .ResourceMinLOD
= 0.0,
332 .SurfaceBaseAddress
= { NULL
, view
->offset
},
336 view
->surface_state
=
337 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
339 view
->surface_state
=
340 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
342 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
345 VkResult
anv_CreateImageView(
347 const VkImageViewCreateInfo
* pCreateInfo
,
350 struct anv_device
*device
= (struct anv_device
*) _device
;
351 struct anv_surface_view
*view
;
353 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
);
355 view
= anv_device_alloc(device
, sizeof(*view
), 8,
356 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
358 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
360 anv_image_view_init(view
, device
, pCreateInfo
, NULL
);
362 view
->base
.destructor
= anv_surface_view_destroy
;
364 *pView
= (VkImageView
) view
;
370 anv_color_attachment_view_init(struct anv_surface_view
*view
,
371 struct anv_device
*device
,
372 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
373 struct anv_cmd_buffer
*cmd_buffer
)
375 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
376 const struct anv_format
*format
=
377 anv_format_for_vk_format(pCreateInfo
->format
);
379 /* XXX: We don't handle any of these */
380 anv_assert(pCreateInfo
->mipLevel
== 0);
381 anv_assert(pCreateInfo
->baseArraySlice
== 0);
382 anv_assert(pCreateInfo
->arraySize
== 1);
383 anv_assert(pCreateInfo
->msaaResolveImage
== 0);
385 view
->bo
= image
->bo
;
386 view
->offset
= image
->offset
;
387 view
->extent
= image
->extent
;
388 view
->format
= pCreateInfo
->format
;
391 view
->surface_state
=
392 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
394 view
->surface_state
=
395 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
397 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
398 .SurfaceType
= SURFTYPE_2D
,
399 .SurfaceArray
= false,
400 .SurfaceFormat
= format
->format
,
401 .SurfaceVerticalAlignment
= anv_valign
[image
->v_align
],
402 .SurfaceHorizontalAlignment
= anv_halign
[image
->h_align
],
403 .TileMode
= image
->tile_mode
,
404 .VerticalLineStride
= 0,
405 .VerticalLineStrideOffset
= 0,
406 .SamplerL2BypassModeDisable
= true,
407 .RenderCacheReadWriteMode
= WriteOnlyCache
,
408 .MemoryObjectControlState
= GEN8_MOCS
,
411 .Height
= image
->extent
.height
- 1,
412 .Width
= image
->extent
.width
- 1,
413 .Depth
= image
->extent
.depth
- 1,
414 .SurfacePitch
= image
->stride
- 1,
415 .MinimumArrayElement
= 0,
416 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
421 .AuxiliarySurfaceMode
= AUX_NONE
,
423 .GreenClearColor
= 0,
425 .AlphaClearColor
= 0,
426 .ShaderChannelSelectRed
= SCS_RED
,
427 .ShaderChannelSelectGreen
= SCS_GREEN
,
428 .ShaderChannelSelectBlue
= SCS_BLUE
,
429 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
430 .ResourceMinLOD
= 0.0,
431 .SurfaceBaseAddress
= { NULL
, view
->offset
},
434 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
437 VkResult
anv_CreateColorAttachmentView(
439 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
440 VkColorAttachmentView
* pView
)
442 struct anv_device
*device
= (struct anv_device
*) _device
;
443 struct anv_surface_view
*view
;
445 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
);
447 view
= anv_device_alloc(device
, sizeof(*view
), 8,
448 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
450 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
452 anv_color_attachment_view_init(view
, device
, pCreateInfo
, NULL
);
454 view
->base
.destructor
= anv_surface_view_destroy
;
456 *pView
= (VkColorAttachmentView
) view
;
461 VkResult
anv_CreateDepthStencilView(
463 const VkDepthStencilViewCreateInfo
* pCreateInfo
,
464 VkDepthStencilView
* pView
)
466 struct anv_device
*device
= (struct anv_device
*) _device
;
467 struct anv_depth_stencil_view
*view
;
468 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
469 const struct anv_format
*format
=
470 anv_format_for_vk_format(image
->format
);
472 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO
);
474 view
= anv_device_alloc(device
, sizeof(*view
), 8,
475 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
477 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
479 /* XXX: We don't handle any of these */
480 anv_assert(pCreateInfo
->mipLevel
== 0);
481 anv_assert(pCreateInfo
->baseArraySlice
== 0);
482 anv_assert(pCreateInfo
->arraySize
== 1);
483 anv_assert(pCreateInfo
->msaaResolveImage
== 0);
485 view
->bo
= image
->bo
;
487 view
->depth_stride
= image
->stride
;
488 view
->depth_offset
= image
->offset
;
489 view
->depth_format
= format
->format
;
491 view
->stencil_stride
= image
->stencil_stride
;
492 view
->stencil_offset
= image
->offset
+ image
->stencil_offset
;
494 *pView
= (VkDepthStencilView
) view
;