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_tile_info
{
62 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
64 * To simplify calculations, the alignments defined in the table are
65 * sometimes larger than required. For example, Skylake requires that X and
66 * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
67 * alignment. We choose 4K to accomodate both chipsets. The alignment of
68 * a linear buffer depends on its element type and usage. Linear depth
69 * buffers have the largest alignment, 64B, so we choose that for all linear
72 uint32_t surface_alignment
;
73 } anv_tile_info_table
[] = {
74 [LINEAR
] = { 1, 1, 64 },
75 [XMAJOR
] = { 512, 8, 4096 },
76 [YMAJOR
] = { 128, 32, 4096 },
77 [WMAJOR
] = { 128, 32, 4096 },
81 anv_image_choose_tile_mode(const VkImageCreateInfo
*vk_info
,
82 const struct anv_image_create_info
*anv_info
)
85 return anv_info
->tile_mode
;
87 switch (vk_info
->tiling
) {
88 case VK_IMAGE_TILING_LINEAR
:
90 case VK_IMAGE_TILING_OPTIMAL
:
93 assert(!"bad VKImageTiling");
98 VkResult
anv_image_create(
100 const VkImageCreateInfo
* pCreateInfo
,
101 const struct anv_image_create_info
* extra
,
104 struct anv_device
*device
= (struct anv_device
*) _device
;
105 struct anv_image
*image
;
106 const struct anv_format
*info
;
107 int32_t aligned_height
;
108 uint32_t stencil_size
;
110 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
112 image
= anv_device_alloc(device
, sizeof(*image
), 8,
113 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
115 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
117 /* XXX: We don't handle any of these */
118 anv_assert(pCreateInfo
->imageType
== VK_IMAGE_TYPE_2D
);
119 anv_assert(pCreateInfo
->mipLevels
== 1);
120 anv_assert(pCreateInfo
->arraySize
== 1);
121 anv_assert(pCreateInfo
->samples
== 1);
122 anv_assert(pCreateInfo
->extent
.depth
== 1);
126 image
->type
= pCreateInfo
->imageType
;
127 image
->format
= pCreateInfo
->format
;
128 image
->extent
= pCreateInfo
->extent
;
129 image
->swap_chain
= NULL
;
130 image
->tile_mode
= anv_image_choose_tile_mode(pCreateInfo
, extra
);
132 assert(image
->extent
.width
> 0);
133 assert(image
->extent
.height
> 0);
134 assert(image
->extent
.depth
> 0);
136 const struct anv_tile_info
*tile_info
=
137 &anv_tile_info_table
[image
->tile_mode
];
139 image
->alignment
= tile_info
->surface_alignment
;
141 /* FINISHME: Stop hardcoding miptree image alignment */
145 info
= anv_format_for_vk_format(pCreateInfo
->format
);
146 assert(info
->cpp
> 0 || info
->has_stencil
);
148 /* First allocate space for the color or depth buffer. info->cpp gives us
149 * the cpp of the color or depth in case of depth/stencil formats. Stencil
150 * only (VK_FORMAT_S8_UINT) has info->cpp == 0 and doesn't allocate
154 image
->stride
= ALIGN_I32(image
->extent
.width
* info
->cpp
,
156 aligned_height
= ALIGN_I32(image
->extent
.height
, tile_info
->height
);
157 image
->size
= image
->stride
* aligned_height
;
163 /* Formats with a stencil buffer (either combined depth/stencil or
164 * VK_FORMAT_S8_UINT) have info->has_stencil == true. The stencil buffer is
165 * placed after the depth buffer and is a separate buffer from the GPU
166 * point of view, but as far as the API is concerned, depth and stencil are
169 if (info
->has_stencil
) {
170 const struct anv_tile_info
*w_info
= &anv_tile_info_table
[WMAJOR
];
171 image
->stencil_offset
= ALIGN_U32(image
->size
, w_info
->surface_alignment
);
172 image
->stencil_stride
= ALIGN_I32(image
->extent
.width
, w_info
->width
);
173 aligned_height
= ALIGN_I32(image
->extent
.height
, w_info
->height
);
174 stencil_size
= image
->stencil_stride
* aligned_height
;
175 image
->size
= image
->stencil_offset
+ stencil_size
;
177 image
->stencil_offset
= 0;
178 image
->stencil_stride
= 0;
181 *pImage
= (VkImage
) image
;
186 VkResult
anv_CreateImage(
188 const VkImageCreateInfo
* pCreateInfo
,
191 return anv_image_create(device
, pCreateInfo
, NULL
, pImage
);
194 VkResult
anv_GetImageSubresourceInfo(
197 const VkImageSubresource
* pSubresource
,
198 VkSubresourceInfoType infoType
,
202 stub_return(VK_UNSUPPORTED
);
206 anv_surface_view_destroy(struct anv_device
*device
,
207 struct anv_object
*obj
, VkObjectType obj_type
)
209 struct anv_surface_view
*view
= (struct anv_surface_view
*)obj
;
211 assert(obj_type
== VK_OBJECT_TYPE_BUFFER_VIEW
||
212 obj_type
== VK_OBJECT_TYPE_IMAGE_VIEW
||
213 obj_type
== VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW
);
215 anv_state_pool_free(&device
->surface_state_pool
, view
->surface_state
);
217 anv_device_free(device
, view
);
221 anv_image_view_init(struct anv_surface_view
*view
,
222 struct anv_device
*device
,
223 const VkImageViewCreateInfo
* pCreateInfo
,
224 struct anv_cmd_buffer
*cmd_buffer
)
226 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
227 const struct anv_format
*info
=
228 anv_format_for_vk_format(pCreateInfo
->format
);
229 uint32_t tile_mode
, format
;
231 /* XXX: We don't handle any of these */
232 anv_assert(pCreateInfo
->viewType
== VK_IMAGE_VIEW_TYPE_2D
);
233 anv_assert(pCreateInfo
->subresourceRange
.baseMipLevel
== 0);
234 anv_assert(pCreateInfo
->subresourceRange
.mipLevels
== 1);
235 anv_assert(pCreateInfo
->subresourceRange
.baseArraySlice
== 0);
236 anv_assert(pCreateInfo
->subresourceRange
.arraySize
== 1);
238 view
->bo
= image
->bo
;
239 switch (pCreateInfo
->subresourceRange
.aspect
) {
240 case VK_IMAGE_ASPECT_STENCIL
:
241 /* FIXME: How is stencil texturing formed? */
242 view
->offset
= image
->offset
+ image
->stencil_offset
;
246 case VK_IMAGE_ASPECT_DEPTH
:
247 case VK_IMAGE_ASPECT_COLOR
:
248 view
->offset
= image
->offset
;
249 tile_mode
= image
->tile_mode
;
250 format
= info
->format
;
257 /* TODO: Miplevels */
258 view
->extent
= image
->extent
;
260 static const uint32_t vk_to_gen_swizzle
[] = {
261 [VK_CHANNEL_SWIZZLE_ZERO
] = SCS_ZERO
,
262 [VK_CHANNEL_SWIZZLE_ONE
] = SCS_ONE
,
263 [VK_CHANNEL_SWIZZLE_R
] = SCS_RED
,
264 [VK_CHANNEL_SWIZZLE_G
] = SCS_GREEN
,
265 [VK_CHANNEL_SWIZZLE_B
] = SCS_BLUE
,
266 [VK_CHANNEL_SWIZZLE_A
] = SCS_ALPHA
269 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
270 .SurfaceType
= SURFTYPE_2D
,
271 .SurfaceArray
= false,
272 .SurfaceFormat
= format
,
273 .SurfaceVerticalAlignment
= anv_valign
[image
->v_align
],
274 .SurfaceHorizontalAlignment
= anv_halign
[image
->h_align
],
275 .TileMode
= tile_mode
,
276 .VerticalLineStride
= 0,
277 .VerticalLineStrideOffset
= 0,
278 .SamplerL2BypassModeDisable
= true,
279 .RenderCacheReadWriteMode
= WriteOnlyCache
,
280 .MemoryObjectControlState
= GEN8_MOCS
,
283 .Height
= image
->extent
.height
- 1,
284 .Width
= image
->extent
.width
- 1,
285 .Depth
= image
->extent
.depth
- 1,
286 .SurfacePitch
= image
->stride
- 1,
287 .MinimumArrayElement
= 0,
288 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
293 .AuxiliarySurfaceMode
= AUX_NONE
,
295 .GreenClearColor
= 0,
297 .AlphaClearColor
= 0,
298 .ShaderChannelSelectRed
= vk_to_gen_swizzle
[pCreateInfo
->channels
.r
],
299 .ShaderChannelSelectGreen
= vk_to_gen_swizzle
[pCreateInfo
->channels
.g
],
300 .ShaderChannelSelectBlue
= vk_to_gen_swizzle
[pCreateInfo
->channels
.b
],
301 .ShaderChannelSelectAlpha
= vk_to_gen_swizzle
[pCreateInfo
->channels
.a
],
302 .ResourceMinLOD
= 0.0,
303 .SurfaceBaseAddress
= { NULL
, view
->offset
},
307 view
->surface_state
=
308 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
310 view
->surface_state
=
311 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
313 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
316 VkResult
anv_CreateImageView(
318 const VkImageViewCreateInfo
* pCreateInfo
,
321 struct anv_device
*device
= (struct anv_device
*) _device
;
322 struct anv_surface_view
*view
;
324 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
);
326 view
= anv_device_alloc(device
, sizeof(*view
), 8,
327 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
329 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
331 anv_image_view_init(view
, device
, pCreateInfo
, NULL
);
333 view
->base
.destructor
= anv_surface_view_destroy
;
335 *pView
= (VkImageView
) view
;
341 anv_color_attachment_view_init(struct anv_surface_view
*view
,
342 struct anv_device
*device
,
343 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
344 struct anv_cmd_buffer
*cmd_buffer
)
346 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
347 const struct anv_format
*format
=
348 anv_format_for_vk_format(pCreateInfo
->format
);
350 /* XXX: We don't handle any of these */
351 anv_assert(pCreateInfo
->mipLevel
== 0);
352 anv_assert(pCreateInfo
->baseArraySlice
== 0);
353 anv_assert(pCreateInfo
->arraySize
== 1);
354 anv_assert(pCreateInfo
->msaaResolveImage
== 0);
356 view
->bo
= image
->bo
;
357 view
->offset
= image
->offset
;
358 view
->extent
= image
->extent
;
359 view
->format
= pCreateInfo
->format
;
362 view
->surface_state
=
363 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
365 view
->surface_state
=
366 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
368 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
369 .SurfaceType
= SURFTYPE_2D
,
370 .SurfaceArray
= false,
371 .SurfaceFormat
= format
->format
,
372 .SurfaceVerticalAlignment
= anv_valign
[image
->v_align
],
373 .SurfaceHorizontalAlignment
= anv_halign
[image
->h_align
],
374 .TileMode
= image
->tile_mode
,
375 .VerticalLineStride
= 0,
376 .VerticalLineStrideOffset
= 0,
377 .SamplerL2BypassModeDisable
= true,
378 .RenderCacheReadWriteMode
= WriteOnlyCache
,
379 .MemoryObjectControlState
= GEN8_MOCS
,
382 .Height
= image
->extent
.height
- 1,
383 .Width
= image
->extent
.width
- 1,
384 .Depth
= image
->extent
.depth
- 1,
385 .SurfacePitch
= image
->stride
- 1,
386 .MinimumArrayElement
= 0,
387 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
392 .AuxiliarySurfaceMode
= AUX_NONE
,
394 .GreenClearColor
= 0,
396 .AlphaClearColor
= 0,
397 .ShaderChannelSelectRed
= SCS_RED
,
398 .ShaderChannelSelectGreen
= SCS_GREEN
,
399 .ShaderChannelSelectBlue
= SCS_BLUE
,
400 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
401 .ResourceMinLOD
= 0.0,
402 .SurfaceBaseAddress
= { NULL
, view
->offset
},
405 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
408 VkResult
anv_CreateColorAttachmentView(
410 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
411 VkColorAttachmentView
* pView
)
413 struct anv_device
*device
= (struct anv_device
*) _device
;
414 struct anv_surface_view
*view
;
416 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
);
418 view
= anv_device_alloc(device
, sizeof(*view
), 8,
419 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
421 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
423 anv_color_attachment_view_init(view
, device
, pCreateInfo
, NULL
);
425 view
->base
.destructor
= anv_surface_view_destroy
;
427 *pView
= (VkColorAttachmentView
) view
;
432 VkResult
anv_CreateDepthStencilView(
434 const VkDepthStencilViewCreateInfo
* pCreateInfo
,
435 VkDepthStencilView
* pView
)
437 struct anv_device
*device
= (struct anv_device
*) _device
;
438 struct anv_depth_stencil_view
*view
;
439 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
440 const struct anv_format
*format
=
441 anv_format_for_vk_format(image
->format
);
443 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO
);
445 view
= anv_device_alloc(device
, sizeof(*view
), 8,
446 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
448 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
450 /* XXX: We don't handle any of these */
451 anv_assert(pCreateInfo
->mipLevel
== 0);
452 anv_assert(pCreateInfo
->baseArraySlice
== 0);
453 anv_assert(pCreateInfo
->arraySize
== 1);
454 anv_assert(pCreateInfo
->msaaResolveImage
== 0);
456 view
->bo
= image
->bo
;
458 view
->depth_stride
= image
->stride
;
459 view
->depth_offset
= image
->offset
;
460 view
->depth_format
= format
->format
;
462 view
->stencil_stride
= image
->stencil_stride
;
463 view
->stencil_offset
= image
->offset
+ image
->stencil_offset
;
465 *pView
= (VkDepthStencilView
) view
;