blob: d21756e084967e6f0e36a8cf90bb1cc4fe4d6708 [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
Chia-I Wu83084ba2014-12-04 12:49:52 +0800151static void cmd_meta_adjust_compressed_dst(struct intel_cmd *cmd,
152 const struct intel_img *img,
153 struct intel_cmd_meta *meta)
154{
155 XGL_INT w, h;
156
157 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
158 w = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_WIDTH);
159 h = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_HEIGHT);
160 meta->dst.surface[2] &= ~(GEN7_SURFACE_DW2_WIDTH__MASK |
161 GEN7_SURFACE_DW2_HEIGHT__MASK);
162 } else {
163 w = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_WIDTH);
164 h = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_HEIGHT);
165 meta->dst.surface[2] &= ~(GEN6_SURFACE_DW2_WIDTH__MASK |
166 GEN6_SURFACE_DW2_HEIGHT__MASK);
167 }
168
169 /* note that the width/height fields have the real values minus 1 */
170 w = (w + img->layout.block_width) / img->layout.block_width - 1;
171 h = (h + img->layout.block_height) / img->layout.block_height - 1;
172
173 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
174 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN7_SURFACE_DW2_WIDTH) |
175 GEN_SHIFT32(h, GEN7_SURFACE_DW2_HEIGHT);
176 } else {
177 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN6_SURFACE_DW2_WIDTH) |
178 GEN_SHIFT32(h, GEN6_SURFACE_DW2_HEIGHT);
179 }
180}
181
Chia-I Wuc14d1562014-10-17 09:49:22 +0800182static void cmd_meta_set_dst_for_img(struct intel_cmd *cmd,
183 const struct intel_img *img,
184 XGL_FORMAT format,
185 XGL_UINT lod, XGL_UINT layer,
186 struct intel_cmd_meta *meta)
187{
188 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO info;
189 struct intel_rt_view *rt;
190 XGL_RESULT ret;
191
192 memset(&info, 0, sizeof(info));
193 info.sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO;
194 info.image = (XGL_IMAGE) img;
195 info.format = format;
196 info.mipLevel = lod;
197 info.baseArraySlice = layer;
198 info.arraySize = 1;
199
200 ret = intel_rt_view_create(cmd->dev, &info, &rt);
201 if (ret != XGL_SUCCESS) {
202 cmd->result = ret;
203 return;
204 }
205
206 meta->dst.valid = true;
207
208 memcpy(meta->dst.surface, rt->cmd, sizeof(rt->cmd[0]) * rt->cmd_len);
209 meta->dst.surface_len = rt->cmd_len;
210
211 meta->dst.reloc_target = (intptr_t) img->obj.mem->bo;
212 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +0800213 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800214
Chia-I Wu83084ba2014-12-04 12:49:52 +0800215 if (icd_format_is_compressed(img->layout.format))
216 cmd_meta_adjust_compressed_dst(cmd, img, meta);
217
Chia-I Wuc14d1562014-10-17 09:49:22 +0800218 intel_rt_view_destroy(rt);
219}
220
221static void cmd_meta_set_src_for_writer(struct intel_cmd *cmd,
222 enum intel_cmd_writer_type writer,
223 XGL_GPU_SIZE size,
224 XGL_FORMAT format,
225 struct intel_cmd_meta *meta)
226{
227 struct intel_mem_view view;
228
229 cmd_meta_init_mem_view(cmd, XGL_NULL_HANDLE, size, format,
230 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
231
232 meta->src.valid = true;
233
234 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
235 meta->src.surface_len = view.cmd_len;
236
237 meta->src.reloc_target = (intptr_t) writer;
238 meta->src.reloc_offset = 0;
239 meta->src.reloc_flags = INTEL_CMD_RELOC_TARGET_IS_WRITER;
240}
241
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800242static void cmd_meta_set_ds_view(struct intel_cmd *cmd,
243 const struct intel_img *img,
244 XGL_UINT lod, XGL_UINT layer,
245 struct intel_cmd_meta *meta)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800246{
247 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO info;
248 struct intel_ds_view *ds;
249 XGL_RESULT ret;
250
251 memset(&info, 0, sizeof(info));
252 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
253 info.image = (XGL_IMAGE) img;
254 info.mipLevel = lod;
255 info.baseArraySlice = layer;
256 info.arraySize = 1;
257
258 ret = intel_ds_view_create(cmd->dev, &info, &ds);
259 if (ret != XGL_SUCCESS) {
260 cmd->result = ret;
261 return;
262 }
263
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800264 meta->ds.view = ds;
265}
266
267static void cmd_meta_set_ds_state(struct intel_cmd *cmd,
268 XGL_IMAGE_ASPECT aspect,
269 XGL_UINT32 stencil_ref,
270 struct intel_cmd_meta *meta)
271{
272 XGL_DEPTH_STENCIL_STATE_CREATE_INFO info;
273 struct intel_ds_state *state;
274 XGL_RESULT ret;
275
276 memset(&info, 0, sizeof(info));
277 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO;
278
279 if (aspect == XGL_IMAGE_ASPECT_DEPTH) {
280 info.depthWriteEnable = XGL_TRUE;
281 }
282 else if (aspect == XGL_IMAGE_ASPECT_STENCIL) {
283 info.stencilTestEnable = XGL_TRUE;
284 info.stencilReadMask = 0xff;
285 info.stencilWriteMask = 0xff;
286 info.front.stencilFailOp = XGL_STENCIL_OP_KEEP;
287 info.front.stencilPassOp = XGL_STENCIL_OP_REPLACE;
288 info.front.stencilDepthFailOp = XGL_STENCIL_OP_KEEP;
289 info.front.stencilFunc = XGL_COMPARE_ALWAYS;
290 info.front.stencilRef = stencil_ref;
291 info.back = info.front;
292 }
293
294 ret = intel_ds_state_create(cmd->dev, &info, &state);
295 if (ret != XGL_SUCCESS) {
296 cmd->result = ret;
297 return;
298 }
299
300 meta->ds.state = state;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800301}
302
303static enum intel_dev_meta_shader get_shader_id(const struct intel_dev *dev,
304 const struct intel_img *img,
305 bool copy_array)
306{
307 enum intel_dev_meta_shader shader_id;
308
309 switch (img->type) {
310 case XGL_IMAGE_1D:
311 shader_id = (copy_array) ?
312 INTEL_DEV_META_FS_COPY_1D_ARRAY : INTEL_DEV_META_FS_COPY_1D;
313 break;
314 case XGL_IMAGE_2D:
315 shader_id = (img->samples > 1) ? INTEL_DEV_META_FS_COPY_2D_MS :
316 (copy_array) ? INTEL_DEV_META_FS_COPY_2D_ARRAY :
317 INTEL_DEV_META_FS_COPY_2D;
318 break;
319 case XGL_IMAGE_3D:
320 default:
321 shader_id = INTEL_DEV_META_FS_COPY_2D_ARRAY;
322 break;
323 }
324
325 return shader_id;
326}
327
Chia-I Wuf3a27252014-11-24 15:27:01 +0800328static bool cmd_meta_mem_dword_aligned(const struct intel_cmd *cmd,
329 XGL_GPU_SIZE src_offset,
330 XGL_GPU_SIZE dst_offset,
331 XGL_GPU_SIZE size)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800332{
Chia-I Wuf3a27252014-11-24 15:27:01 +0800333 return !((src_offset | dst_offset | size) & 0x3);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800334}
335
336static XGL_FORMAT cmd_meta_img_raw_format(const struct intel_cmd *cmd,
337 XGL_FORMAT format)
338{
339 format.numericFormat = XGL_NUM_FMT_UINT;
340
341 if (icd_format_is_compressed(format)) {
342 switch (icd_format_get_size(format)) {
343 case 1:
344 format.channelFormat = XGL_CH_FMT_R8;
345 break;
346 case 2:
347 format.channelFormat = XGL_CH_FMT_R16;
348 break;
349 case 4:
350 format.channelFormat = XGL_CH_FMT_R32;
351 break;
352 case 8:
353 format.channelFormat = XGL_CH_FMT_R32G32;
354 break;
355 case 16:
356 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
357 break;
358 default:
359 assert(!"unsupported compressed block size");
360 format.channelFormat = XGL_CH_FMT_R8;
361 break;
362 }
363 }
364
365 return format;
366}
367
368XGL_VOID XGLAPI intelCmdCopyMemory(
369 XGL_CMD_BUFFER cmdBuffer,
370 XGL_GPU_MEMORY srcMem,
371 XGL_GPU_MEMORY destMem,
372 XGL_UINT regionCount,
373 const XGL_MEMORY_COPY* pRegions)
374{
375 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
376 struct intel_mem *src = intel_mem(srcMem);
377 struct intel_mem *dst = intel_mem(destMem);
378 struct intel_cmd_meta meta;
379 XGL_FORMAT format;
380 XGL_UINT i;
381
382 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800383 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800384
Chia-I Wuc14d1562014-10-17 09:49:22 +0800385 meta.height = 1;
386 meta.samples = 1;
387
388 format.channelFormat = XGL_CH_FMT_UNDEFINED;
389 format.numericFormat = XGL_NUM_FMT_UINT;
390
391 for (i = 0; i < regionCount; i++) {
392 const XGL_MEMORY_COPY *region = &pRegions[i];
393 XGL_CHANNEL_FORMAT ch;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800394
Chia-I Wuf3a27252014-11-24 15:27:01 +0800395 meta.src.x = region->srcOffset;
396 meta.dst.x = region->destOffset;
397 meta.width = region->copySize;
398
399 if (cmd_meta_mem_dword_aligned(cmd, region->srcOffset,
400 region->destOffset, region->copySize)) {
401 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
402 meta.src.x /= 4;
403 meta.dst.x /= 4;
404 meta.width /= 4;
405
406 /*
407 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to
408 * be 16
409 */
410 ch = XGL_CH_FMT_R32G32B32A32;
411 } else {
412 if (cmd_gen(cmd) == INTEL_GEN(6)) {
413 intel_dev_log(cmd->dev, XGL_DBG_MSG_ERROR,
414 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
415 "unaligned xglCmdCopyMemory unsupported");
416 cmd->result = XGL_ERROR_UNKNOWN;
417 continue;
418 }
419
420 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM_UNALIGNED;
421
422 /*
423 * INTEL_DEV_META_VS_COPY_MEM_UNALIGNED is untyped but expects the
424 * stride to be 4
425 */
426 ch = XGL_CH_FMT_R8G8B8A8;
427 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800428
429 if (format.channelFormat != ch) {
430 format.channelFormat = ch;
431
432 cmd_meta_set_src_for_mem(cmd, src, format, &meta);
433 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
434 }
435
Chia-I Wuc14d1562014-10-17 09:49:22 +0800436 cmd_draw_meta(cmd, &meta);
437 }
438}
439
440XGL_VOID XGLAPI intelCmdCopyImage(
441 XGL_CMD_BUFFER cmdBuffer,
442 XGL_IMAGE srcImage,
443 XGL_IMAGE destImage,
444 XGL_UINT regionCount,
445 const XGL_IMAGE_COPY* pRegions)
446{
447 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
448 struct intel_img *src = intel_img(srcImage);
449 struct intel_img *dst = intel_img(destImage);
450 struct intel_cmd_meta meta;
451 XGL_FORMAT raw_format;
452 bool raw_copy;
453 XGL_UINT i;
454
455 if (src->type != dst->type) {
456 cmd->result = XGL_ERROR_UNKNOWN;
457 return;
458 }
459
460 if (icd_format_is_equal(src->layout.format, dst->layout.format)) {
461 raw_copy = true;
462 raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
463 } else if (icd_format_is_compressed(src->layout.format) ||
464 icd_format_is_compressed(dst->layout.format)) {
465 cmd->result = XGL_ERROR_UNKNOWN;
466 return;
467 }
468
469 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800470 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800471
472 cmd_meta_set_src_for_img(cmd, src,
473 (raw_copy) ? raw_format : src->layout.format,
474 XGL_IMAGE_ASPECT_COLOR, &meta);
475
476 meta.samples = dst->samples;
477
478 for (i = 0; i < regionCount; i++) {
479 const XGL_IMAGE_COPY *region = &pRegions[i];
480 XGL_UINT j;
481
482 meta.shader_id = get_shader_id(cmd->dev, src,
483 (region->extent.depth > 1));
484
485 meta.src.lod = region->srcSubresource.mipLevel;
486 meta.src.layer = region->srcSubresource.arraySlice +
487 region->srcOffset.z;
488 meta.src.x = region->srcOffset.x;
489 meta.src.y = region->srcOffset.y;
490
491 meta.dst.lod = region->destSubresource.mipLevel;
492 meta.dst.layer = region->destSubresource.arraySlice +
493 region->destOffset.z;
494 meta.dst.x = region->destOffset.x;
495 meta.dst.y = region->destOffset.y;
496
497 meta.width = region->extent.width;
498 meta.height = region->extent.height;
499
500 for (j = 0; j < region->extent.depth; j++) {
501 cmd_meta_set_dst_for_img(cmd, dst,
502 (raw_copy) ? raw_format : dst->layout.format,
503 meta.dst.lod, meta.dst.layer, &meta);
504
505 cmd_draw_meta(cmd, &meta);
506
507 meta.src.layer++;
508 meta.dst.layer++;
509 }
510 }
511}
512
513XGL_VOID XGLAPI intelCmdCopyMemoryToImage(
514 XGL_CMD_BUFFER cmdBuffer,
515 XGL_GPU_MEMORY srcMem,
516 XGL_IMAGE destImage,
517 XGL_UINT regionCount,
518 const XGL_MEMORY_IMAGE_COPY* pRegions)
519{
520 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
521 struct intel_mem *mem = intel_mem(srcMem);
522 struct intel_img *img = intel_img(destImage);
523 struct intel_cmd_meta meta;
524 XGL_FORMAT format;
525 XGL_UINT i;
526
527 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800528 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800529
530 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM_TO_IMG;
531 meta.samples = img->samples;
532
533 format = cmd_meta_img_raw_format(cmd, img->layout.format);
534 cmd_meta_set_src_for_mem(cmd, mem, format, &meta);
535
536 for (i = 0; i < regionCount; i++) {
537 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
538 XGL_UINT j;
539
540 meta.src.x = region->memOffset / icd_format_get_size(format);
541
542 meta.dst.lod = region->imageSubresource.mipLevel;
543 meta.dst.layer = region->imageSubresource.arraySlice +
544 region->imageOffset.z;
545 meta.dst.x = region->imageOffset.x;
546 meta.dst.y = region->imageOffset.y;
547
548 meta.width = region->imageExtent.width;
549 meta.height = region->imageExtent.height;
550
551 for (j = 0; j < region->imageExtent.depth; j++) {
552 cmd_meta_set_dst_for_img(cmd, img, format,
553 meta.dst.lod, meta.dst.layer, &meta);
554
555 cmd_draw_meta(cmd, &meta);
556
557 meta.src.x += meta.width * meta.height;
558 meta.dst.layer++;
559 }
560 }
561}
562
563XGL_VOID XGLAPI intelCmdCopyImageToMemory(
564 XGL_CMD_BUFFER cmdBuffer,
565 XGL_IMAGE srcImage,
566 XGL_GPU_MEMORY destMem,
567 XGL_UINT regionCount,
568 const XGL_MEMORY_IMAGE_COPY* pRegions)
569{
570 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
571 struct intel_img *img = intel_img(srcImage);
572 struct intel_mem *mem = intel_mem(destMem);
573 struct intel_cmd_meta meta;
574 XGL_FORMAT format;
575 XGL_UINT i;
576
577 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800578 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800579
580 format = cmd_meta_img_raw_format(cmd, img->layout.format);
581 cmd_meta_set_src_for_img(cmd, img, format, XGL_IMAGE_ASPECT_COLOR, &meta);
582 cmd_meta_set_dst_for_mem(cmd, mem, format, &meta);
583
584 meta.height = 1;
585 meta.samples = 1;
586
587 for (i = 0; i < regionCount; i++) {
588 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
589 XGL_UINT j;
590
591 meta.shader_id = get_shader_id(cmd->dev, img,
592 (region->imageExtent.depth > 1));
593
594 meta.src.lod = region->imageSubresource.mipLevel;
595 meta.src.layer = region->imageSubresource.arraySlice +
596 region->imageOffset.z;
597 meta.src.x = region->imageOffset.x;
598 meta.src.y = region->imageOffset.y;
599
600 meta.dst.x = region->memOffset / icd_format_get_size(format);
601
602 meta.width = region->imageExtent.width * region->imageExtent.height;
603
604 for (j = 0; j < region->imageExtent.depth; j++) {
605 cmd_draw_meta(cmd, &meta);
606
607 meta.src.layer++;
608 meta.dst.x += meta.width;
609 }
610 }
611}
612
613XGL_VOID XGLAPI intelCmdCloneImageData(
614 XGL_CMD_BUFFER cmdBuffer,
615 XGL_IMAGE srcImage,
616 XGL_IMAGE_STATE srcImageState,
617 XGL_IMAGE destImage,
618 XGL_IMAGE_STATE destImageState)
619{
620 const struct intel_img *src = intel_img(srcImage);
621 XGL_IMAGE_COPY region;
622 XGL_UINT lv;
623
624 memset(&region, 0, sizeof(region));
625 region.srcSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
626 region.destSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
627
628 for (lv = 0; lv < src->mip_levels; lv++) {
629 region.srcSubresource.mipLevel = lv;
630 region.destSubresource.mipLevel = lv;
631
632 region.extent.width = u_minify(src->layout.width0, lv);
633 region.extent.height = u_minify(src->layout.height0, lv);
634 region.extent.depth = src->array_size;
635
636 intelCmdCopyImage(cmdBuffer, srcImage, destImage, 1, &region);
637 }
638}
639
640XGL_VOID XGLAPI intelCmdUpdateMemory(
641 XGL_CMD_BUFFER cmdBuffer,
642 XGL_GPU_MEMORY destMem,
643 XGL_GPU_SIZE destOffset,
644 XGL_GPU_SIZE dataSize,
645 const XGL_UINT32* pData)
646{
647 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
648 struct intel_mem *dst = intel_mem(destMem);
649 struct intel_cmd_meta meta;
650 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800651 uint32_t *ptr;
652 uint32_t offset;
653
Chia-I Wuf3a27252014-11-24 15:27:01 +0800654 /* must be 4-byte aligned */
655 if ((destOffset | dataSize) & 3) {
656 cmd->result = XGL_ERROR_UNKNOWN;
657 return;
658 }
659
Chia-I Wuc14d1562014-10-17 09:49:22 +0800660 /* write to dynamic state writer first */
661 offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
662 (dataSize + 3) / 4, &ptr);
663 memcpy(ptr, pData, dataSize);
664
Chia-I Wuc14d1562014-10-17 09:49:22 +0800665 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800666 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800667
Chia-I Wuf3a27252014-11-24 15:27:01 +0800668 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
669
670 meta.src.x = offset / 4;
671 meta.dst.x = destOffset / 4;
672 meta.width = dataSize / 4;
673 meta.height = 1;
674 meta.samples = 1;
675
676 /*
677 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to be 16
678 */
679 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
680 format.numericFormat = XGL_NUM_FMT_UINT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800681
682 cmd_meta_set_src_for_writer(cmd, INTEL_CMD_WRITER_STATE,
683 offset + dataSize, format, &meta);
684 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
685
Chia-I Wuc14d1562014-10-17 09:49:22 +0800686 cmd_draw_meta(cmd, &meta);
687}
688
689XGL_VOID XGLAPI intelCmdFillMemory(
690 XGL_CMD_BUFFER cmdBuffer,
691 XGL_GPU_MEMORY destMem,
692 XGL_GPU_SIZE destOffset,
693 XGL_GPU_SIZE fillSize,
694 XGL_UINT32 data)
695{
696 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
697 struct intel_mem *dst = intel_mem(destMem);
698 struct intel_cmd_meta meta;
699 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800700
701 /* must be 4-byte aligned */
702 if ((destOffset | fillSize) & 3) {
703 cmd->result = XGL_ERROR_UNKNOWN;
704 return;
705 }
706
707 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800708 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800709
Chia-I Wuf3a27252014-11-24 15:27:01 +0800710 meta.shader_id = INTEL_DEV_META_VS_FILL_MEM;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800711
712 meta.clear_val[0] = data;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800713
Chia-I Wuf3a27252014-11-24 15:27:01 +0800714 meta.dst.x = destOffset / 4;
715 meta.width = fillSize / 4;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800716 meta.height = 1;
717 meta.samples = 1;
718
Chia-I Wuf3a27252014-11-24 15:27:01 +0800719 /*
720 * INTEL_DEV_META_VS_FILL_MEM is untyped but expects the stride to be 16
721 */
722 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
723 format.numericFormat = XGL_NUM_FMT_UINT;
724
725 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
726
Chia-I Wuc14d1562014-10-17 09:49:22 +0800727 cmd_draw_meta(cmd, &meta);
728}
729
730static void cmd_meta_clear_image(struct intel_cmd *cmd,
731 struct intel_img *img,
732 XGL_FORMAT format,
733 struct intel_cmd_meta *meta,
734 const XGL_IMAGE_SUBRESOURCE_RANGE *range)
735{
736 XGL_UINT mip_levels, array_size;
737 XGL_UINT i, j;
738
739 if (range->baseMipLevel >= img->mip_levels ||
740 range->baseArraySlice >= img->array_size)
741 return;
742
743 mip_levels = img->mip_levels - range->baseMipLevel;
744 if (mip_levels > range->mipLevels)
745 mip_levels = range->mipLevels;
746
747 array_size = img->array_size - range->baseArraySlice;
748 if (array_size > range->arraySize)
749 array_size = range->arraySize;
750
Chia-I Wuc14d1562014-10-17 09:49:22 +0800751 for (i = 0; i < mip_levels; i++) {
Chia-I Wufaaed472014-10-28 14:17:43 +0800752 meta->dst.lod = range->baseMipLevel + i;
753 meta->dst.layer = range->baseArraySlice;
754
Chia-I Wuc14d1562014-10-17 09:49:22 +0800755 meta->width = u_minify(img->layout.width0, meta->dst.lod);
756 meta->height = u_minify(img->layout.height0, meta->dst.lod);
757
758 for (j = 0; j < array_size; j++) {
759 if (range->aspect == XGL_IMAGE_ASPECT_COLOR) {
760 cmd_meta_set_dst_for_img(cmd, img, format,
761 meta->dst.lod, meta->dst.layer, meta);
762
763 cmd_draw_meta(cmd, meta);
764 } else {
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800765 cmd_meta_set_ds_view(cmd, img, meta->dst.lod,
Chia-I Wuc14d1562014-10-17 09:49:22 +0800766 meta->dst.layer, meta);
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800767 cmd_meta_set_ds_state(cmd, range->aspect,
768 meta->clear_val[1], meta);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800769
770 cmd_draw_meta(cmd, meta);
771
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800772 intel_ds_view_destroy(meta->ds.view);
773 intel_ds_state_destroy(meta->ds.state);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800774 }
775
776 meta->dst.layer++;
777 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800778 }
779}
780
781XGL_VOID XGLAPI intelCmdClearColorImage(
782 XGL_CMD_BUFFER cmdBuffer,
783 XGL_IMAGE image,
784 const XGL_FLOAT color[4],
785 XGL_UINT rangeCount,
786 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
787{
788 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
789 struct intel_img *img = intel_img(image);
790 struct intel_cmd_meta meta;
791 XGL_UINT i;
792
793 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800794 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800795
796 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
797 meta.samples = img->samples;
798
799 meta.clear_val[0] = u_fui(color[0]);
800 meta.clear_val[1] = u_fui(color[1]);
801 meta.clear_val[2] = u_fui(color[2]);
802 meta.clear_val[3] = u_fui(color[3]);
803
804 for (i = 0; i < rangeCount; i++) {
805 cmd_meta_clear_image(cmd, img, img->layout.format,
806 &meta, &pRanges[i]);
807 }
808}
809
810XGL_VOID XGLAPI intelCmdClearColorImageRaw(
811 XGL_CMD_BUFFER cmdBuffer,
812 XGL_IMAGE image,
813 const XGL_UINT32 color[4],
814 XGL_UINT rangeCount,
815 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
816{
817 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
818 struct intel_img *img = intel_img(image);
819 struct intel_cmd_meta meta;
820 XGL_FORMAT format;
821 XGL_UINT i;
822
823 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800824 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800825
826 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
827 meta.samples = img->samples;
828
829 meta.clear_val[0] = color[0];
830 meta.clear_val[1] = color[1];
831 meta.clear_val[2] = color[2];
832 meta.clear_val[3] = color[3];
833
834 format = cmd_meta_img_raw_format(cmd, img->layout.format);
835
836 for (i = 0; i < rangeCount; i++)
837 cmd_meta_clear_image(cmd, img, format, &meta, &pRanges[i]);
838}
839
840XGL_VOID XGLAPI intelCmdClearDepthStencil(
841 XGL_CMD_BUFFER cmdBuffer,
842 XGL_IMAGE image,
843 XGL_FLOAT depth,
844 XGL_UINT32 stencil,
845 XGL_UINT rangeCount,
846 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
847{
848 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
849 struct intel_img *img = intel_img(image);
850 struct intel_cmd_meta meta;
851 XGL_UINT i;
852
853 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800854 meta.mode = INTEL_CMD_META_DEPTH_STENCIL_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800855
856 meta.shader_id = INTEL_DEV_META_FS_CLEAR_DEPTH;
857 meta.samples = img->samples;
858
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800859 meta.clear_val[0] = u_fui(depth);
860 meta.clear_val[1] = stencil;
861
Chia-I Wuc14d1562014-10-17 09:49:22 +0800862 for (i = 0; i < rangeCount; i++) {
863 const XGL_IMAGE_SUBRESOURCE_RANGE *range = &pRanges[i];
864
Chia-I Wuc14d1562014-10-17 09:49:22 +0800865 cmd_meta_clear_image(cmd, img, img->layout.format,
866 &meta, range);
867 }
868}
869
870XGL_VOID XGLAPI intelCmdResolveImage(
871 XGL_CMD_BUFFER cmdBuffer,
872 XGL_IMAGE srcImage,
873 XGL_IMAGE destImage,
874 XGL_UINT rectCount,
875 const XGL_IMAGE_RESOLVE* pRects)
876{
877 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
878 struct intel_img *src = intel_img(srcImage);
879 struct intel_img *dst = intel_img(destImage);
880 struct intel_cmd_meta meta;
881 XGL_FORMAT format;
882 XGL_UINT i;
883
884 if (src->samples <= 1 || dst->samples > 1 ||
885 !icd_format_is_equal(src->layout.format, dst->layout.format)) {
886 cmd->result = XGL_ERROR_UNKNOWN;
887 return;
888 }
889
890 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800891 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800892
893 switch (src->samples) {
894 case 2:
895 default:
896 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_2X;
897 break;
898 case 4:
899 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_4X;
900 break;
901 case 8:
902 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_8X;
903 break;
904 case 16:
905 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_16X;
906 break;
907 }
908
909 meta.samples = 1;
910
911 format = cmd_meta_img_raw_format(cmd, src->layout.format);
912 cmd_meta_set_src_for_img(cmd, src, format, XGL_IMAGE_ASPECT_COLOR, &meta);
913
914 for (i = 0; i < rectCount; i++) {
915 const XGL_IMAGE_RESOLVE *rect = &pRects[i];
916
917 meta.src.lod = rect->srcSubresource.mipLevel;
918 meta.src.layer = rect->srcSubresource.arraySlice;
919 meta.src.x = rect->srcOffset.x;
920 meta.src.y = rect->srcOffset.y;
921
922 meta.dst.lod = rect->destSubresource.mipLevel;
923 meta.dst.layer = rect->destSubresource.arraySlice;
924 meta.dst.x = rect->destOffset.x;
925 meta.dst.y = rect->destOffset.y;
926
927 meta.width = rect->extent.width;
928 meta.height = rect->extent.height;
929
930 cmd_meta_set_dst_for_img(cmd, dst, format,
931 meta.dst.lod, meta.dst.layer, &meta);
932
933 cmd_draw_meta(cmd, &meta);
934 }
935}