blob: 2ea964e1cf81eafcac909a21cc7391d2e7e60006 [file] [log] [blame]
Chia-I Wuc14d1562014-10-17 09:49:22 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28#include "img.h"
29#include "mem.h"
30#include "cmd_priv.h"
31
32static void cmd_meta_init_mem_view(struct intel_cmd *cmd,
33 XGL_GPU_MEMORY mem,
34 XGL_GPU_SIZE range,
35 XGL_FORMAT format,
36 XGL_MEMORY_STATE state,
37 struct intel_mem_view *view)
38{
39 XGL_MEMORY_VIEW_ATTACH_INFO info;
40
41 memset(&info, 0, sizeof(info));
42 info.sType = XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO;
43 info.mem = mem;
44 info.range = range;
45 info.stride = icd_format_get_size(format);
46 info.format = format;
47 info.state = state;
48
49 intel_mem_view_init(view, cmd->dev, &info);
50}
51
52static void cmd_meta_set_src_for_mem(struct intel_cmd *cmd,
53 const struct intel_mem *mem,
54 XGL_FORMAT format,
55 struct intel_cmd_meta *meta)
56{
57 struct intel_mem_view view;
58
59 cmd_meta_init_mem_view(cmd, (XGL_GPU_MEMORY) mem, mem->size, format,
60 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
61
62 meta->src.valid = true;
63
64 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
65 meta->src.surface_len = view.cmd_len;
66
67 meta->src.reloc_target = (intptr_t) mem->bo;
68 meta->src.reloc_offset = 0;
69 meta->src.reloc_flags = 0;
70}
71
72static void cmd_meta_set_dst_for_mem(struct intel_cmd *cmd,
73 const struct intel_mem *mem,
74 XGL_FORMAT format,
75 struct intel_cmd_meta *meta)
76{
77 struct intel_mem_view view;
78
79 cmd_meta_init_mem_view(cmd, (XGL_GPU_MEMORY) mem, mem->size, format,
80 XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY, &view);
81
82 meta->dst.valid = true;
83
84 memcpy(meta->dst.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
85 meta->dst.surface_len = view.cmd_len;
86
87 meta->dst.reloc_target = (intptr_t) mem->bo;
88 meta->dst.reloc_offset = 0;
89 meta->dst.reloc_flags = 0;
90}
91
92static void cmd_meta_set_src_for_img(struct intel_cmd *cmd,
93 const struct intel_img *img,
94 XGL_FORMAT format,
95 XGL_IMAGE_ASPECT aspect,
96 struct intel_cmd_meta *meta)
97{
98 XGL_IMAGE_VIEW_CREATE_INFO info;
99 struct intel_img_view *view;
100 XGL_RESULT ret;
101
102 memset(&info, 0, sizeof(info));
103 info.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
104 info.image = (XGL_IMAGE) img;
105
106 switch (img->type) {
107 case XGL_IMAGE_1D:
108 info.viewType = XGL_IMAGE_VIEW_1D;
109 break;
110 case XGL_IMAGE_2D:
111 info.viewType = XGL_IMAGE_VIEW_2D;
112 break;
113 case XGL_IMAGE_3D:
114 info.viewType = XGL_IMAGE_VIEW_3D;
115 break;
116 default:
117 break;
118 }
119
120 info.format = format;
121 info.channels.r = XGL_CHANNEL_SWIZZLE_R;
122 info.channels.g = XGL_CHANNEL_SWIZZLE_G;
123 info.channels.b = XGL_CHANNEL_SWIZZLE_B;
124 info.channels.a = XGL_CHANNEL_SWIZZLE_A;
125 info.subresourceRange.aspect = aspect;
126 info.subresourceRange.baseMipLevel = 0;
127 info.subresourceRange.mipLevels = XGL_LAST_MIP_OR_SLICE;
128 info.subresourceRange.baseArraySlice = 0;
129 info.subresourceRange.arraySize = XGL_LAST_MIP_OR_SLICE;
130
131 ret = intel_img_view_create(cmd->dev, &info, &view);
132 if (ret != XGL_SUCCESS) {
133 cmd->result = ret;
134 return;
135 }
136
137 meta->src.valid = true;
138
139 memcpy(meta->src.surface, view->cmd,
140 sizeof(view->cmd[0]) * view->cmd_len);
141 meta->src.surface_len = view->cmd_len;
142
143 meta->src.reloc_target = (intptr_t) img->obj.mem->bo;
144 meta->src.reloc_offset = 0;
145 meta->src.reloc_flags = 0;
146
147 intel_img_view_destroy(view);
148}
149
150static void cmd_meta_set_dst_for_img(struct intel_cmd *cmd,
151 const struct intel_img *img,
152 XGL_FORMAT format,
153 XGL_UINT lod, XGL_UINT layer,
154 struct intel_cmd_meta *meta)
155{
156 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO info;
157 struct intel_rt_view *rt;
158 XGL_RESULT ret;
159
160 memset(&info, 0, sizeof(info));
161 info.sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO;
162 info.image = (XGL_IMAGE) img;
163 info.format = format;
164 info.mipLevel = lod;
165 info.baseArraySlice = layer;
166 info.arraySize = 1;
167
168 ret = intel_rt_view_create(cmd->dev, &info, &rt);
169 if (ret != XGL_SUCCESS) {
170 cmd->result = ret;
171 return;
172 }
173
174 meta->dst.valid = true;
175
176 memcpy(meta->dst.surface, rt->cmd, sizeof(rt->cmd[0]) * rt->cmd_len);
177 meta->dst.surface_len = rt->cmd_len;
178
179 meta->dst.reloc_target = (intptr_t) img->obj.mem->bo;
180 meta->dst.reloc_offset = 0;
181 meta->dst.reloc_flags = 0;
182
183 intel_rt_view_destroy(rt);
184}
185
186static void cmd_meta_set_src_for_writer(struct intel_cmd *cmd,
187 enum intel_cmd_writer_type writer,
188 XGL_GPU_SIZE size,
189 XGL_FORMAT format,
190 struct intel_cmd_meta *meta)
191{
192 struct intel_mem_view view;
193
194 cmd_meta_init_mem_view(cmd, XGL_NULL_HANDLE, size, format,
195 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
196
197 meta->src.valid = true;
198
199 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
200 meta->src.surface_len = view.cmd_len;
201
202 meta->src.reloc_target = (intptr_t) writer;
203 meta->src.reloc_offset = 0;
204 meta->src.reloc_flags = INTEL_CMD_RELOC_TARGET_IS_WRITER;
205}
206
207static void cmd_meta_set_ds(struct intel_cmd *cmd,
208 const struct intel_img *img,
209 XGL_UINT lod, XGL_UINT layer,
210 struct intel_cmd_meta *meta)
211{
212 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO info;
213 struct intel_ds_view *ds;
214 XGL_RESULT ret;
215
216 memset(&info, 0, sizeof(info));
217 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
218 info.image = (XGL_IMAGE) img;
219 info.mipLevel = lod;
220 info.baseArraySlice = layer;
221 info.arraySize = 1;
222
223 ret = intel_ds_view_create(cmd->dev, &info, &ds);
224 if (ret != XGL_SUCCESS) {
225 cmd->result = ret;
226 return;
227 }
228
229 meta->ds = ds;
230}
231
232static enum intel_dev_meta_shader get_shader_id(const struct intel_dev *dev,
233 const struct intel_img *img,
234 bool copy_array)
235{
236 enum intel_dev_meta_shader shader_id;
237
238 switch (img->type) {
239 case XGL_IMAGE_1D:
240 shader_id = (copy_array) ?
241 INTEL_DEV_META_FS_COPY_1D_ARRAY : INTEL_DEV_META_FS_COPY_1D;
242 break;
243 case XGL_IMAGE_2D:
244 shader_id = (img->samples > 1) ? INTEL_DEV_META_FS_COPY_2D_MS :
245 (copy_array) ? INTEL_DEV_META_FS_COPY_2D_ARRAY :
246 INTEL_DEV_META_FS_COPY_2D;
247 break;
248 case XGL_IMAGE_3D:
249 default:
250 shader_id = INTEL_DEV_META_FS_COPY_2D_ARRAY;
251 break;
252 }
253
254 return shader_id;
255}
256
257/**
258 * Return the suitable format for copying between memories. The
259 * format is sampleable, renderable, and the offsets and copy size are
260 * multiples of the format size.
261 */
262static XGL_CHANNEL_FORMAT cmd_meta_mem_channel_format(const struct intel_cmd *cmd,
263 XGL_GPU_SIZE src_offset,
264 XGL_GPU_SIZE dst_offset,
265 XGL_GPU_SIZE size,
266 XGL_SIZE *format_size)
267{
268 const XGL_GPU_SIZE align = (src_offset | dst_offset | size) & 0xf;
269
270 if (align & 0x1) {
271 *format_size = 1;
272 return XGL_CH_FMT_R8;
273 } else if (align & 0x2) {
274 *format_size = 2;
275 return XGL_CH_FMT_R16;
276 } else if (align & 0x4) {
277 *format_size = 4;
278 return XGL_CH_FMT_R32;
279 } else if (align & 0x8) {
280 *format_size = 8;
281 return XGL_CH_FMT_R32G32;
282 } else {
283 *format_size = 16;
284 return XGL_CH_FMT_R32G32B32A32;
285 }
286}
287
288static XGL_FORMAT cmd_meta_img_raw_format(const struct intel_cmd *cmd,
289 XGL_FORMAT format)
290{
291 format.numericFormat = XGL_NUM_FMT_UINT;
292
293 if (icd_format_is_compressed(format)) {
294 switch (icd_format_get_size(format)) {
295 case 1:
296 format.channelFormat = XGL_CH_FMT_R8;
297 break;
298 case 2:
299 format.channelFormat = XGL_CH_FMT_R16;
300 break;
301 case 4:
302 format.channelFormat = XGL_CH_FMT_R32;
303 break;
304 case 8:
305 format.channelFormat = XGL_CH_FMT_R32G32;
306 break;
307 case 16:
308 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
309 break;
310 default:
311 assert(!"unsupported compressed block size");
312 format.channelFormat = XGL_CH_FMT_R8;
313 break;
314 }
315 }
316
317 return format;
318}
319
320XGL_VOID XGLAPI intelCmdCopyMemory(
321 XGL_CMD_BUFFER cmdBuffer,
322 XGL_GPU_MEMORY srcMem,
323 XGL_GPU_MEMORY destMem,
324 XGL_UINT regionCount,
325 const XGL_MEMORY_COPY* pRegions)
326{
327 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
328 struct intel_mem *src = intel_mem(srcMem);
329 struct intel_mem *dst = intel_mem(destMem);
330 struct intel_cmd_meta meta;
331 XGL_FORMAT format;
332 XGL_UINT i;
333
334 memset(&meta, 0, sizeof(meta));
335
336 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM;
337 meta.height = 1;
338 meta.samples = 1;
339
340 format.channelFormat = XGL_CH_FMT_UNDEFINED;
341 format.numericFormat = XGL_NUM_FMT_UINT;
342
343 for (i = 0; i < regionCount; i++) {
344 const XGL_MEMORY_COPY *region = &pRegions[i];
345 XGL_CHANNEL_FORMAT ch;
346 XGL_SIZE format_size;
347
348 ch = cmd_meta_mem_channel_format(cmd, region->srcOffset,
349 region->destOffset, region->copySize, &format_size);
350
351 if (format.channelFormat != ch) {
352 format.channelFormat = ch;
353
354 cmd_meta_set_src_for_mem(cmd, src, format, &meta);
355 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
356 }
357
358 meta.src.x = region->srcOffset / format_size;
359 meta.dst.x = region->destOffset / format_size;
360 meta.width = region->copySize / format_size;
361
362 cmd_draw_meta(cmd, &meta);
363 }
364}
365
366XGL_VOID XGLAPI intelCmdCopyImage(
367 XGL_CMD_BUFFER cmdBuffer,
368 XGL_IMAGE srcImage,
369 XGL_IMAGE destImage,
370 XGL_UINT regionCount,
371 const XGL_IMAGE_COPY* pRegions)
372{
373 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
374 struct intel_img *src = intel_img(srcImage);
375 struct intel_img *dst = intel_img(destImage);
376 struct intel_cmd_meta meta;
377 XGL_FORMAT raw_format;
378 bool raw_copy;
379 XGL_UINT i;
380
381 if (src->type != dst->type) {
382 cmd->result = XGL_ERROR_UNKNOWN;
383 return;
384 }
385
386 if (icd_format_is_equal(src->layout.format, dst->layout.format)) {
387 raw_copy = true;
388 raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
389 } else if (icd_format_is_compressed(src->layout.format) ||
390 icd_format_is_compressed(dst->layout.format)) {
391 cmd->result = XGL_ERROR_UNKNOWN;
392 return;
393 }
394
395 memset(&meta, 0, sizeof(meta));
396
397 cmd_meta_set_src_for_img(cmd, src,
398 (raw_copy) ? raw_format : src->layout.format,
399 XGL_IMAGE_ASPECT_COLOR, &meta);
400
401 meta.samples = dst->samples;
402
403 for (i = 0; i < regionCount; i++) {
404 const XGL_IMAGE_COPY *region = &pRegions[i];
405 XGL_UINT j;
406
407 meta.shader_id = get_shader_id(cmd->dev, src,
408 (region->extent.depth > 1));
409
410 meta.src.lod = region->srcSubresource.mipLevel;
411 meta.src.layer = region->srcSubresource.arraySlice +
412 region->srcOffset.z;
413 meta.src.x = region->srcOffset.x;
414 meta.src.y = region->srcOffset.y;
415
416 meta.dst.lod = region->destSubresource.mipLevel;
417 meta.dst.layer = region->destSubresource.arraySlice +
418 region->destOffset.z;
419 meta.dst.x = region->destOffset.x;
420 meta.dst.y = region->destOffset.y;
421
422 meta.width = region->extent.width;
423 meta.height = region->extent.height;
424
425 for (j = 0; j < region->extent.depth; j++) {
426 cmd_meta_set_dst_for_img(cmd, dst,
427 (raw_copy) ? raw_format : dst->layout.format,
428 meta.dst.lod, meta.dst.layer, &meta);
429
430 cmd_draw_meta(cmd, &meta);
431
432 meta.src.layer++;
433 meta.dst.layer++;
434 }
435 }
436}
437
438XGL_VOID XGLAPI intelCmdCopyMemoryToImage(
439 XGL_CMD_BUFFER cmdBuffer,
440 XGL_GPU_MEMORY srcMem,
441 XGL_IMAGE destImage,
442 XGL_UINT regionCount,
443 const XGL_MEMORY_IMAGE_COPY* pRegions)
444{
445 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
446 struct intel_mem *mem = intel_mem(srcMem);
447 struct intel_img *img = intel_img(destImage);
448 struct intel_cmd_meta meta;
449 XGL_FORMAT format;
450 XGL_UINT i;
451
452 memset(&meta, 0, sizeof(meta));
453
454 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM_TO_IMG;
455 meta.samples = img->samples;
456
457 format = cmd_meta_img_raw_format(cmd, img->layout.format);
458 cmd_meta_set_src_for_mem(cmd, mem, format, &meta);
459
460 for (i = 0; i < regionCount; i++) {
461 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
462 XGL_UINT j;
463
464 meta.src.x = region->memOffset / icd_format_get_size(format);
465
466 meta.dst.lod = region->imageSubresource.mipLevel;
467 meta.dst.layer = region->imageSubresource.arraySlice +
468 region->imageOffset.z;
469 meta.dst.x = region->imageOffset.x;
470 meta.dst.y = region->imageOffset.y;
471
472 meta.width = region->imageExtent.width;
473 meta.height = region->imageExtent.height;
474
475 for (j = 0; j < region->imageExtent.depth; j++) {
476 cmd_meta_set_dst_for_img(cmd, img, format,
477 meta.dst.lod, meta.dst.layer, &meta);
478
479 cmd_draw_meta(cmd, &meta);
480
481 meta.src.x += meta.width * meta.height;
482 meta.dst.layer++;
483 }
484 }
485}
486
487XGL_VOID XGLAPI intelCmdCopyImageToMemory(
488 XGL_CMD_BUFFER cmdBuffer,
489 XGL_IMAGE srcImage,
490 XGL_GPU_MEMORY destMem,
491 XGL_UINT regionCount,
492 const XGL_MEMORY_IMAGE_COPY* pRegions)
493{
494 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
495 struct intel_img *img = intel_img(srcImage);
496 struct intel_mem *mem = intel_mem(destMem);
497 struct intel_cmd_meta meta;
498 XGL_FORMAT format;
499 XGL_UINT i;
500
501 memset(&meta, 0, sizeof(meta));
502
503 format = cmd_meta_img_raw_format(cmd, img->layout.format);
504 cmd_meta_set_src_for_img(cmd, img, format, XGL_IMAGE_ASPECT_COLOR, &meta);
505 cmd_meta_set_dst_for_mem(cmd, mem, format, &meta);
506
507 meta.height = 1;
508 meta.samples = 1;
509
510 for (i = 0; i < regionCount; i++) {
511 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
512 XGL_UINT j;
513
514 meta.shader_id = get_shader_id(cmd->dev, img,
515 (region->imageExtent.depth > 1));
516
517 meta.src.lod = region->imageSubresource.mipLevel;
518 meta.src.layer = region->imageSubresource.arraySlice +
519 region->imageOffset.z;
520 meta.src.x = region->imageOffset.x;
521 meta.src.y = region->imageOffset.y;
522
523 meta.dst.x = region->memOffset / icd_format_get_size(format);
524
525 meta.width = region->imageExtent.width * region->imageExtent.height;
526
527 for (j = 0; j < region->imageExtent.depth; j++) {
528 cmd_draw_meta(cmd, &meta);
529
530 meta.src.layer++;
531 meta.dst.x += meta.width;
532 }
533 }
534}
535
536XGL_VOID XGLAPI intelCmdCloneImageData(
537 XGL_CMD_BUFFER cmdBuffer,
538 XGL_IMAGE srcImage,
539 XGL_IMAGE_STATE srcImageState,
540 XGL_IMAGE destImage,
541 XGL_IMAGE_STATE destImageState)
542{
543 const struct intel_img *src = intel_img(srcImage);
544 XGL_IMAGE_COPY region;
545 XGL_UINT lv;
546
547 memset(&region, 0, sizeof(region));
548 region.srcSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
549 region.destSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
550
551 for (lv = 0; lv < src->mip_levels; lv++) {
552 region.srcSubresource.mipLevel = lv;
553 region.destSubresource.mipLevel = lv;
554
555 region.extent.width = u_minify(src->layout.width0, lv);
556 region.extent.height = u_minify(src->layout.height0, lv);
557 region.extent.depth = src->array_size;
558
559 intelCmdCopyImage(cmdBuffer, srcImage, destImage, 1, &region);
560 }
561}
562
563XGL_VOID XGLAPI intelCmdUpdateMemory(
564 XGL_CMD_BUFFER cmdBuffer,
565 XGL_GPU_MEMORY destMem,
566 XGL_GPU_SIZE destOffset,
567 XGL_GPU_SIZE dataSize,
568 const XGL_UINT32* pData)
569{
570 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
571 struct intel_mem *dst = intel_mem(destMem);
572 struct intel_cmd_meta meta;
573 XGL_FORMAT format;
574 XGL_SIZE format_size;
575 uint32_t *ptr;
576 uint32_t offset;
577
578 /* write to dynamic state writer first */
579 offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
580 (dataSize + 3) / 4, &ptr);
581 memcpy(ptr, pData, dataSize);
582
583 format.channelFormat = cmd_meta_mem_channel_format(cmd,
584 offset, destOffset, dataSize, &format_size);
585 format.numericFormat = XGL_NUM_FMT_UINT;
586
587 memset(&meta, 0, sizeof(meta));
588
589 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM;
590
591 cmd_meta_set_src_for_writer(cmd, INTEL_CMD_WRITER_STATE,
592 offset + dataSize, format, &meta);
593 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
594
595 meta.src.x = offset / format_size;
596 meta.dst.x = destOffset / format_size;
597 meta.width = dataSize / format_size;
598 meta.height = 1;
599 meta.samples = 1;
600
601 cmd_draw_meta(cmd, &meta);
602}
603
604XGL_VOID XGLAPI intelCmdFillMemory(
605 XGL_CMD_BUFFER cmdBuffer,
606 XGL_GPU_MEMORY destMem,
607 XGL_GPU_SIZE destOffset,
608 XGL_GPU_SIZE fillSize,
609 XGL_UINT32 data)
610{
611 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
612 struct intel_mem *dst = intel_mem(destMem);
613 struct intel_cmd_meta meta;
614 XGL_FORMAT format;
615 XGL_SIZE format_size;
616
617 /* must be 4-byte aligned */
618 if ((destOffset | fillSize) & 3) {
619 cmd->result = XGL_ERROR_UNKNOWN;
620 return;
621 }
622
623 memset(&meta, 0, sizeof(meta));
624
625 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
626
627 meta.clear_val[0] = data;
628 meta.clear_val[1] = data;
629 meta.clear_val[2] = data;
630 meta.clear_val[3] = data;
631
632 format.channelFormat = cmd_meta_mem_channel_format(cmd,
633 0, destOffset, fillSize, &format_size);;
634 format.numericFormat = XGL_NUM_FMT_UINT;
635 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
636
637 meta.dst.x = destOffset / format_size;
638 meta.width = fillSize / format_size;
639 meta.height = 1;
640 meta.samples = 1;
641
642 cmd_draw_meta(cmd, &meta);
643}
644
645static void cmd_meta_clear_image(struct intel_cmd *cmd,
646 struct intel_img *img,
647 XGL_FORMAT format,
648 struct intel_cmd_meta *meta,
649 const XGL_IMAGE_SUBRESOURCE_RANGE *range)
650{
651 XGL_UINT mip_levels, array_size;
652 XGL_UINT i, j;
653
654 if (range->baseMipLevel >= img->mip_levels ||
655 range->baseArraySlice >= img->array_size)
656 return;
657
658 mip_levels = img->mip_levels - range->baseMipLevel;
659 if (mip_levels > range->mipLevels)
660 mip_levels = range->mipLevels;
661
662 array_size = img->array_size - range->baseArraySlice;
663 if (array_size > range->arraySize)
664 array_size = range->arraySize;
665
666 meta->dst.lod = range->baseMipLevel;
667 meta->dst.layer = range->baseArraySlice;
668
669 for (i = 0; i < mip_levels; i++) {
670 meta->width = u_minify(img->layout.width0, meta->dst.lod);
671 meta->height = u_minify(img->layout.height0, meta->dst.lod);
672
673 for (j = 0; j < array_size; j++) {
674 if (range->aspect == XGL_IMAGE_ASPECT_COLOR) {
675 cmd_meta_set_dst_for_img(cmd, img, format,
676 meta->dst.lod, meta->dst.layer, meta);
677
678 cmd_draw_meta(cmd, meta);
679 } else {
680 cmd_meta_set_ds(cmd, img, meta->dst.lod,
681 meta->dst.layer, meta);
682
683 cmd_draw_meta(cmd, meta);
684
685 intel_ds_view_destroy(meta->ds);
686 }
687
688 meta->dst.layer++;
689 }
690
691 meta->dst.lod++;
692 }
693}
694
695XGL_VOID XGLAPI intelCmdClearColorImage(
696 XGL_CMD_BUFFER cmdBuffer,
697 XGL_IMAGE image,
698 const XGL_FLOAT color[4],
699 XGL_UINT rangeCount,
700 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
701{
702 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
703 struct intel_img *img = intel_img(image);
704 struct intel_cmd_meta meta;
705 XGL_UINT i;
706
707 memset(&meta, 0, sizeof(meta));
708
709 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
710 meta.samples = img->samples;
711
712 meta.clear_val[0] = u_fui(color[0]);
713 meta.clear_val[1] = u_fui(color[1]);
714 meta.clear_val[2] = u_fui(color[2]);
715 meta.clear_val[3] = u_fui(color[3]);
716
717 for (i = 0; i < rangeCount; i++) {
718 cmd_meta_clear_image(cmd, img, img->layout.format,
719 &meta, &pRanges[i]);
720 }
721}
722
723XGL_VOID XGLAPI intelCmdClearColorImageRaw(
724 XGL_CMD_BUFFER cmdBuffer,
725 XGL_IMAGE image,
726 const XGL_UINT32 color[4],
727 XGL_UINT rangeCount,
728 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
729{
730 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
731 struct intel_img *img = intel_img(image);
732 struct intel_cmd_meta meta;
733 XGL_FORMAT format;
734 XGL_UINT i;
735
736 memset(&meta, 0, sizeof(meta));
737
738 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
739 meta.samples = img->samples;
740
741 meta.clear_val[0] = color[0];
742 meta.clear_val[1] = color[1];
743 meta.clear_val[2] = color[2];
744 meta.clear_val[3] = color[3];
745
746 format = cmd_meta_img_raw_format(cmd, img->layout.format);
747
748 for (i = 0; i < rangeCount; i++)
749 cmd_meta_clear_image(cmd, img, format, &meta, &pRanges[i]);
750}
751
752XGL_VOID XGLAPI intelCmdClearDepthStencil(
753 XGL_CMD_BUFFER cmdBuffer,
754 XGL_IMAGE image,
755 XGL_FLOAT depth,
756 XGL_UINT32 stencil,
757 XGL_UINT rangeCount,
758 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
759{
760 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
761 struct intel_img *img = intel_img(image);
762 struct intel_cmd_meta meta;
763 XGL_UINT i;
764
765 memset(&meta, 0, sizeof(meta));
766
767 meta.shader_id = INTEL_DEV_META_FS_CLEAR_DEPTH;
768 meta.samples = img->samples;
769
770 for (i = 0; i < rangeCount; i++) {
771 const XGL_IMAGE_SUBRESOURCE_RANGE *range = &pRanges[i];
772
773 if (range->aspect == XGL_IMAGE_ASPECT_STENCIL)
774 meta.clear_val[0] = stencil;
775 else
776 meta.clear_val[0] = u_fui(depth);
777
778 cmd_meta_clear_image(cmd, img, img->layout.format,
779 &meta, range);
780 }
781}
782
783XGL_VOID XGLAPI intelCmdResolveImage(
784 XGL_CMD_BUFFER cmdBuffer,
785 XGL_IMAGE srcImage,
786 XGL_IMAGE destImage,
787 XGL_UINT rectCount,
788 const XGL_IMAGE_RESOLVE* pRects)
789{
790 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
791 struct intel_img *src = intel_img(srcImage);
792 struct intel_img *dst = intel_img(destImage);
793 struct intel_cmd_meta meta;
794 XGL_FORMAT format;
795 XGL_UINT i;
796
797 if (src->samples <= 1 || dst->samples > 1 ||
798 !icd_format_is_equal(src->layout.format, dst->layout.format)) {
799 cmd->result = XGL_ERROR_UNKNOWN;
800 return;
801 }
802
803 memset(&meta, 0, sizeof(meta));
804
805 switch (src->samples) {
806 case 2:
807 default:
808 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_2X;
809 break;
810 case 4:
811 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_4X;
812 break;
813 case 8:
814 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_8X;
815 break;
816 case 16:
817 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_16X;
818 break;
819 }
820
821 meta.samples = 1;
822
823 format = cmd_meta_img_raw_format(cmd, src->layout.format);
824 cmd_meta_set_src_for_img(cmd, src, format, XGL_IMAGE_ASPECT_COLOR, &meta);
825
826 for (i = 0; i < rectCount; i++) {
827 const XGL_IMAGE_RESOLVE *rect = &pRects[i];
828
829 meta.src.lod = rect->srcSubresource.mipLevel;
830 meta.src.layer = rect->srcSubresource.arraySlice;
831 meta.src.x = rect->srcOffset.x;
832 meta.src.y = rect->srcOffset.y;
833
834 meta.dst.lod = rect->destSubresource.mipLevel;
835 meta.dst.layer = rect->destSubresource.arraySlice;
836 meta.dst.x = rect->destOffset.x;
837 meta.dst.y = rect->destOffset.y;
838
839 meta.width = rect->extent.width;
840 meta.height = rect->extent.height;
841
842 cmd_meta_set_dst_for_img(cmd, dst, format,
843 meta.dst.lod, meta.dst.layer, &meta);
844
845 cmd_draw_meta(cmd, &meta);
846 }
847}