2 * Copyright © 2016 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
24 #include "anv_private.h"
27 lookup_blorp_shader(struct blorp_context
*blorp
,
28 const void *key
, uint32_t key_size
,
29 uint32_t *kernel_out
, void *prog_data_out
)
31 struct anv_device
*device
= blorp
->driver_ctx
;
33 /* The blorp cache must be a real cache */
34 assert(device
->blorp_shader_cache
.cache
);
36 struct anv_shader_bin
*bin
=
37 anv_pipeline_cache_search(&device
->blorp_shader_cache
, key
, key_size
);
41 /* The cache already has a reference and it's not going anywhere so there
42 * is no need to hold a second reference.
44 anv_shader_bin_unref(device
, bin
);
46 *kernel_out
= bin
->kernel
.offset
;
47 *(const struct brw_stage_prog_data
**)prog_data_out
=
48 anv_shader_bin_get_prog_data(bin
);
54 upload_blorp_shader(struct blorp_context
*blorp
,
55 const void *key
, uint32_t key_size
,
56 const void *kernel
, uint32_t kernel_size
,
57 const void *prog_data
, uint32_t prog_data_size
,
58 uint32_t *kernel_out
, void *prog_data_out
)
60 struct anv_device
*device
= blorp
->driver_ctx
;
62 /* The blorp cache must be a real cache */
63 assert(device
->blorp_shader_cache
.cache
);
65 struct anv_pipeline_bind_map bind_map
= {
70 struct anv_shader_bin
*bin
=
71 anv_pipeline_cache_upload_kernel(&device
->blorp_shader_cache
,
72 key
, key_size
, kernel
, kernel_size
,
73 prog_data
, prog_data_size
, &bind_map
);
75 /* The cache already has a reference and it's not going anywhere so there
76 * is no need to hold a second reference.
78 anv_shader_bin_unref(device
, bin
);
80 *kernel_out
= bin
->kernel
.offset
;
81 *(const struct brw_stage_prog_data
**)prog_data_out
=
82 anv_shader_bin_get_prog_data(bin
);
86 anv_device_init_blorp(struct anv_device
*device
)
88 anv_pipeline_cache_init(&device
->blorp_shader_cache
, device
, true);
89 blorp_init(&device
->blorp
, device
, &device
->isl_dev
);
90 device
->blorp
.compiler
= device
->instance
->physicalDevice
.compiler
;
91 device
->blorp
.mocs
.tex
= device
->default_mocs
;
92 device
->blorp
.mocs
.rb
= device
->default_mocs
;
93 device
->blorp
.mocs
.vb
= device
->default_mocs
;
94 device
->blorp
.lookup_shader
= lookup_blorp_shader
;
95 device
->blorp
.upload_shader
= upload_blorp_shader
;
96 switch (device
->info
.gen
) {
98 if (device
->info
.is_haswell
) {
99 device
->blorp
.exec
= gen75_blorp_exec
;
101 device
->blorp
.exec
= gen7_blorp_exec
;
105 device
->blorp
.exec
= gen8_blorp_exec
;
108 device
->blorp
.exec
= gen9_blorp_exec
;
111 unreachable("Unknown hardware generation");
116 anv_device_finish_blorp(struct anv_device
*device
)
118 blorp_finish(&device
->blorp
);
119 anv_pipeline_cache_finish(&device
->blorp_shader_cache
);
123 get_blorp_surf_for_anv_buffer(struct anv_device
*device
,
124 struct anv_buffer
*buffer
, uint64_t offset
,
125 uint32_t width
, uint32_t height
,
126 uint32_t row_pitch
, enum isl_format format
,
127 struct blorp_surf
*blorp_surf
,
128 struct isl_surf
*isl_surf
)
130 *blorp_surf
= (struct blorp_surf
) {
133 .buffer
= buffer
->bo
,
134 .offset
= buffer
->offset
+ offset
,
138 isl_surf_init(&device
->isl_dev
, isl_surf
,
139 .dim
= ISL_SURF_DIM_2D
,
147 .min_pitch
= row_pitch
,
148 .usage
= ISL_SURF_USAGE_TEXTURE_BIT
|
149 ISL_SURF_USAGE_RENDER_TARGET_BIT
,
150 .tiling_flags
= ISL_TILING_LINEAR_BIT
);
151 assert(isl_surf
->row_pitch
== row_pitch
);
155 get_blorp_surf_for_anv_image(const struct anv_image
*image
,
156 VkImageAspectFlags aspect
,
157 struct blorp_surf
*blorp_surf
)
159 const struct anv_surface
*surface
=
160 anv_image_get_surface_for_aspect_mask(image
, aspect
);
162 *blorp_surf
= (struct blorp_surf
) {
163 .surf
= &surface
->isl
,
166 .offset
= image
->offset
+ surface
->offset
,
172 copy_buffer_to_image(struct anv_cmd_buffer
*cmd_buffer
,
173 struct anv_buffer
*anv_buffer
,
174 struct anv_image
*anv_image
,
175 uint32_t regionCount
,
176 const VkBufferImageCopy
* pRegions
,
177 bool buffer_to_image
)
179 struct blorp_batch batch
;
180 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
);
183 struct blorp_surf surf
;
186 } image
, buffer
, *src
, *dst
;
189 buffer
.offset
= (VkOffset3D
) { 0, 0, 0 };
191 if (buffer_to_image
) {
199 for (unsigned r
= 0; r
< regionCount
; r
++) {
200 const VkImageAspectFlags aspect
= pRegions
[r
].imageSubresource
.aspectMask
;
202 get_blorp_surf_for_anv_image(anv_image
, aspect
, &image
.surf
);
204 anv_sanitize_image_offset(anv_image
->type
, pRegions
[r
].imageOffset
);
205 image
.level
= pRegions
[r
].imageSubresource
.mipLevel
;
208 anv_sanitize_image_extent(anv_image
->type
, pRegions
[r
].imageExtent
);
209 if (anv_image
->type
!= VK_IMAGE_TYPE_3D
) {
210 image
.offset
.z
= pRegions
[r
].imageSubresource
.baseArrayLayer
;
211 extent
.depth
= pRegions
[r
].imageSubresource
.layerCount
;
214 const enum isl_format buffer_format
=
215 anv_get_isl_format(&cmd_buffer
->device
->info
, anv_image
->vk_format
,
216 aspect
, VK_IMAGE_TILING_LINEAR
);
218 const VkExtent3D bufferImageExtent
= {
219 .width
= pRegions
[r
].bufferRowLength
?
220 pRegions
[r
].bufferRowLength
: extent
.width
,
221 .height
= pRegions
[r
].bufferImageHeight
?
222 pRegions
[r
].bufferImageHeight
: extent
.height
,
225 const struct isl_format_layout
*buffer_fmtl
=
226 isl_format_get_layout(buffer_format
);
228 const uint32_t buffer_row_pitch
=
229 DIV_ROUND_UP(bufferImageExtent
.width
, buffer_fmtl
->bw
) *
230 (buffer_fmtl
->bpb
/ 8);
232 const uint32_t buffer_layer_stride
=
233 DIV_ROUND_UP(bufferImageExtent
.height
, buffer_fmtl
->bh
) *
236 struct isl_surf buffer_isl_surf
;
237 get_blorp_surf_for_anv_buffer(cmd_buffer
->device
,
238 anv_buffer
, pRegions
[r
].bufferOffset
,
239 extent
.width
, extent
.height
,
240 buffer_row_pitch
, buffer_format
,
241 &buffer
.surf
, &buffer_isl_surf
);
243 for (unsigned z
= 0; z
< extent
.depth
; z
++) {
244 blorp_copy(&batch
, &src
->surf
, src
->level
, src
->offset
.z
,
245 &dst
->surf
, dst
->level
, dst
->offset
.z
,
246 src
->offset
.x
, src
->offset
.y
, dst
->offset
.x
, dst
->offset
.y
,
247 extent
.width
, extent
.height
);
250 buffer
.surf
.addr
.offset
+= buffer_layer_stride
;
254 blorp_batch_finish(&batch
);
257 void anv_CmdCopyBufferToImage(
258 VkCommandBuffer commandBuffer
,
261 VkImageLayout dstImageLayout
,
262 uint32_t regionCount
,
263 const VkBufferImageCopy
* pRegions
)
265 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
266 ANV_FROM_HANDLE(anv_buffer
, src_buffer
, srcBuffer
);
267 ANV_FROM_HANDLE(anv_image
, dst_image
, dstImage
);
269 copy_buffer_to_image(cmd_buffer
, src_buffer
, dst_image
,
270 regionCount
, pRegions
, true);
273 void anv_CmdCopyImageToBuffer(
274 VkCommandBuffer commandBuffer
,
276 VkImageLayout srcImageLayout
,
278 uint32_t regionCount
,
279 const VkBufferImageCopy
* pRegions
)
281 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
282 ANV_FROM_HANDLE(anv_image
, src_image
, srcImage
);
283 ANV_FROM_HANDLE(anv_buffer
, dst_buffer
, dstBuffer
);
285 copy_buffer_to_image(cmd_buffer
, dst_buffer
, src_image
,
286 regionCount
, pRegions
, false);
290 flip_coords(unsigned *src0
, unsigned *src1
, unsigned *dst0
, unsigned *dst1
)
294 unsigned tmp
= *src0
;
301 unsigned tmp
= *dst0
;
310 void anv_CmdBlitImage(
311 VkCommandBuffer commandBuffer
,
313 VkImageLayout srcImageLayout
,
315 VkImageLayout dstImageLayout
,
316 uint32_t regionCount
,
317 const VkImageBlit
* pRegions
,
321 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, commandBuffer
);
322 ANV_FROM_HANDLE(anv_image
, src_image
, srcImage
);
323 ANV_FROM_HANDLE(anv_image
, dst_image
, dstImage
);
325 struct blorp_surf src
, dst
;
329 case VK_FILTER_NEAREST
:
330 gl_filter
= 0x2600; /* GL_NEAREST */
332 case VK_FILTER_LINEAR
:
333 gl_filter
= 0x2601; /* GL_LINEAR */
336 unreachable("Invalid filter");
339 struct blorp_batch batch
;
340 blorp_batch_init(&cmd_buffer
->device
->blorp
, &batch
, cmd_buffer
);
342 for (unsigned r
= 0; r
< regionCount
; r
++) {
343 const VkImageSubresourceLayers
*src_res
= &pRegions
[r
].srcSubresource
;
344 const VkImageSubresourceLayers
*dst_res
= &pRegions
[r
].dstSubresource
;
346 get_blorp_surf_for_anv_image(src_image
, src_res
->aspectMask
, &src
);
347 get_blorp_surf_for_anv_image(dst_image
, dst_res
->aspectMask
, &dst
);
349 struct anv_format src_format
=
350 anv_get_format(&cmd_buffer
->device
->info
, src_image
->vk_format
,
351 src_res
->aspectMask
, src_image
->tiling
);
352 struct anv_format dst_format
=
353 anv_get_format(&cmd_buffer
->device
->info
, dst_image
->vk_format
,
354 dst_res
->aspectMask
, dst_image
->tiling
);
356 unsigned dst_start
, dst_end
;
357 if (dst_image
->type
== VK_IMAGE_TYPE_3D
) {
358 assert(dst_res
->baseArrayLayer
== 0);
359 dst_start
= pRegions
[r
].dstOffsets
[0].z
;
360 dst_end
= pRegions
[r
].dstOffsets
[1].z
;
362 dst_start
= dst_res
->baseArrayLayer
;
363 dst_end
= dst_start
+ dst_res
->layerCount
;
366 unsigned src_start
, src_end
;
367 if (src_image
->type
== VK_IMAGE_TYPE_3D
) {
368 assert(src_res
->baseArrayLayer
== 0);
369 src_start
= pRegions
[r
].srcOffsets
[0].z
;
370 src_end
= pRegions
[r
].srcOffsets
[1].z
;
372 src_start
= src_res
->baseArrayLayer
;
373 src_end
= src_start
+ src_res
->layerCount
;
376 bool flip_z
= flip_coords(&src_start
, &src_end
, &dst_start
, &dst_end
);
377 float src_z_step
= (float)(src_end
+ 1 - src_start
) /
378 (float)(dst_end
+ 1 - dst_start
);
385 unsigned src_x0
= pRegions
[r
].srcOffsets
[0].x
;
386 unsigned src_x1
= pRegions
[r
].srcOffsets
[1].x
;
387 unsigned dst_x0
= pRegions
[r
].dstOffsets
[0].x
;
388 unsigned dst_x1
= pRegions
[r
].dstOffsets
[1].x
;
389 bool flip_x
= flip_coords(&src_x0
, &src_x1
, &dst_x0
, &dst_x1
);
391 unsigned src_y0
= pRegions
[r
].srcOffsets
[0].y
;
392 unsigned src_y1
= pRegions
[r
].srcOffsets
[1].y
;
393 unsigned dst_y0
= pRegions
[r
].dstOffsets
[0].y
;
394 unsigned dst_y1
= pRegions
[r
].dstOffsets
[1].y
;
395 bool flip_y
= flip_coords(&src_y0
, &src_y1
, &dst_y0
, &dst_y1
);
397 const unsigned num_layers
= dst_end
- dst_start
;
398 for (unsigned i
= 0; i
< num_layers
; i
++) {
399 unsigned dst_z
= dst_start
+ i
;
400 unsigned src_z
= src_start
+ i
* src_z_step
;
402 blorp_blit(&batch
, &src
, src_res
->mipLevel
, src_z
,
403 src_format
.isl_format
, src_format
.swizzle
,
404 &dst
, dst_res
->mipLevel
, dst_z
,
405 dst_format
.isl_format
, dst_format
.swizzle
,
406 src_x0
, src_y0
, src_x1
, src_y1
,
407 dst_x0
, dst_y0
, dst_x1
, dst_y1
,
408 gl_filter
, flip_x
, flip_y
);
413 blorp_batch_finish(&batch
);