blob: 6627c84a3ad55963986dbc81a7ceb85076bd3464 [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"
Chia-I Wu429a0aa2014-10-24 11:57:51 +080030#include "state.h"
Chia-I Wuc14d1562014-10-17 09:49:22 +080031#include "cmd_priv.h"
32
33static void cmd_meta_init_mem_view(struct intel_cmd *cmd,
34 XGL_GPU_MEMORY mem,
35 XGL_GPU_SIZE range,
36 XGL_FORMAT format,
37 XGL_MEMORY_STATE state,
38 struct intel_mem_view *view)
39{
40 XGL_MEMORY_VIEW_ATTACH_INFO info;
41
42 memset(&info, 0, sizeof(info));
43 info.sType = XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO;
44 info.mem = mem;
45 info.range = range;
46 info.stride = icd_format_get_size(format);
47 info.format = format;
48 info.state = state;
49
50 intel_mem_view_init(view, cmd->dev, &info);
51}
52
53static void cmd_meta_set_src_for_mem(struct intel_cmd *cmd,
54 const struct intel_mem *mem,
55 XGL_FORMAT format,
56 struct intel_cmd_meta *meta)
57{
58 struct intel_mem_view view;
59
60 cmd_meta_init_mem_view(cmd, (XGL_GPU_MEMORY) mem, mem->size, format,
61 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
62
63 meta->src.valid = true;
64
65 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
66 meta->src.surface_len = view.cmd_len;
67
68 meta->src.reloc_target = (intptr_t) mem->bo;
69 meta->src.reloc_offset = 0;
70 meta->src.reloc_flags = 0;
71}
72
73static void cmd_meta_set_dst_for_mem(struct intel_cmd *cmd,
74 const struct intel_mem *mem,
75 XGL_FORMAT format,
76 struct intel_cmd_meta *meta)
77{
78 struct intel_mem_view view;
79
80 cmd_meta_init_mem_view(cmd, (XGL_GPU_MEMORY) mem, mem->size, format,
81 XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY, &view);
82
83 meta->dst.valid = true;
84
85 memcpy(meta->dst.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
86 meta->dst.surface_len = view.cmd_len;
87
88 meta->dst.reloc_target = (intptr_t) mem->bo;
89 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +080090 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +080091}
92
93static void cmd_meta_set_src_for_img(struct intel_cmd *cmd,
94 const struct intel_img *img,
95 XGL_FORMAT format,
96 XGL_IMAGE_ASPECT aspect,
97 struct intel_cmd_meta *meta)
98{
99 XGL_IMAGE_VIEW_CREATE_INFO info;
100 struct intel_img_view *view;
101 XGL_RESULT ret;
102
103 memset(&info, 0, sizeof(info));
104 info.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
105 info.image = (XGL_IMAGE) img;
106
107 switch (img->type) {
108 case XGL_IMAGE_1D:
109 info.viewType = XGL_IMAGE_VIEW_1D;
110 break;
111 case XGL_IMAGE_2D:
112 info.viewType = XGL_IMAGE_VIEW_2D;
113 break;
114 case XGL_IMAGE_3D:
115 info.viewType = XGL_IMAGE_VIEW_3D;
116 break;
117 default:
118 break;
119 }
120
121 info.format = format;
122 info.channels.r = XGL_CHANNEL_SWIZZLE_R;
123 info.channels.g = XGL_CHANNEL_SWIZZLE_G;
124 info.channels.b = XGL_CHANNEL_SWIZZLE_B;
125 info.channels.a = XGL_CHANNEL_SWIZZLE_A;
126 info.subresourceRange.aspect = aspect;
127 info.subresourceRange.baseMipLevel = 0;
128 info.subresourceRange.mipLevels = XGL_LAST_MIP_OR_SLICE;
129 info.subresourceRange.baseArraySlice = 0;
130 info.subresourceRange.arraySize = XGL_LAST_MIP_OR_SLICE;
131
132 ret = intel_img_view_create(cmd->dev, &info, &view);
133 if (ret != XGL_SUCCESS) {
134 cmd->result = ret;
135 return;
136 }
137
138 meta->src.valid = true;
139
140 memcpy(meta->src.surface, view->cmd,
141 sizeof(view->cmd[0]) * view->cmd_len);
142 meta->src.surface_len = view->cmd_len;
143
144 meta->src.reloc_target = (intptr_t) img->obj.mem->bo;
145 meta->src.reloc_offset = 0;
146 meta->src.reloc_flags = 0;
147
148 intel_img_view_destroy(view);
149}
150
151static void cmd_meta_set_dst_for_img(struct intel_cmd *cmd,
152 const struct intel_img *img,
153 XGL_FORMAT format,
154 XGL_UINT lod, XGL_UINT layer,
155 struct intel_cmd_meta *meta)
156{
157 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO info;
158 struct intel_rt_view *rt;
159 XGL_RESULT ret;
160
161 memset(&info, 0, sizeof(info));
162 info.sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO;
163 info.image = (XGL_IMAGE) img;
164 info.format = format;
165 info.mipLevel = lod;
166 info.baseArraySlice = layer;
167 info.arraySize = 1;
168
169 ret = intel_rt_view_create(cmd->dev, &info, &rt);
170 if (ret != XGL_SUCCESS) {
171 cmd->result = ret;
172 return;
173 }
174
175 meta->dst.valid = true;
176
177 memcpy(meta->dst.surface, rt->cmd, sizeof(rt->cmd[0]) * rt->cmd_len);
178 meta->dst.surface_len = rt->cmd_len;
179
180 meta->dst.reloc_target = (intptr_t) img->obj.mem->bo;
181 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +0800182 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800183
184 intel_rt_view_destroy(rt);
185}
186
187static void cmd_meta_set_src_for_writer(struct intel_cmd *cmd,
188 enum intel_cmd_writer_type writer,
189 XGL_GPU_SIZE size,
190 XGL_FORMAT format,
191 struct intel_cmd_meta *meta)
192{
193 struct intel_mem_view view;
194
195 cmd_meta_init_mem_view(cmd, XGL_NULL_HANDLE, size, format,
196 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
197
198 meta->src.valid = true;
199
200 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
201 meta->src.surface_len = view.cmd_len;
202
203 meta->src.reloc_target = (intptr_t) writer;
204 meta->src.reloc_offset = 0;
205 meta->src.reloc_flags = INTEL_CMD_RELOC_TARGET_IS_WRITER;
206}
207
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800208static void cmd_meta_set_ds_view(struct intel_cmd *cmd,
209 const struct intel_img *img,
210 XGL_UINT lod, XGL_UINT layer,
211 struct intel_cmd_meta *meta)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800212{
213 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO info;
214 struct intel_ds_view *ds;
215 XGL_RESULT ret;
216
217 memset(&info, 0, sizeof(info));
218 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
219 info.image = (XGL_IMAGE) img;
220 info.mipLevel = lod;
221 info.baseArraySlice = layer;
222 info.arraySize = 1;
223
224 ret = intel_ds_view_create(cmd->dev, &info, &ds);
225 if (ret != XGL_SUCCESS) {
226 cmd->result = ret;
227 return;
228 }
229
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800230 meta->ds.view = ds;
231}
232
233static void cmd_meta_set_ds_state(struct intel_cmd *cmd,
234 XGL_IMAGE_ASPECT aspect,
235 XGL_UINT32 stencil_ref,
236 struct intel_cmd_meta *meta)
237{
238 XGL_DEPTH_STENCIL_STATE_CREATE_INFO info;
239 struct intel_ds_state *state;
240 XGL_RESULT ret;
241
242 memset(&info, 0, sizeof(info));
243 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO;
244
245 if (aspect == XGL_IMAGE_ASPECT_DEPTH) {
246 info.depthWriteEnable = XGL_TRUE;
247 }
248 else if (aspect == XGL_IMAGE_ASPECT_STENCIL) {
249 info.stencilTestEnable = XGL_TRUE;
250 info.stencilReadMask = 0xff;
251 info.stencilWriteMask = 0xff;
252 info.front.stencilFailOp = XGL_STENCIL_OP_KEEP;
253 info.front.stencilPassOp = XGL_STENCIL_OP_REPLACE;
254 info.front.stencilDepthFailOp = XGL_STENCIL_OP_KEEP;
255 info.front.stencilFunc = XGL_COMPARE_ALWAYS;
256 info.front.stencilRef = stencil_ref;
257 info.back = info.front;
258 }
259
260 ret = intel_ds_state_create(cmd->dev, &info, &state);
261 if (ret != XGL_SUCCESS) {
262 cmd->result = ret;
263 return;
264 }
265
266 meta->ds.state = state;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800267}
268
269static enum intel_dev_meta_shader get_shader_id(const struct intel_dev *dev,
270 const struct intel_img *img,
271 bool copy_array)
272{
273 enum intel_dev_meta_shader shader_id;
274
275 switch (img->type) {
276 case XGL_IMAGE_1D:
277 shader_id = (copy_array) ?
278 INTEL_DEV_META_FS_COPY_1D_ARRAY : INTEL_DEV_META_FS_COPY_1D;
279 break;
280 case XGL_IMAGE_2D:
281 shader_id = (img->samples > 1) ? INTEL_DEV_META_FS_COPY_2D_MS :
282 (copy_array) ? INTEL_DEV_META_FS_COPY_2D_ARRAY :
283 INTEL_DEV_META_FS_COPY_2D;
284 break;
285 case XGL_IMAGE_3D:
286 default:
287 shader_id = INTEL_DEV_META_FS_COPY_2D_ARRAY;
288 break;
289 }
290
291 return shader_id;
292}
293
Chia-I Wuf3a27252014-11-24 15:27:01 +0800294static bool cmd_meta_mem_dword_aligned(const struct intel_cmd *cmd,
295 XGL_GPU_SIZE src_offset,
296 XGL_GPU_SIZE dst_offset,
297 XGL_GPU_SIZE size)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800298{
Chia-I Wuf3a27252014-11-24 15:27:01 +0800299 return !((src_offset | dst_offset | size) & 0x3);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800300}
301
302static XGL_FORMAT cmd_meta_img_raw_format(const struct intel_cmd *cmd,
303 XGL_FORMAT format)
304{
305 format.numericFormat = XGL_NUM_FMT_UINT;
306
307 if (icd_format_is_compressed(format)) {
308 switch (icd_format_get_size(format)) {
309 case 1:
310 format.channelFormat = XGL_CH_FMT_R8;
311 break;
312 case 2:
313 format.channelFormat = XGL_CH_FMT_R16;
314 break;
315 case 4:
316 format.channelFormat = XGL_CH_FMT_R32;
317 break;
318 case 8:
319 format.channelFormat = XGL_CH_FMT_R32G32;
320 break;
321 case 16:
322 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
323 break;
324 default:
325 assert(!"unsupported compressed block size");
326 format.channelFormat = XGL_CH_FMT_R8;
327 break;
328 }
329 }
330
331 return format;
332}
333
334XGL_VOID XGLAPI intelCmdCopyMemory(
335 XGL_CMD_BUFFER cmdBuffer,
336 XGL_GPU_MEMORY srcMem,
337 XGL_GPU_MEMORY destMem,
338 XGL_UINT regionCount,
339 const XGL_MEMORY_COPY* pRegions)
340{
341 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
342 struct intel_mem *src = intel_mem(srcMem);
343 struct intel_mem *dst = intel_mem(destMem);
344 struct intel_cmd_meta meta;
345 XGL_FORMAT format;
346 XGL_UINT i;
347
348 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800349 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800350
Chia-I Wuc14d1562014-10-17 09:49:22 +0800351 meta.height = 1;
352 meta.samples = 1;
353
354 format.channelFormat = XGL_CH_FMT_UNDEFINED;
355 format.numericFormat = XGL_NUM_FMT_UINT;
356
357 for (i = 0; i < regionCount; i++) {
358 const XGL_MEMORY_COPY *region = &pRegions[i];
359 XGL_CHANNEL_FORMAT ch;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800360
Chia-I Wuf3a27252014-11-24 15:27:01 +0800361 meta.src.x = region->srcOffset;
362 meta.dst.x = region->destOffset;
363 meta.width = region->copySize;
364
365 if (cmd_meta_mem_dword_aligned(cmd, region->srcOffset,
366 region->destOffset, region->copySize)) {
367 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
368 meta.src.x /= 4;
369 meta.dst.x /= 4;
370 meta.width /= 4;
371
372 /*
373 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to
374 * be 16
375 */
376 ch = XGL_CH_FMT_R32G32B32A32;
377 } else {
378 if (cmd_gen(cmd) == INTEL_GEN(6)) {
379 intel_dev_log(cmd->dev, XGL_DBG_MSG_ERROR,
380 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
381 "unaligned xglCmdCopyMemory unsupported");
382 cmd->result = XGL_ERROR_UNKNOWN;
383 continue;
384 }
385
386 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM_UNALIGNED;
387
388 /*
389 * INTEL_DEV_META_VS_COPY_MEM_UNALIGNED is untyped but expects the
390 * stride to be 4
391 */
392 ch = XGL_CH_FMT_R8G8B8A8;
393 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800394
395 if (format.channelFormat != ch) {
396 format.channelFormat = ch;
397
398 cmd_meta_set_src_for_mem(cmd, src, format, &meta);
399 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
400 }
401
Chia-I Wuc14d1562014-10-17 09:49:22 +0800402 cmd_draw_meta(cmd, &meta);
403 }
404}
405
406XGL_VOID XGLAPI intelCmdCopyImage(
407 XGL_CMD_BUFFER cmdBuffer,
408 XGL_IMAGE srcImage,
409 XGL_IMAGE destImage,
410 XGL_UINT regionCount,
411 const XGL_IMAGE_COPY* pRegions)
412{
413 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
414 struct intel_img *src = intel_img(srcImage);
415 struct intel_img *dst = intel_img(destImage);
416 struct intel_cmd_meta meta;
417 XGL_FORMAT raw_format;
418 bool raw_copy;
419 XGL_UINT i;
420
421 if (src->type != dst->type) {
422 cmd->result = XGL_ERROR_UNKNOWN;
423 return;
424 }
425
426 if (icd_format_is_equal(src->layout.format, dst->layout.format)) {
427 raw_copy = true;
428 raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
429 } else if (icd_format_is_compressed(src->layout.format) ||
430 icd_format_is_compressed(dst->layout.format)) {
431 cmd->result = XGL_ERROR_UNKNOWN;
432 return;
433 }
434
435 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800436 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800437
438 cmd_meta_set_src_for_img(cmd, src,
439 (raw_copy) ? raw_format : src->layout.format,
440 XGL_IMAGE_ASPECT_COLOR, &meta);
441
442 meta.samples = dst->samples;
443
444 for (i = 0; i < regionCount; i++) {
445 const XGL_IMAGE_COPY *region = &pRegions[i];
446 XGL_UINT j;
447
448 meta.shader_id = get_shader_id(cmd->dev, src,
449 (region->extent.depth > 1));
450
451 meta.src.lod = region->srcSubresource.mipLevel;
452 meta.src.layer = region->srcSubresource.arraySlice +
453 region->srcOffset.z;
454 meta.src.x = region->srcOffset.x;
455 meta.src.y = region->srcOffset.y;
456
457 meta.dst.lod = region->destSubresource.mipLevel;
458 meta.dst.layer = region->destSubresource.arraySlice +
459 region->destOffset.z;
460 meta.dst.x = region->destOffset.x;
461 meta.dst.y = region->destOffset.y;
462
463 meta.width = region->extent.width;
464 meta.height = region->extent.height;
465
466 for (j = 0; j < region->extent.depth; j++) {
467 cmd_meta_set_dst_for_img(cmd, dst,
468 (raw_copy) ? raw_format : dst->layout.format,
469 meta.dst.lod, meta.dst.layer, &meta);
470
471 cmd_draw_meta(cmd, &meta);
472
473 meta.src.layer++;
474 meta.dst.layer++;
475 }
476 }
477}
478
479XGL_VOID XGLAPI intelCmdCopyMemoryToImage(
480 XGL_CMD_BUFFER cmdBuffer,
481 XGL_GPU_MEMORY srcMem,
482 XGL_IMAGE destImage,
483 XGL_UINT regionCount,
484 const XGL_MEMORY_IMAGE_COPY* pRegions)
485{
486 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
487 struct intel_mem *mem = intel_mem(srcMem);
488 struct intel_img *img = intel_img(destImage);
489 struct intel_cmd_meta meta;
490 XGL_FORMAT format;
491 XGL_UINT i;
492
493 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800494 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800495
496 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM_TO_IMG;
497 meta.samples = img->samples;
498
499 format = cmd_meta_img_raw_format(cmd, img->layout.format);
500 cmd_meta_set_src_for_mem(cmd, mem, format, &meta);
501
502 for (i = 0; i < regionCount; i++) {
503 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
504 XGL_UINT j;
505
506 meta.src.x = region->memOffset / icd_format_get_size(format);
507
508 meta.dst.lod = region->imageSubresource.mipLevel;
509 meta.dst.layer = region->imageSubresource.arraySlice +
510 region->imageOffset.z;
511 meta.dst.x = region->imageOffset.x;
512 meta.dst.y = region->imageOffset.y;
513
514 meta.width = region->imageExtent.width;
515 meta.height = region->imageExtent.height;
516
517 for (j = 0; j < region->imageExtent.depth; j++) {
518 cmd_meta_set_dst_for_img(cmd, img, format,
519 meta.dst.lod, meta.dst.layer, &meta);
520
521 cmd_draw_meta(cmd, &meta);
522
523 meta.src.x += meta.width * meta.height;
524 meta.dst.layer++;
525 }
526 }
527}
528
529XGL_VOID XGLAPI intelCmdCopyImageToMemory(
530 XGL_CMD_BUFFER cmdBuffer,
531 XGL_IMAGE srcImage,
532 XGL_GPU_MEMORY destMem,
533 XGL_UINT regionCount,
534 const XGL_MEMORY_IMAGE_COPY* pRegions)
535{
536 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
537 struct intel_img *img = intel_img(srcImage);
538 struct intel_mem *mem = intel_mem(destMem);
539 struct intel_cmd_meta meta;
540 XGL_FORMAT format;
541 XGL_UINT i;
542
543 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800544 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800545
546 format = cmd_meta_img_raw_format(cmd, img->layout.format);
547 cmd_meta_set_src_for_img(cmd, img, format, XGL_IMAGE_ASPECT_COLOR, &meta);
548 cmd_meta_set_dst_for_mem(cmd, mem, format, &meta);
549
550 meta.height = 1;
551 meta.samples = 1;
552
553 for (i = 0; i < regionCount; i++) {
554 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
555 XGL_UINT j;
556
557 meta.shader_id = get_shader_id(cmd->dev, img,
558 (region->imageExtent.depth > 1));
559
560 meta.src.lod = region->imageSubresource.mipLevel;
561 meta.src.layer = region->imageSubresource.arraySlice +
562 region->imageOffset.z;
563 meta.src.x = region->imageOffset.x;
564 meta.src.y = region->imageOffset.y;
565
566 meta.dst.x = region->memOffset / icd_format_get_size(format);
567
568 meta.width = region->imageExtent.width * region->imageExtent.height;
569
570 for (j = 0; j < region->imageExtent.depth; j++) {
571 cmd_draw_meta(cmd, &meta);
572
573 meta.src.layer++;
574 meta.dst.x += meta.width;
575 }
576 }
577}
578
579XGL_VOID XGLAPI intelCmdCloneImageData(
580 XGL_CMD_BUFFER cmdBuffer,
581 XGL_IMAGE srcImage,
582 XGL_IMAGE_STATE srcImageState,
583 XGL_IMAGE destImage,
584 XGL_IMAGE_STATE destImageState)
585{
586 const struct intel_img *src = intel_img(srcImage);
587 XGL_IMAGE_COPY region;
588 XGL_UINT lv;
589
590 memset(&region, 0, sizeof(region));
591 region.srcSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
592 region.destSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
593
594 for (lv = 0; lv < src->mip_levels; lv++) {
595 region.srcSubresource.mipLevel = lv;
596 region.destSubresource.mipLevel = lv;
597
598 region.extent.width = u_minify(src->layout.width0, lv);
599 region.extent.height = u_minify(src->layout.height0, lv);
600 region.extent.depth = src->array_size;
601
602 intelCmdCopyImage(cmdBuffer, srcImage, destImage, 1, &region);
603 }
604}
605
606XGL_VOID XGLAPI intelCmdUpdateMemory(
607 XGL_CMD_BUFFER cmdBuffer,
608 XGL_GPU_MEMORY destMem,
609 XGL_GPU_SIZE destOffset,
610 XGL_GPU_SIZE dataSize,
611 const XGL_UINT32* pData)
612{
613 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
614 struct intel_mem *dst = intel_mem(destMem);
615 struct intel_cmd_meta meta;
616 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800617 uint32_t *ptr;
618 uint32_t offset;
619
Chia-I Wuf3a27252014-11-24 15:27:01 +0800620 /* must be 4-byte aligned */
621 if ((destOffset | dataSize) & 3) {
622 cmd->result = XGL_ERROR_UNKNOWN;
623 return;
624 }
625
Chia-I Wuc14d1562014-10-17 09:49:22 +0800626 /* write to dynamic state writer first */
627 offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
628 (dataSize + 3) / 4, &ptr);
629 memcpy(ptr, pData, dataSize);
630
Chia-I Wuc14d1562014-10-17 09:49:22 +0800631 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800632 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800633
Chia-I Wuf3a27252014-11-24 15:27:01 +0800634 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
635
636 meta.src.x = offset / 4;
637 meta.dst.x = destOffset / 4;
638 meta.width = dataSize / 4;
639 meta.height = 1;
640 meta.samples = 1;
641
642 /*
643 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to be 16
644 */
645 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
646 format.numericFormat = XGL_NUM_FMT_UINT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800647
648 cmd_meta_set_src_for_writer(cmd, INTEL_CMD_WRITER_STATE,
649 offset + dataSize, format, &meta);
650 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
651
Chia-I Wuc14d1562014-10-17 09:49:22 +0800652 cmd_draw_meta(cmd, &meta);
653}
654
655XGL_VOID XGLAPI intelCmdFillMemory(
656 XGL_CMD_BUFFER cmdBuffer,
657 XGL_GPU_MEMORY destMem,
658 XGL_GPU_SIZE destOffset,
659 XGL_GPU_SIZE fillSize,
660 XGL_UINT32 data)
661{
662 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
663 struct intel_mem *dst = intel_mem(destMem);
664 struct intel_cmd_meta meta;
665 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800666
667 /* must be 4-byte aligned */
668 if ((destOffset | fillSize) & 3) {
669 cmd->result = XGL_ERROR_UNKNOWN;
670 return;
671 }
672
673 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800674 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800675
Chia-I Wuf3a27252014-11-24 15:27:01 +0800676 meta.shader_id = INTEL_DEV_META_VS_FILL_MEM;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800677
678 meta.clear_val[0] = data;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800679
Chia-I Wuf3a27252014-11-24 15:27:01 +0800680 meta.dst.x = destOffset / 4;
681 meta.width = fillSize / 4;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800682 meta.height = 1;
683 meta.samples = 1;
684
Chia-I Wuf3a27252014-11-24 15:27:01 +0800685 /*
686 * INTEL_DEV_META_VS_FILL_MEM is untyped but expects the stride to be 16
687 */
688 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
689 format.numericFormat = XGL_NUM_FMT_UINT;
690
691 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
692
Chia-I Wuc14d1562014-10-17 09:49:22 +0800693 cmd_draw_meta(cmd, &meta);
694}
695
696static void cmd_meta_clear_image(struct intel_cmd *cmd,
697 struct intel_img *img,
698 XGL_FORMAT format,
699 struct intel_cmd_meta *meta,
700 const XGL_IMAGE_SUBRESOURCE_RANGE *range)
701{
702 XGL_UINT mip_levels, array_size;
703 XGL_UINT i, j;
704
705 if (range->baseMipLevel >= img->mip_levels ||
706 range->baseArraySlice >= img->array_size)
707 return;
708
709 mip_levels = img->mip_levels - range->baseMipLevel;
710 if (mip_levels > range->mipLevels)
711 mip_levels = range->mipLevels;
712
713 array_size = img->array_size - range->baseArraySlice;
714 if (array_size > range->arraySize)
715 array_size = range->arraySize;
716
Chia-I Wuc14d1562014-10-17 09:49:22 +0800717 for (i = 0; i < mip_levels; i++) {
Chia-I Wufaaed472014-10-28 14:17:43 +0800718 meta->dst.lod = range->baseMipLevel + i;
719 meta->dst.layer = range->baseArraySlice;
720
Chia-I Wuc14d1562014-10-17 09:49:22 +0800721 meta->width = u_minify(img->layout.width0, meta->dst.lod);
722 meta->height = u_minify(img->layout.height0, meta->dst.lod);
723
724 for (j = 0; j < array_size; j++) {
725 if (range->aspect == XGL_IMAGE_ASPECT_COLOR) {
726 cmd_meta_set_dst_for_img(cmd, img, format,
727 meta->dst.lod, meta->dst.layer, meta);
728
729 cmd_draw_meta(cmd, meta);
730 } else {
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800731 cmd_meta_set_ds_view(cmd, img, meta->dst.lod,
Chia-I Wuc14d1562014-10-17 09:49:22 +0800732 meta->dst.layer, meta);
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800733 cmd_meta_set_ds_state(cmd, range->aspect,
734 meta->clear_val[1], meta);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800735
736 cmd_draw_meta(cmd, meta);
737
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800738 intel_ds_view_destroy(meta->ds.view);
739 intel_ds_state_destroy(meta->ds.state);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800740 }
741
742 meta->dst.layer++;
743 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800744 }
745}
746
747XGL_VOID XGLAPI intelCmdClearColorImage(
748 XGL_CMD_BUFFER cmdBuffer,
749 XGL_IMAGE image,
750 const XGL_FLOAT color[4],
751 XGL_UINT rangeCount,
752 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
753{
754 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
755 struct intel_img *img = intel_img(image);
756 struct intel_cmd_meta meta;
757 XGL_UINT i;
758
759 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800760 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800761
762 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
763 meta.samples = img->samples;
764
765 meta.clear_val[0] = u_fui(color[0]);
766 meta.clear_val[1] = u_fui(color[1]);
767 meta.clear_val[2] = u_fui(color[2]);
768 meta.clear_val[3] = u_fui(color[3]);
769
770 for (i = 0; i < rangeCount; i++) {
771 cmd_meta_clear_image(cmd, img, img->layout.format,
772 &meta, &pRanges[i]);
773 }
774}
775
776XGL_VOID XGLAPI intelCmdClearColorImageRaw(
777 XGL_CMD_BUFFER cmdBuffer,
778 XGL_IMAGE image,
779 const XGL_UINT32 color[4],
780 XGL_UINT rangeCount,
781 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
782{
783 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
784 struct intel_img *img = intel_img(image);
785 struct intel_cmd_meta meta;
786 XGL_FORMAT format;
787 XGL_UINT i;
788
789 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800790 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800791
792 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
793 meta.samples = img->samples;
794
795 meta.clear_val[0] = color[0];
796 meta.clear_val[1] = color[1];
797 meta.clear_val[2] = color[2];
798 meta.clear_val[3] = color[3];
799
800 format = cmd_meta_img_raw_format(cmd, img->layout.format);
801
802 for (i = 0; i < rangeCount; i++)
803 cmd_meta_clear_image(cmd, img, format, &meta, &pRanges[i]);
804}
805
806XGL_VOID XGLAPI intelCmdClearDepthStencil(
807 XGL_CMD_BUFFER cmdBuffer,
808 XGL_IMAGE image,
809 XGL_FLOAT depth,
810 XGL_UINT32 stencil,
811 XGL_UINT rangeCount,
812 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
813{
814 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
815 struct intel_img *img = intel_img(image);
816 struct intel_cmd_meta meta;
817 XGL_UINT i;
818
819 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800820 meta.mode = INTEL_CMD_META_DEPTH_STENCIL_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800821
822 meta.shader_id = INTEL_DEV_META_FS_CLEAR_DEPTH;
823 meta.samples = img->samples;
824
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800825 meta.clear_val[0] = u_fui(depth);
826 meta.clear_val[1] = stencil;
827
Chia-I Wuc14d1562014-10-17 09:49:22 +0800828 for (i = 0; i < rangeCount; i++) {
829 const XGL_IMAGE_SUBRESOURCE_RANGE *range = &pRanges[i];
830
Chia-I Wuc14d1562014-10-17 09:49:22 +0800831 cmd_meta_clear_image(cmd, img, img->layout.format,
832 &meta, range);
833 }
834}
835
836XGL_VOID XGLAPI intelCmdResolveImage(
837 XGL_CMD_BUFFER cmdBuffer,
838 XGL_IMAGE srcImage,
839 XGL_IMAGE destImage,
840 XGL_UINT rectCount,
841 const XGL_IMAGE_RESOLVE* pRects)
842{
843 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
844 struct intel_img *src = intel_img(srcImage);
845 struct intel_img *dst = intel_img(destImage);
846 struct intel_cmd_meta meta;
847 XGL_FORMAT format;
848 XGL_UINT i;
849
850 if (src->samples <= 1 || dst->samples > 1 ||
851 !icd_format_is_equal(src->layout.format, dst->layout.format)) {
852 cmd->result = XGL_ERROR_UNKNOWN;
853 return;
854 }
855
856 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800857 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800858
859 switch (src->samples) {
860 case 2:
861 default:
862 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_2X;
863 break;
864 case 4:
865 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_4X;
866 break;
867 case 8:
868 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_8X;
869 break;
870 case 16:
871 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_16X;
872 break;
873 }
874
875 meta.samples = 1;
876
877 format = cmd_meta_img_raw_format(cmd, src->layout.format);
878 cmd_meta_set_src_for_img(cmd, src, format, XGL_IMAGE_ASPECT_COLOR, &meta);
879
880 for (i = 0; i < rectCount; i++) {
881 const XGL_IMAGE_RESOLVE *rect = &pRects[i];
882
883 meta.src.lod = rect->srcSubresource.mipLevel;
884 meta.src.layer = rect->srcSubresource.arraySlice;
885 meta.src.x = rect->srcOffset.x;
886 meta.src.y = rect->srcOffset.y;
887
888 meta.dst.lod = rect->destSubresource.mipLevel;
889 meta.dst.layer = rect->destSubresource.arraySlice;
890 meta.dst.x = rect->destOffset.x;
891 meta.dst.y = rect->destOffset.y;
892
893 meta.width = rect->extent.width;
894 meta.height = rect->extent.height;
895
896 cmd_meta_set_dst_for_img(cmd, dst, format,
897 meta.dst.lod, meta.dst.layer, &meta);
898
899 cmd_draw_meta(cmd, &meta);
900 }
901}