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
:
76 if (unlikely(vk_info
->format
== VK_FORMAT_S8_UINT
)) {
77 anv_abortf("requested linear stencil buffer");
80 case VK_IMAGE_TILING_OPTIMAL
:
81 if (unlikely(vk_info
->format
== VK_FORMAT_S8_UINT
)) {
87 assert(!"bad VKImageTiling");
92 VkResult
anv_image_create(
94 const VkImageCreateInfo
* pCreateInfo
,
95 const struct anv_image_create_info
* extra
,
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
;
104 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
106 image
= anv_device_alloc(device
, sizeof(*image
), 8,
107 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
109 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
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);
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
);
126 assert(image
->extent
.width
> 0);
127 assert(image
->extent
.height
> 0);
128 assert(image
->extent
.depth
> 0);
130 const struct anv_tile_info
*tile_info
=
131 &anv_tile_info_table
[image
->tile_mode
];
133 image
->alignment
= tile_info
->surface_alignment
;
135 /* FINISHME: Stop hardcoding miptree image alignment */
139 info
= anv_format_for_vk_format(pCreateInfo
->format
);
140 assert(info
->cpp
> 0 || info
->has_stencil
);
143 image
->stride
= ALIGN_I32(image
->extent
.width
* info
->cpp
,
145 aligned_height
= ALIGN_I32(image
->extent
.height
, tile_info
->height
);
146 image
->size
= image
->stride
* aligned_height
;
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
;
160 image
->stencil_offset
= 0;
161 image
->stencil_stride
= 0;
164 *pImage
= (VkImage
) image
;
169 VkResult
anv_CreateImage(
171 const VkImageCreateInfo
* pCreateInfo
,
174 return anv_image_create(device
, pCreateInfo
, NULL
, pImage
);
177 VkResult
anv_GetImageSubresourceInfo(
180 const VkImageSubresource
* pSubresource
,
181 VkSubresourceInfoType infoType
,
185 stub_return(VK_UNSUPPORTED
);
189 anv_surface_view_destroy(struct anv_device
*device
,
190 struct anv_object
*obj
, VkObjectType obj_type
)
192 struct anv_surface_view
*view
= (struct anv_surface_view
*)obj
;
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
);
198 anv_state_pool_free(&device
->surface_state_pool
, view
->surface_state
);
200 anv_device_free(device
, view
);
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
)
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
;
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);
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
;
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
;
240 /* TODO: Miplevels */
241 view
->extent
= image
->extent
;
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
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
,
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
,
276 .AuxiliarySurfaceMode
= AUX_NONE
,
278 .GreenClearColor
= 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
},
290 view
->surface_state
=
291 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
293 view
->surface_state
=
294 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
296 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
299 VkResult
anv_CreateImageView(
301 const VkImageViewCreateInfo
* pCreateInfo
,
304 struct anv_device
*device
= (struct anv_device
*) _device
;
305 struct anv_surface_view
*view
;
307 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
);
309 view
= anv_device_alloc(device
, sizeof(*view
), 8,
310 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
312 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
314 anv_image_view_init(view
, device
, pCreateInfo
, NULL
);
316 view
->base
.destructor
= anv_surface_view_destroy
;
318 *pView
= (VkImageView
) view
;
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
)
329 struct anv_image
*image
= (struct anv_image
*) pCreateInfo
->image
;
330 const struct anv_format
*format
=
331 anv_format_for_vk_format(pCreateInfo
->format
);
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);
339 view
->bo
= image
->bo
;
340 view
->offset
= image
->offset
;
341 view
->extent
= image
->extent
;
342 view
->format
= pCreateInfo
->format
;
345 view
->surface_state
=
346 anv_state_stream_alloc(&cmd_buffer
->surface_state_stream
, 64, 64);
348 view
->surface_state
=
349 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
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
,
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
,
375 .AuxiliarySurfaceMode
= AUX_NONE
,
377 .GreenClearColor
= 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
},
388 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
391 VkResult
anv_CreateColorAttachmentView(
393 const VkColorAttachmentViewCreateInfo
* pCreateInfo
,
394 VkColorAttachmentView
* pView
)
396 struct anv_device
*device
= (struct anv_device
*) _device
;
397 struct anv_surface_view
*view
;
399 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO
);
401 view
= anv_device_alloc(device
, sizeof(*view
), 8,
402 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
404 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
406 anv_color_attachment_view_init(view
, device
, pCreateInfo
, NULL
);
408 view
->base
.destructor
= anv_surface_view_destroy
;
410 *pView
= (VkColorAttachmentView
) view
;
415 VkResult
anv_CreateDepthStencilView(
417 const VkDepthStencilViewCreateInfo
* pCreateInfo
,
418 VkDepthStencilView
* pView
)
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
);
426 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO
);
428 view
= anv_device_alloc(device
, sizeof(*view
), 8,
429 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
431 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
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);
439 view
->bo
= image
->bo
;
441 view
->depth_stride
= image
->stride
;
442 view
->depth_offset
= image
->offset
;
443 view
->depth_format
= format
->format
;
445 view
->stencil_stride
= image
->stencil_stride
;
446 view
->stencil_offset
= image
->offset
+ image
->stencil_offset
;
448 *pView
= (VkDepthStencilView
) view
;