blob: f383fad9ce4fe6a9de093cebeea98e94fdd73038 [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
Chia-I Wu957b9ca2014-11-30 12:58:17 +0800180 /* adjust width/height */
181 if (icd_format_is_compressed(img->layout.format)) {
182 XGL_INT w, h;
183
184 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
185 w = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_WIDTH);
186 h = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_HEIGHT);
187 meta->dst.surface[2] &= ~(GEN7_SURFACE_DW2_WIDTH__MASK |
188 GEN7_SURFACE_DW2_HEIGHT__MASK);
189 } else {
190 w = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_WIDTH);
191 h = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_HEIGHT);
192 meta->dst.surface[2] &= ~(GEN6_SURFACE_DW2_WIDTH__MASK |
193 GEN6_SURFACE_DW2_HEIGHT__MASK);
194 }
195
196 /* note that the width/height fields have the real values minus 1 */
197 w = (w + img->layout.block_width) / img->layout.block_width - 1;
198 h = (h + img->layout.block_height) / img->layout.block_height - 1;
199
200 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
201 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN7_SURFACE_DW2_WIDTH) |
202 GEN_SHIFT32(h, GEN7_SURFACE_DW2_HEIGHT);
203 } else {
204 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN6_SURFACE_DW2_WIDTH) |
205 GEN_SHIFT32(h, GEN6_SURFACE_DW2_HEIGHT);
206 }
207 }
208
Chia-I Wuc14d1562014-10-17 09:49:22 +0800209 meta->dst.reloc_target = (intptr_t) img->obj.mem->bo;
210 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +0800211 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800212
213 intel_rt_view_destroy(rt);
214}
215
216static void cmd_meta_set_src_for_writer(struct intel_cmd *cmd,
217 enum intel_cmd_writer_type writer,
218 XGL_GPU_SIZE size,
219 XGL_FORMAT format,
220 struct intel_cmd_meta *meta)
221{
222 struct intel_mem_view view;
223
224 cmd_meta_init_mem_view(cmd, XGL_NULL_HANDLE, size, format,
225 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
226
227 meta->src.valid = true;
228
229 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
230 meta->src.surface_len = view.cmd_len;
231
232 meta->src.reloc_target = (intptr_t) writer;
233 meta->src.reloc_offset = 0;
234 meta->src.reloc_flags = INTEL_CMD_RELOC_TARGET_IS_WRITER;
235}
236
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800237static void cmd_meta_set_ds_view(struct intel_cmd *cmd,
238 const struct intel_img *img,
239 XGL_UINT lod, XGL_UINT layer,
240 struct intel_cmd_meta *meta)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800241{
242 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO info;
243 struct intel_ds_view *ds;
244 XGL_RESULT ret;
245
246 memset(&info, 0, sizeof(info));
247 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
248 info.image = (XGL_IMAGE) img;
249 info.mipLevel = lod;
250 info.baseArraySlice = layer;
251 info.arraySize = 1;
252
253 ret = intel_ds_view_create(cmd->dev, &info, &ds);
254 if (ret != XGL_SUCCESS) {
255 cmd->result = ret;
256 return;
257 }
258
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800259 meta->ds.view = ds;
260}
261
262static void cmd_meta_set_ds_state(struct intel_cmd *cmd,
263 XGL_IMAGE_ASPECT aspect,
264 XGL_UINT32 stencil_ref,
265 struct intel_cmd_meta *meta)
266{
267 XGL_DEPTH_STENCIL_STATE_CREATE_INFO info;
268 struct intel_ds_state *state;
269 XGL_RESULT ret;
270
271 memset(&info, 0, sizeof(info));
272 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO;
273
274 if (aspect == XGL_IMAGE_ASPECT_DEPTH) {
275 info.depthWriteEnable = XGL_TRUE;
276 }
277 else if (aspect == XGL_IMAGE_ASPECT_STENCIL) {
278 info.stencilTestEnable = XGL_TRUE;
279 info.stencilReadMask = 0xff;
280 info.stencilWriteMask = 0xff;
281 info.front.stencilFailOp = XGL_STENCIL_OP_KEEP;
282 info.front.stencilPassOp = XGL_STENCIL_OP_REPLACE;
283 info.front.stencilDepthFailOp = XGL_STENCIL_OP_KEEP;
284 info.front.stencilFunc = XGL_COMPARE_ALWAYS;
285 info.front.stencilRef = stencil_ref;
286 info.back = info.front;
287 }
288
289 ret = intel_ds_state_create(cmd->dev, &info, &state);
290 if (ret != XGL_SUCCESS) {
291 cmd->result = ret;
292 return;
293 }
294
295 meta->ds.state = state;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800296}
297
298static enum intel_dev_meta_shader get_shader_id(const struct intel_dev *dev,
299 const struct intel_img *img,
300 bool copy_array)
301{
302 enum intel_dev_meta_shader shader_id;
303
304 switch (img->type) {
305 case XGL_IMAGE_1D:
306 shader_id = (copy_array) ?
307 INTEL_DEV_META_FS_COPY_1D_ARRAY : INTEL_DEV_META_FS_COPY_1D;
308 break;
309 case XGL_IMAGE_2D:
310 shader_id = (img->samples > 1) ? INTEL_DEV_META_FS_COPY_2D_MS :
311 (copy_array) ? INTEL_DEV_META_FS_COPY_2D_ARRAY :
312 INTEL_DEV_META_FS_COPY_2D;
313 break;
314 case XGL_IMAGE_3D:
315 default:
316 shader_id = INTEL_DEV_META_FS_COPY_2D_ARRAY;
317 break;
318 }
319
320 return shader_id;
321}
322
Chia-I Wuf3a27252014-11-24 15:27:01 +0800323static bool cmd_meta_mem_dword_aligned(const struct intel_cmd *cmd,
324 XGL_GPU_SIZE src_offset,
325 XGL_GPU_SIZE dst_offset,
326 XGL_GPU_SIZE size)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800327{
Chia-I Wuf3a27252014-11-24 15:27:01 +0800328 return !((src_offset | dst_offset | size) & 0x3);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800329}
330
331static XGL_FORMAT cmd_meta_img_raw_format(const struct intel_cmd *cmd,
332 XGL_FORMAT format)
333{
334 format.numericFormat = XGL_NUM_FMT_UINT;
335
336 if (icd_format_is_compressed(format)) {
337 switch (icd_format_get_size(format)) {
338 case 1:
339 format.channelFormat = XGL_CH_FMT_R8;
340 break;
341 case 2:
342 format.channelFormat = XGL_CH_FMT_R16;
343 break;
344 case 4:
345 format.channelFormat = XGL_CH_FMT_R32;
346 break;
347 case 8:
348 format.channelFormat = XGL_CH_FMT_R32G32;
349 break;
350 case 16:
351 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
352 break;
353 default:
354 assert(!"unsupported compressed block size");
355 format.channelFormat = XGL_CH_FMT_R8;
356 break;
357 }
358 }
359
360 return format;
361}
362
363XGL_VOID XGLAPI intelCmdCopyMemory(
364 XGL_CMD_BUFFER cmdBuffer,
365 XGL_GPU_MEMORY srcMem,
366 XGL_GPU_MEMORY destMem,
367 XGL_UINT regionCount,
368 const XGL_MEMORY_COPY* pRegions)
369{
370 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
371 struct intel_mem *src = intel_mem(srcMem);
372 struct intel_mem *dst = intel_mem(destMem);
373 struct intel_cmd_meta meta;
374 XGL_FORMAT format;
375 XGL_UINT i;
376
377 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800378 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800379
Chia-I Wuc14d1562014-10-17 09:49:22 +0800380 meta.height = 1;
381 meta.samples = 1;
382
383 format.channelFormat = XGL_CH_FMT_UNDEFINED;
384 format.numericFormat = XGL_NUM_FMT_UINT;
385
386 for (i = 0; i < regionCount; i++) {
387 const XGL_MEMORY_COPY *region = &pRegions[i];
388 XGL_CHANNEL_FORMAT ch;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800389
Chia-I Wuf3a27252014-11-24 15:27:01 +0800390 meta.src.x = region->srcOffset;
391 meta.dst.x = region->destOffset;
392 meta.width = region->copySize;
393
394 if (cmd_meta_mem_dword_aligned(cmd, region->srcOffset,
395 region->destOffset, region->copySize)) {
396 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
397 meta.src.x /= 4;
398 meta.dst.x /= 4;
399 meta.width /= 4;
400
401 /*
402 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to
403 * be 16
404 */
405 ch = XGL_CH_FMT_R32G32B32A32;
406 } else {
407 if (cmd_gen(cmd) == INTEL_GEN(6)) {
408 intel_dev_log(cmd->dev, XGL_DBG_MSG_ERROR,
409 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
410 "unaligned xglCmdCopyMemory unsupported");
411 cmd->result = XGL_ERROR_UNKNOWN;
412 continue;
413 }
414
415 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM_UNALIGNED;
416
417 /*
418 * INTEL_DEV_META_VS_COPY_MEM_UNALIGNED is untyped but expects the
419 * stride to be 4
420 */
421 ch = XGL_CH_FMT_R8G8B8A8;
422 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800423
424 if (format.channelFormat != ch) {
425 format.channelFormat = ch;
426
427 cmd_meta_set_src_for_mem(cmd, src, format, &meta);
428 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
429 }
430
Chia-I Wuc14d1562014-10-17 09:49:22 +0800431 cmd_draw_meta(cmd, &meta);
432 }
433}
434
435XGL_VOID XGLAPI intelCmdCopyImage(
436 XGL_CMD_BUFFER cmdBuffer,
437 XGL_IMAGE srcImage,
438 XGL_IMAGE destImage,
439 XGL_UINT regionCount,
440 const XGL_IMAGE_COPY* pRegions)
441{
442 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
443 struct intel_img *src = intel_img(srcImage);
444 struct intel_img *dst = intel_img(destImage);
445 struct intel_cmd_meta meta;
446 XGL_FORMAT raw_format;
447 bool raw_copy;
448 XGL_UINT i;
449
450 if (src->type != dst->type) {
451 cmd->result = XGL_ERROR_UNKNOWN;
452 return;
453 }
454
455 if (icd_format_is_equal(src->layout.format, dst->layout.format)) {
456 raw_copy = true;
457 raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
458 } else if (icd_format_is_compressed(src->layout.format) ||
459 icd_format_is_compressed(dst->layout.format)) {
460 cmd->result = XGL_ERROR_UNKNOWN;
461 return;
462 }
463
464 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800465 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800466
467 cmd_meta_set_src_for_img(cmd, src,
468 (raw_copy) ? raw_format : src->layout.format,
469 XGL_IMAGE_ASPECT_COLOR, &meta);
470
471 meta.samples = dst->samples;
472
473 for (i = 0; i < regionCount; i++) {
474 const XGL_IMAGE_COPY *region = &pRegions[i];
475 XGL_UINT j;
476
477 meta.shader_id = get_shader_id(cmd->dev, src,
478 (region->extent.depth > 1));
479
480 meta.src.lod = region->srcSubresource.mipLevel;
481 meta.src.layer = region->srcSubresource.arraySlice +
482 region->srcOffset.z;
483 meta.src.x = region->srcOffset.x;
484 meta.src.y = region->srcOffset.y;
485
486 meta.dst.lod = region->destSubresource.mipLevel;
487 meta.dst.layer = region->destSubresource.arraySlice +
488 region->destOffset.z;
489 meta.dst.x = region->destOffset.x;
490 meta.dst.y = region->destOffset.y;
491
492 meta.width = region->extent.width;
493 meta.height = region->extent.height;
494
495 for (j = 0; j < region->extent.depth; j++) {
496 cmd_meta_set_dst_for_img(cmd, dst,
497 (raw_copy) ? raw_format : dst->layout.format,
498 meta.dst.lod, meta.dst.layer, &meta);
499
500 cmd_draw_meta(cmd, &meta);
501
502 meta.src.layer++;
503 meta.dst.layer++;
504 }
505 }
506}
507
508XGL_VOID XGLAPI intelCmdCopyMemoryToImage(
509 XGL_CMD_BUFFER cmdBuffer,
510 XGL_GPU_MEMORY srcMem,
511 XGL_IMAGE destImage,
512 XGL_UINT regionCount,
513 const XGL_MEMORY_IMAGE_COPY* pRegions)
514{
515 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
516 struct intel_mem *mem = intel_mem(srcMem);
517 struct intel_img *img = intel_img(destImage);
518 struct intel_cmd_meta meta;
519 XGL_FORMAT format;
520 XGL_UINT i;
521
522 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800523 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800524
525 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM_TO_IMG;
526 meta.samples = img->samples;
527
528 format = cmd_meta_img_raw_format(cmd, img->layout.format);
529 cmd_meta_set_src_for_mem(cmd, mem, format, &meta);
530
531 for (i = 0; i < regionCount; i++) {
532 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
533 XGL_UINT j;
534
535 meta.src.x = region->memOffset / icd_format_get_size(format);
536
537 meta.dst.lod = region->imageSubresource.mipLevel;
538 meta.dst.layer = region->imageSubresource.arraySlice +
539 region->imageOffset.z;
540 meta.dst.x = region->imageOffset.x;
541 meta.dst.y = region->imageOffset.y;
542
543 meta.width = region->imageExtent.width;
544 meta.height = region->imageExtent.height;
545
546 for (j = 0; j < region->imageExtent.depth; j++) {
547 cmd_meta_set_dst_for_img(cmd, img, format,
548 meta.dst.lod, meta.dst.layer, &meta);
549
550 cmd_draw_meta(cmd, &meta);
551
552 meta.src.x += meta.width * meta.height;
553 meta.dst.layer++;
554 }
555 }
556}
557
558XGL_VOID XGLAPI intelCmdCopyImageToMemory(
559 XGL_CMD_BUFFER cmdBuffer,
560 XGL_IMAGE srcImage,
561 XGL_GPU_MEMORY destMem,
562 XGL_UINT regionCount,
563 const XGL_MEMORY_IMAGE_COPY* pRegions)
564{
565 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
566 struct intel_img *img = intel_img(srcImage);
567 struct intel_mem *mem = intel_mem(destMem);
568 struct intel_cmd_meta meta;
569 XGL_FORMAT format;
570 XGL_UINT i;
571
572 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800573 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800574
575 format = cmd_meta_img_raw_format(cmd, img->layout.format);
576 cmd_meta_set_src_for_img(cmd, img, format, XGL_IMAGE_ASPECT_COLOR, &meta);
577 cmd_meta_set_dst_for_mem(cmd, mem, format, &meta);
578
579 meta.height = 1;
580 meta.samples = 1;
581
582 for (i = 0; i < regionCount; i++) {
583 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
584 XGL_UINT j;
585
586 meta.shader_id = get_shader_id(cmd->dev, img,
587 (region->imageExtent.depth > 1));
588
589 meta.src.lod = region->imageSubresource.mipLevel;
590 meta.src.layer = region->imageSubresource.arraySlice +
591 region->imageOffset.z;
592 meta.src.x = region->imageOffset.x;
593 meta.src.y = region->imageOffset.y;
594
595 meta.dst.x = region->memOffset / icd_format_get_size(format);
596
597 meta.width = region->imageExtent.width * region->imageExtent.height;
598
599 for (j = 0; j < region->imageExtent.depth; j++) {
600 cmd_draw_meta(cmd, &meta);
601
602 meta.src.layer++;
603 meta.dst.x += meta.width;
604 }
605 }
606}
607
608XGL_VOID XGLAPI intelCmdCloneImageData(
609 XGL_CMD_BUFFER cmdBuffer,
610 XGL_IMAGE srcImage,
611 XGL_IMAGE_STATE srcImageState,
612 XGL_IMAGE destImage,
613 XGL_IMAGE_STATE destImageState)
614{
615 const struct intel_img *src = intel_img(srcImage);
616 XGL_IMAGE_COPY region;
617 XGL_UINT lv;
618
619 memset(&region, 0, sizeof(region));
620 region.srcSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
621 region.destSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
622
623 for (lv = 0; lv < src->mip_levels; lv++) {
624 region.srcSubresource.mipLevel = lv;
625 region.destSubresource.mipLevel = lv;
626
627 region.extent.width = u_minify(src->layout.width0, lv);
628 region.extent.height = u_minify(src->layout.height0, lv);
629 region.extent.depth = src->array_size;
630
631 intelCmdCopyImage(cmdBuffer, srcImage, destImage, 1, &region);
632 }
633}
634
635XGL_VOID XGLAPI intelCmdUpdateMemory(
636 XGL_CMD_BUFFER cmdBuffer,
637 XGL_GPU_MEMORY destMem,
638 XGL_GPU_SIZE destOffset,
639 XGL_GPU_SIZE dataSize,
640 const XGL_UINT32* pData)
641{
642 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
643 struct intel_mem *dst = intel_mem(destMem);
644 struct intel_cmd_meta meta;
645 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800646 uint32_t *ptr;
647 uint32_t offset;
648
Chia-I Wuf3a27252014-11-24 15:27:01 +0800649 /* must be 4-byte aligned */
650 if ((destOffset | dataSize) & 3) {
651 cmd->result = XGL_ERROR_UNKNOWN;
652 return;
653 }
654
Chia-I Wuc14d1562014-10-17 09:49:22 +0800655 /* write to dynamic state writer first */
656 offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
657 (dataSize + 3) / 4, &ptr);
658 memcpy(ptr, pData, dataSize);
659
Chia-I Wuc14d1562014-10-17 09:49:22 +0800660 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800661 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800662
Chia-I Wuf3a27252014-11-24 15:27:01 +0800663 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
664
665 meta.src.x = offset / 4;
666 meta.dst.x = destOffset / 4;
667 meta.width = dataSize / 4;
668 meta.height = 1;
669 meta.samples = 1;
670
671 /*
672 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to be 16
673 */
674 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
675 format.numericFormat = XGL_NUM_FMT_UINT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800676
677 cmd_meta_set_src_for_writer(cmd, INTEL_CMD_WRITER_STATE,
678 offset + dataSize, format, &meta);
679 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
680
Chia-I Wuc14d1562014-10-17 09:49:22 +0800681 cmd_draw_meta(cmd, &meta);
682}
683
684XGL_VOID XGLAPI intelCmdFillMemory(
685 XGL_CMD_BUFFER cmdBuffer,
686 XGL_GPU_MEMORY destMem,
687 XGL_GPU_SIZE destOffset,
688 XGL_GPU_SIZE fillSize,
689 XGL_UINT32 data)
690{
691 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
692 struct intel_mem *dst = intel_mem(destMem);
693 struct intel_cmd_meta meta;
694 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800695
696 /* must be 4-byte aligned */
697 if ((destOffset | fillSize) & 3) {
698 cmd->result = XGL_ERROR_UNKNOWN;
699 return;
700 }
701
702 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800703 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800704
Chia-I Wuf3a27252014-11-24 15:27:01 +0800705 meta.shader_id = INTEL_DEV_META_VS_FILL_MEM;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800706
707 meta.clear_val[0] = data;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800708
Chia-I Wuf3a27252014-11-24 15:27:01 +0800709 meta.dst.x = destOffset / 4;
710 meta.width = fillSize / 4;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800711 meta.height = 1;
712 meta.samples = 1;
713
Chia-I Wuf3a27252014-11-24 15:27:01 +0800714 /*
715 * INTEL_DEV_META_VS_FILL_MEM is untyped but expects the stride to be 16
716 */
717 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
718 format.numericFormat = XGL_NUM_FMT_UINT;
719
720 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
721
Chia-I Wuc14d1562014-10-17 09:49:22 +0800722 cmd_draw_meta(cmd, &meta);
723}
724
725static void cmd_meta_clear_image(struct intel_cmd *cmd,
726 struct intel_img *img,
727 XGL_FORMAT format,
728 struct intel_cmd_meta *meta,
729 const XGL_IMAGE_SUBRESOURCE_RANGE *range)
730{
731 XGL_UINT mip_levels, array_size;
732 XGL_UINT i, j;
733
734 if (range->baseMipLevel >= img->mip_levels ||
735 range->baseArraySlice >= img->array_size)
736 return;
737
738 mip_levels = img->mip_levels - range->baseMipLevel;
739 if (mip_levels > range->mipLevels)
740 mip_levels = range->mipLevels;
741
742 array_size = img->array_size - range->baseArraySlice;
743 if (array_size > range->arraySize)
744 array_size = range->arraySize;
745
Chia-I Wuc14d1562014-10-17 09:49:22 +0800746 for (i = 0; i < mip_levels; i++) {
Chia-I Wufaaed472014-10-28 14:17:43 +0800747 meta->dst.lod = range->baseMipLevel + i;
748 meta->dst.layer = range->baseArraySlice;
749
Chia-I Wuc14d1562014-10-17 09:49:22 +0800750 meta->width = u_minify(img->layout.width0, meta->dst.lod);
751 meta->height = u_minify(img->layout.height0, meta->dst.lod);
752
753 for (j = 0; j < array_size; j++) {
754 if (range->aspect == XGL_IMAGE_ASPECT_COLOR) {
755 cmd_meta_set_dst_for_img(cmd, img, format,
756 meta->dst.lod, meta->dst.layer, meta);
757
758 cmd_draw_meta(cmd, meta);
759 } else {
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800760 cmd_meta_set_ds_view(cmd, img, meta->dst.lod,
Chia-I Wuc14d1562014-10-17 09:49:22 +0800761 meta->dst.layer, meta);
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800762 cmd_meta_set_ds_state(cmd, range->aspect,
763 meta->clear_val[1], meta);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800764
765 cmd_draw_meta(cmd, meta);
766
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800767 intel_ds_view_destroy(meta->ds.view);
768 intel_ds_state_destroy(meta->ds.state);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800769 }
770
771 meta->dst.layer++;
772 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800773 }
774}
775
776XGL_VOID XGLAPI intelCmdClearColorImage(
777 XGL_CMD_BUFFER cmdBuffer,
778 XGL_IMAGE image,
779 const XGL_FLOAT 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_UINT i;
787
788 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800789 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800790
791 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
792 meta.samples = img->samples;
793
794 meta.clear_val[0] = u_fui(color[0]);
795 meta.clear_val[1] = u_fui(color[1]);
796 meta.clear_val[2] = u_fui(color[2]);
797 meta.clear_val[3] = u_fui(color[3]);
798
799 for (i = 0; i < rangeCount; i++) {
800 cmd_meta_clear_image(cmd, img, img->layout.format,
801 &meta, &pRanges[i]);
802 }
803}
804
805XGL_VOID XGLAPI intelCmdClearColorImageRaw(
806 XGL_CMD_BUFFER cmdBuffer,
807 XGL_IMAGE image,
808 const XGL_UINT32 color[4],
809 XGL_UINT rangeCount,
810 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
811{
812 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
813 struct intel_img *img = intel_img(image);
814 struct intel_cmd_meta meta;
815 XGL_FORMAT format;
816 XGL_UINT i;
817
818 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800819 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800820
821 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
822 meta.samples = img->samples;
823
824 meta.clear_val[0] = color[0];
825 meta.clear_val[1] = color[1];
826 meta.clear_val[2] = color[2];
827 meta.clear_val[3] = color[3];
828
829 format = cmd_meta_img_raw_format(cmd, img->layout.format);
830
831 for (i = 0; i < rangeCount; i++)
832 cmd_meta_clear_image(cmd, img, format, &meta, &pRanges[i]);
833}
834
835XGL_VOID XGLAPI intelCmdClearDepthStencil(
836 XGL_CMD_BUFFER cmdBuffer,
837 XGL_IMAGE image,
838 XGL_FLOAT depth,
839 XGL_UINT32 stencil,
840 XGL_UINT rangeCount,
841 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
842{
843 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
844 struct intel_img *img = intel_img(image);
845 struct intel_cmd_meta meta;
846 XGL_UINT i;
847
848 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800849 meta.mode = INTEL_CMD_META_DEPTH_STENCIL_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800850
851 meta.shader_id = INTEL_DEV_META_FS_CLEAR_DEPTH;
852 meta.samples = img->samples;
853
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800854 meta.clear_val[0] = u_fui(depth);
855 meta.clear_val[1] = stencil;
856
Chia-I Wuc14d1562014-10-17 09:49:22 +0800857 for (i = 0; i < rangeCount; i++) {
858 const XGL_IMAGE_SUBRESOURCE_RANGE *range = &pRanges[i];
859
Chia-I Wuc14d1562014-10-17 09:49:22 +0800860 cmd_meta_clear_image(cmd, img, img->layout.format,
861 &meta, range);
862 }
863}
864
865XGL_VOID XGLAPI intelCmdResolveImage(
866 XGL_CMD_BUFFER cmdBuffer,
867 XGL_IMAGE srcImage,
868 XGL_IMAGE destImage,
869 XGL_UINT rectCount,
870 const XGL_IMAGE_RESOLVE* pRects)
871{
872 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
873 struct intel_img *src = intel_img(srcImage);
874 struct intel_img *dst = intel_img(destImage);
875 struct intel_cmd_meta meta;
876 XGL_FORMAT format;
877 XGL_UINT i;
878
879 if (src->samples <= 1 || dst->samples > 1 ||
880 !icd_format_is_equal(src->layout.format, dst->layout.format)) {
881 cmd->result = XGL_ERROR_UNKNOWN;
882 return;
883 }
884
885 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800886 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800887
888 switch (src->samples) {
889 case 2:
890 default:
891 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_2X;
892 break;
893 case 4:
894 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_4X;
895 break;
896 case 8:
897 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_8X;
898 break;
899 case 16:
900 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_16X;
901 break;
902 }
903
904 meta.samples = 1;
905
906 format = cmd_meta_img_raw_format(cmd, src->layout.format);
907 cmd_meta_set_src_for_img(cmd, src, format, XGL_IMAGE_ASPECT_COLOR, &meta);
908
909 for (i = 0; i < rectCount; i++) {
910 const XGL_IMAGE_RESOLVE *rect = &pRects[i];
911
912 meta.src.lod = rect->srcSubresource.mipLevel;
913 meta.src.layer = rect->srcSubresource.arraySlice;
914 meta.src.x = rect->srcOffset.x;
915 meta.src.y = rect->srcOffset.y;
916
917 meta.dst.lod = rect->destSubresource.mipLevel;
918 meta.dst.layer = rect->destSubresource.arraySlice;
919 meta.dst.x = rect->destOffset.x;
920 meta.dst.y = rect->destOffset.y;
921
922 meta.width = rect->extent.width;
923 meta.height = rect->extent.height;
924
925 cmd_meta_set_dst_for_img(cmd, dst, format,
926 meta.dst.lod, meta.dst.layer, &meta);
927
928 cmd_draw_meta(cmd, &meta);
929 }
930}