blob: ad037fce0b368f45c0a5ec1e096eb854748a4bfa [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{
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800155 XGL_INT w, h, layer;
156 unsigned x_offset, y_offset;
Chia-I Wu83084ba2014-12-04 12:49:52 +0800157
158 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
159 w = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_WIDTH);
160 h = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_HEIGHT);
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800161 layer = GEN_EXTRACT(meta->dst.surface[4],
162 GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800163 } else {
164 w = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_WIDTH);
165 h = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_HEIGHT);
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800166 layer = GEN_EXTRACT(meta->dst.surface[4],
167 GEN6_SURFACE_DW4_MIN_ARRAY_ELEMENT);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800168 }
169
170 /* note that the width/height fields have the real values minus 1 */
171 w = (w + img->layout.block_width) / img->layout.block_width - 1;
172 h = (h + img->layout.block_height) / img->layout.block_height - 1;
173
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800174 /* adjust width and height */
Chia-I Wu83084ba2014-12-04 12:49:52 +0800175 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800176 meta->dst.surface[2] &= ~(GEN7_SURFACE_DW2_WIDTH__MASK |
177 GEN7_SURFACE_DW2_HEIGHT__MASK);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800178 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN7_SURFACE_DW2_WIDTH) |
179 GEN_SHIFT32(h, GEN7_SURFACE_DW2_HEIGHT);
180 } else {
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800181 meta->dst.surface[2] &= ~(GEN6_SURFACE_DW2_WIDTH__MASK |
182 GEN6_SURFACE_DW2_HEIGHT__MASK);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800183 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN6_SURFACE_DW2_WIDTH) |
184 GEN_SHIFT32(h, GEN6_SURFACE_DW2_HEIGHT);
185 }
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800186
187 if (!layer)
188 return;
189
190 meta->dst.reloc_offset = intel_layout_get_slice_tile_offset(&img->layout,
191 0, layer, &x_offset, &y_offset);
192
193 /*
194 * The lower 2 bits (or 1 bit for Y) are missing. This may be a problem
195 * for small images (16x16 or smaller). We will need to adjust the
196 * drawing rectangle instead.
197 */
198 x_offset = (x_offset / img->layout.block_width) >> 2;
199 y_offset = (y_offset / img->layout.block_height) >> 1;
200
201 /* adjust min array element and X/Y offsets */
202 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
203 meta->dst.surface[4] &= ~GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT__MASK;
204 meta->dst.surface[5] |= GEN_SHIFT32(x_offset, GEN7_SURFACE_DW5_X_OFFSET) |
205 GEN_SHIFT32(y_offset, GEN7_SURFACE_DW5_Y_OFFSET);
206 } else {
207 meta->dst.surface[4] &= ~GEN6_SURFACE_DW4_MIN_ARRAY_ELEMENT__MASK;
208 meta->dst.surface[5] |= GEN_SHIFT32(x_offset, GEN6_SURFACE_DW5_X_OFFSET) |
209 GEN_SHIFT32(y_offset, GEN6_SURFACE_DW5_Y_OFFSET);
210 }
Chia-I Wu83084ba2014-12-04 12:49:52 +0800211}
212
Chia-I Wuc14d1562014-10-17 09:49:22 +0800213static void cmd_meta_set_dst_for_img(struct intel_cmd *cmd,
214 const struct intel_img *img,
215 XGL_FORMAT format,
216 XGL_UINT lod, XGL_UINT layer,
217 struct intel_cmd_meta *meta)
218{
219 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO info;
220 struct intel_rt_view *rt;
221 XGL_RESULT ret;
222
223 memset(&info, 0, sizeof(info));
224 info.sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO;
225 info.image = (XGL_IMAGE) img;
226 info.format = format;
227 info.mipLevel = lod;
228 info.baseArraySlice = layer;
229 info.arraySize = 1;
230
231 ret = intel_rt_view_create(cmd->dev, &info, &rt);
232 if (ret != XGL_SUCCESS) {
233 cmd->result = ret;
234 return;
235 }
236
237 meta->dst.valid = true;
238
239 memcpy(meta->dst.surface, rt->cmd, sizeof(rt->cmd[0]) * rt->cmd_len);
240 meta->dst.surface_len = rt->cmd_len;
241
242 meta->dst.reloc_target = (intptr_t) img->obj.mem->bo;
243 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +0800244 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800245
Chia-I Wu83084ba2014-12-04 12:49:52 +0800246 if (icd_format_is_compressed(img->layout.format))
247 cmd_meta_adjust_compressed_dst(cmd, img, meta);
248
Chia-I Wuc14d1562014-10-17 09:49:22 +0800249 intel_rt_view_destroy(rt);
250}
251
252static void cmd_meta_set_src_for_writer(struct intel_cmd *cmd,
253 enum intel_cmd_writer_type writer,
254 XGL_GPU_SIZE size,
255 XGL_FORMAT format,
256 struct intel_cmd_meta *meta)
257{
258 struct intel_mem_view view;
259
260 cmd_meta_init_mem_view(cmd, XGL_NULL_HANDLE, size, format,
261 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
262
263 meta->src.valid = true;
264
265 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
266 meta->src.surface_len = view.cmd_len;
267
268 meta->src.reloc_target = (intptr_t) writer;
269 meta->src.reloc_offset = 0;
270 meta->src.reloc_flags = INTEL_CMD_RELOC_TARGET_IS_WRITER;
271}
272
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800273static void cmd_meta_set_ds_view(struct intel_cmd *cmd,
274 const struct intel_img *img,
275 XGL_UINT lod, XGL_UINT layer,
276 struct intel_cmd_meta *meta)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800277{
278 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO info;
279 struct intel_ds_view *ds;
280 XGL_RESULT ret;
281
282 memset(&info, 0, sizeof(info));
283 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
284 info.image = (XGL_IMAGE) img;
285 info.mipLevel = lod;
286 info.baseArraySlice = layer;
287 info.arraySize = 1;
288
289 ret = intel_ds_view_create(cmd->dev, &info, &ds);
290 if (ret != XGL_SUCCESS) {
291 cmd->result = ret;
292 return;
293 }
294
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800295 meta->ds.view = ds;
296}
297
298static void cmd_meta_set_ds_state(struct intel_cmd *cmd,
299 XGL_IMAGE_ASPECT aspect,
300 XGL_UINT32 stencil_ref,
301 struct intel_cmd_meta *meta)
302{
303 XGL_DEPTH_STENCIL_STATE_CREATE_INFO info;
304 struct intel_ds_state *state;
305 XGL_RESULT ret;
306
307 memset(&info, 0, sizeof(info));
308 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO;
309
310 if (aspect == XGL_IMAGE_ASPECT_DEPTH) {
311 info.depthWriteEnable = XGL_TRUE;
312 }
313 else if (aspect == XGL_IMAGE_ASPECT_STENCIL) {
314 info.stencilTestEnable = XGL_TRUE;
315 info.stencilReadMask = 0xff;
316 info.stencilWriteMask = 0xff;
317 info.front.stencilFailOp = XGL_STENCIL_OP_KEEP;
318 info.front.stencilPassOp = XGL_STENCIL_OP_REPLACE;
319 info.front.stencilDepthFailOp = XGL_STENCIL_OP_KEEP;
320 info.front.stencilFunc = XGL_COMPARE_ALWAYS;
321 info.front.stencilRef = stencil_ref;
322 info.back = info.front;
323 }
324
325 ret = intel_ds_state_create(cmd->dev, &info, &state);
326 if (ret != XGL_SUCCESS) {
327 cmd->result = ret;
328 return;
329 }
330
331 meta->ds.state = state;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800332}
333
334static enum intel_dev_meta_shader get_shader_id(const struct intel_dev *dev,
335 const struct intel_img *img,
336 bool copy_array)
337{
338 enum intel_dev_meta_shader shader_id;
339
340 switch (img->type) {
341 case XGL_IMAGE_1D:
342 shader_id = (copy_array) ?
343 INTEL_DEV_META_FS_COPY_1D_ARRAY : INTEL_DEV_META_FS_COPY_1D;
344 break;
345 case XGL_IMAGE_2D:
346 shader_id = (img->samples > 1) ? INTEL_DEV_META_FS_COPY_2D_MS :
347 (copy_array) ? INTEL_DEV_META_FS_COPY_2D_ARRAY :
348 INTEL_DEV_META_FS_COPY_2D;
349 break;
350 case XGL_IMAGE_3D:
351 default:
352 shader_id = INTEL_DEV_META_FS_COPY_2D_ARRAY;
353 break;
354 }
355
356 return shader_id;
357}
358
Chia-I Wuf3a27252014-11-24 15:27:01 +0800359static bool cmd_meta_mem_dword_aligned(const struct intel_cmd *cmd,
360 XGL_GPU_SIZE src_offset,
361 XGL_GPU_SIZE dst_offset,
362 XGL_GPU_SIZE size)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800363{
Chia-I Wuf3a27252014-11-24 15:27:01 +0800364 return !((src_offset | dst_offset | size) & 0x3);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800365}
366
367static XGL_FORMAT cmd_meta_img_raw_format(const struct intel_cmd *cmd,
368 XGL_FORMAT format)
369{
370 format.numericFormat = XGL_NUM_FMT_UINT;
371
372 if (icd_format_is_compressed(format)) {
373 switch (icd_format_get_size(format)) {
374 case 1:
375 format.channelFormat = XGL_CH_FMT_R8;
376 break;
377 case 2:
378 format.channelFormat = XGL_CH_FMT_R16;
379 break;
380 case 4:
381 format.channelFormat = XGL_CH_FMT_R32;
382 break;
383 case 8:
384 format.channelFormat = XGL_CH_FMT_R32G32;
385 break;
386 case 16:
387 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
388 break;
389 default:
390 assert(!"unsupported compressed block size");
391 format.channelFormat = XGL_CH_FMT_R8;
392 break;
393 }
394 }
395
396 return format;
397}
398
399XGL_VOID XGLAPI intelCmdCopyMemory(
400 XGL_CMD_BUFFER cmdBuffer,
401 XGL_GPU_MEMORY srcMem,
402 XGL_GPU_MEMORY destMem,
403 XGL_UINT regionCount,
404 const XGL_MEMORY_COPY* pRegions)
405{
406 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
407 struct intel_mem *src = intel_mem(srcMem);
408 struct intel_mem *dst = intel_mem(destMem);
409 struct intel_cmd_meta meta;
410 XGL_FORMAT format;
411 XGL_UINT i;
412
413 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800414 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800415
Chia-I Wuc14d1562014-10-17 09:49:22 +0800416 meta.height = 1;
417 meta.samples = 1;
418
419 format.channelFormat = XGL_CH_FMT_UNDEFINED;
420 format.numericFormat = XGL_NUM_FMT_UINT;
421
422 for (i = 0; i < regionCount; i++) {
423 const XGL_MEMORY_COPY *region = &pRegions[i];
424 XGL_CHANNEL_FORMAT ch;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800425
Chia-I Wuf3a27252014-11-24 15:27:01 +0800426 meta.src.x = region->srcOffset;
427 meta.dst.x = region->destOffset;
428 meta.width = region->copySize;
429
430 if (cmd_meta_mem_dword_aligned(cmd, region->srcOffset,
431 region->destOffset, region->copySize)) {
432 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
433 meta.src.x /= 4;
434 meta.dst.x /= 4;
435 meta.width /= 4;
436
437 /*
438 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to
439 * be 16
440 */
441 ch = XGL_CH_FMT_R32G32B32A32;
442 } else {
443 if (cmd_gen(cmd) == INTEL_GEN(6)) {
444 intel_dev_log(cmd->dev, XGL_DBG_MSG_ERROR,
445 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
446 "unaligned xglCmdCopyMemory unsupported");
447 cmd->result = XGL_ERROR_UNKNOWN;
448 continue;
449 }
450
451 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM_UNALIGNED;
452
453 /*
454 * INTEL_DEV_META_VS_COPY_MEM_UNALIGNED is untyped but expects the
455 * stride to be 4
456 */
457 ch = XGL_CH_FMT_R8G8B8A8;
458 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800459
460 if (format.channelFormat != ch) {
461 format.channelFormat = ch;
462
463 cmd_meta_set_src_for_mem(cmd, src, format, &meta);
464 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
465 }
466
Chia-I Wuc14d1562014-10-17 09:49:22 +0800467 cmd_draw_meta(cmd, &meta);
468 }
469}
470
471XGL_VOID XGLAPI intelCmdCopyImage(
472 XGL_CMD_BUFFER cmdBuffer,
473 XGL_IMAGE srcImage,
474 XGL_IMAGE destImage,
475 XGL_UINT regionCount,
476 const XGL_IMAGE_COPY* pRegions)
477{
478 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
479 struct intel_img *src = intel_img(srcImage);
480 struct intel_img *dst = intel_img(destImage);
481 struct intel_cmd_meta meta;
482 XGL_FORMAT raw_format;
483 bool raw_copy;
484 XGL_UINT i;
485
486 if (src->type != dst->type) {
487 cmd->result = XGL_ERROR_UNKNOWN;
488 return;
489 }
490
491 if (icd_format_is_equal(src->layout.format, dst->layout.format)) {
492 raw_copy = true;
493 raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
494 } else if (icd_format_is_compressed(src->layout.format) ||
495 icd_format_is_compressed(dst->layout.format)) {
496 cmd->result = XGL_ERROR_UNKNOWN;
497 return;
498 }
499
500 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800501 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800502
503 cmd_meta_set_src_for_img(cmd, src,
504 (raw_copy) ? raw_format : src->layout.format,
505 XGL_IMAGE_ASPECT_COLOR, &meta);
506
507 meta.samples = dst->samples;
508
509 for (i = 0; i < regionCount; i++) {
510 const XGL_IMAGE_COPY *region = &pRegions[i];
511 XGL_UINT j;
512
513 meta.shader_id = get_shader_id(cmd->dev, src,
514 (region->extent.depth > 1));
515
516 meta.src.lod = region->srcSubresource.mipLevel;
517 meta.src.layer = region->srcSubresource.arraySlice +
518 region->srcOffset.z;
519 meta.src.x = region->srcOffset.x;
520 meta.src.y = region->srcOffset.y;
521
522 meta.dst.lod = region->destSubresource.mipLevel;
523 meta.dst.layer = region->destSubresource.arraySlice +
524 region->destOffset.z;
525 meta.dst.x = region->destOffset.x;
526 meta.dst.y = region->destOffset.y;
527
528 meta.width = region->extent.width;
529 meta.height = region->extent.height;
530
531 for (j = 0; j < region->extent.depth; j++) {
532 cmd_meta_set_dst_for_img(cmd, dst,
533 (raw_copy) ? raw_format : dst->layout.format,
534 meta.dst.lod, meta.dst.layer, &meta);
535
536 cmd_draw_meta(cmd, &meta);
537
538 meta.src.layer++;
539 meta.dst.layer++;
540 }
541 }
542}
543
544XGL_VOID XGLAPI intelCmdCopyMemoryToImage(
545 XGL_CMD_BUFFER cmdBuffer,
546 XGL_GPU_MEMORY srcMem,
547 XGL_IMAGE destImage,
548 XGL_UINT regionCount,
549 const XGL_MEMORY_IMAGE_COPY* pRegions)
550{
551 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
552 struct intel_mem *mem = intel_mem(srcMem);
553 struct intel_img *img = intel_img(destImage);
554 struct intel_cmd_meta meta;
555 XGL_FORMAT format;
556 XGL_UINT i;
557
558 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800559 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800560
561 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM_TO_IMG;
562 meta.samples = img->samples;
563
564 format = cmd_meta_img_raw_format(cmd, img->layout.format);
565 cmd_meta_set_src_for_mem(cmd, mem, format, &meta);
566
567 for (i = 0; i < regionCount; i++) {
568 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
569 XGL_UINT j;
570
571 meta.src.x = region->memOffset / icd_format_get_size(format);
572
573 meta.dst.lod = region->imageSubresource.mipLevel;
574 meta.dst.layer = region->imageSubresource.arraySlice +
575 region->imageOffset.z;
576 meta.dst.x = region->imageOffset.x;
577 meta.dst.y = region->imageOffset.y;
578
579 meta.width = region->imageExtent.width;
580 meta.height = region->imageExtent.height;
581
582 for (j = 0; j < region->imageExtent.depth; j++) {
583 cmd_meta_set_dst_for_img(cmd, img, format,
584 meta.dst.lod, meta.dst.layer, &meta);
585
586 cmd_draw_meta(cmd, &meta);
587
588 meta.src.x += meta.width * meta.height;
589 meta.dst.layer++;
590 }
591 }
592}
593
594XGL_VOID XGLAPI intelCmdCopyImageToMemory(
595 XGL_CMD_BUFFER cmdBuffer,
596 XGL_IMAGE srcImage,
597 XGL_GPU_MEMORY destMem,
598 XGL_UINT regionCount,
599 const XGL_MEMORY_IMAGE_COPY* pRegions)
600{
601 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
602 struct intel_img *img = intel_img(srcImage);
603 struct intel_mem *mem = intel_mem(destMem);
604 struct intel_cmd_meta meta;
605 XGL_FORMAT format;
606 XGL_UINT i;
607
608 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800609 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800610
611 format = cmd_meta_img_raw_format(cmd, img->layout.format);
612 cmd_meta_set_src_for_img(cmd, img, format, XGL_IMAGE_ASPECT_COLOR, &meta);
613 cmd_meta_set_dst_for_mem(cmd, mem, format, &meta);
614
615 meta.height = 1;
616 meta.samples = 1;
617
618 for (i = 0; i < regionCount; i++) {
619 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
620 XGL_UINT j;
621
622 meta.shader_id = get_shader_id(cmd->dev, img,
623 (region->imageExtent.depth > 1));
624
625 meta.src.lod = region->imageSubresource.mipLevel;
626 meta.src.layer = region->imageSubresource.arraySlice +
627 region->imageOffset.z;
628 meta.src.x = region->imageOffset.x;
629 meta.src.y = region->imageOffset.y;
630
631 meta.dst.x = region->memOffset / icd_format_get_size(format);
632
633 meta.width = region->imageExtent.width * region->imageExtent.height;
634
635 for (j = 0; j < region->imageExtent.depth; j++) {
636 cmd_draw_meta(cmd, &meta);
637
638 meta.src.layer++;
639 meta.dst.x += meta.width;
640 }
641 }
642}
643
644XGL_VOID XGLAPI intelCmdCloneImageData(
645 XGL_CMD_BUFFER cmdBuffer,
646 XGL_IMAGE srcImage,
647 XGL_IMAGE_STATE srcImageState,
648 XGL_IMAGE destImage,
649 XGL_IMAGE_STATE destImageState)
650{
651 const struct intel_img *src = intel_img(srcImage);
652 XGL_IMAGE_COPY region;
653 XGL_UINT lv;
654
655 memset(&region, 0, sizeof(region));
656 region.srcSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
657 region.destSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
658
659 for (lv = 0; lv < src->mip_levels; lv++) {
660 region.srcSubresource.mipLevel = lv;
661 region.destSubresource.mipLevel = lv;
662
663 region.extent.width = u_minify(src->layout.width0, lv);
664 region.extent.height = u_minify(src->layout.height0, lv);
665 region.extent.depth = src->array_size;
666
667 intelCmdCopyImage(cmdBuffer, srcImage, destImage, 1, &region);
668 }
669}
670
671XGL_VOID XGLAPI intelCmdUpdateMemory(
672 XGL_CMD_BUFFER cmdBuffer,
673 XGL_GPU_MEMORY destMem,
674 XGL_GPU_SIZE destOffset,
675 XGL_GPU_SIZE dataSize,
676 const XGL_UINT32* pData)
677{
678 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
679 struct intel_mem *dst = intel_mem(destMem);
680 struct intel_cmd_meta meta;
681 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800682 uint32_t *ptr;
683 uint32_t offset;
684
Chia-I Wuf3a27252014-11-24 15:27:01 +0800685 /* must be 4-byte aligned */
686 if ((destOffset | dataSize) & 3) {
687 cmd->result = XGL_ERROR_UNKNOWN;
688 return;
689 }
690
Chia-I Wuc14d1562014-10-17 09:49:22 +0800691 /* write to dynamic state writer first */
692 offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
693 (dataSize + 3) / 4, &ptr);
694 memcpy(ptr, pData, dataSize);
695
Chia-I Wuc14d1562014-10-17 09:49:22 +0800696 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800697 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800698
Chia-I Wuf3a27252014-11-24 15:27:01 +0800699 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
700
701 meta.src.x = offset / 4;
702 meta.dst.x = destOffset / 4;
703 meta.width = dataSize / 4;
704 meta.height = 1;
705 meta.samples = 1;
706
707 /*
708 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to be 16
709 */
710 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
711 format.numericFormat = XGL_NUM_FMT_UINT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800712
713 cmd_meta_set_src_for_writer(cmd, INTEL_CMD_WRITER_STATE,
714 offset + dataSize, format, &meta);
715 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
716
Chia-I Wuc14d1562014-10-17 09:49:22 +0800717 cmd_draw_meta(cmd, &meta);
718}
719
720XGL_VOID XGLAPI intelCmdFillMemory(
721 XGL_CMD_BUFFER cmdBuffer,
722 XGL_GPU_MEMORY destMem,
723 XGL_GPU_SIZE destOffset,
724 XGL_GPU_SIZE fillSize,
725 XGL_UINT32 data)
726{
727 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
728 struct intel_mem *dst = intel_mem(destMem);
729 struct intel_cmd_meta meta;
730 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800731
732 /* must be 4-byte aligned */
733 if ((destOffset | fillSize) & 3) {
734 cmd->result = XGL_ERROR_UNKNOWN;
735 return;
736 }
737
738 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800739 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800740
Chia-I Wuf3a27252014-11-24 15:27:01 +0800741 meta.shader_id = INTEL_DEV_META_VS_FILL_MEM;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800742
743 meta.clear_val[0] = data;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800744
Chia-I Wuf3a27252014-11-24 15:27:01 +0800745 meta.dst.x = destOffset / 4;
746 meta.width = fillSize / 4;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800747 meta.height = 1;
748 meta.samples = 1;
749
Chia-I Wuf3a27252014-11-24 15:27:01 +0800750 /*
751 * INTEL_DEV_META_VS_FILL_MEM is untyped but expects the stride to be 16
752 */
753 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
754 format.numericFormat = XGL_NUM_FMT_UINT;
755
756 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
757
Chia-I Wuc14d1562014-10-17 09:49:22 +0800758 cmd_draw_meta(cmd, &meta);
759}
760
761static void cmd_meta_clear_image(struct intel_cmd *cmd,
762 struct intel_img *img,
763 XGL_FORMAT format,
764 struct intel_cmd_meta *meta,
765 const XGL_IMAGE_SUBRESOURCE_RANGE *range)
766{
767 XGL_UINT mip_levels, array_size;
768 XGL_UINT i, j;
769
770 if (range->baseMipLevel >= img->mip_levels ||
771 range->baseArraySlice >= img->array_size)
772 return;
773
774 mip_levels = img->mip_levels - range->baseMipLevel;
775 if (mip_levels > range->mipLevels)
776 mip_levels = range->mipLevels;
777
778 array_size = img->array_size - range->baseArraySlice;
779 if (array_size > range->arraySize)
780 array_size = range->arraySize;
781
Chia-I Wuc14d1562014-10-17 09:49:22 +0800782 for (i = 0; i < mip_levels; i++) {
Chia-I Wufaaed472014-10-28 14:17:43 +0800783 meta->dst.lod = range->baseMipLevel + i;
784 meta->dst.layer = range->baseArraySlice;
785
Chia-I Wuc14d1562014-10-17 09:49:22 +0800786 meta->width = u_minify(img->layout.width0, meta->dst.lod);
787 meta->height = u_minify(img->layout.height0, meta->dst.lod);
788
789 for (j = 0; j < array_size; j++) {
790 if (range->aspect == XGL_IMAGE_ASPECT_COLOR) {
791 cmd_meta_set_dst_for_img(cmd, img, format,
792 meta->dst.lod, meta->dst.layer, meta);
793
794 cmd_draw_meta(cmd, meta);
795 } else {
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800796 cmd_meta_set_ds_view(cmd, img, meta->dst.lod,
Chia-I Wuc14d1562014-10-17 09:49:22 +0800797 meta->dst.layer, meta);
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800798 cmd_meta_set_ds_state(cmd, range->aspect,
799 meta->clear_val[1], meta);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800800
801 cmd_draw_meta(cmd, meta);
802
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800803 intel_ds_view_destroy(meta->ds.view);
804 intel_ds_state_destroy(meta->ds.state);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800805 }
806
807 meta->dst.layer++;
808 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800809 }
810}
811
812XGL_VOID XGLAPI intelCmdClearColorImage(
813 XGL_CMD_BUFFER cmdBuffer,
814 XGL_IMAGE image,
815 const XGL_FLOAT color[4],
816 XGL_UINT rangeCount,
817 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
818{
819 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
820 struct intel_img *img = intel_img(image);
821 struct intel_cmd_meta meta;
822 XGL_UINT i;
823
824 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800825 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800826
827 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
828 meta.samples = img->samples;
829
830 meta.clear_val[0] = u_fui(color[0]);
831 meta.clear_val[1] = u_fui(color[1]);
832 meta.clear_val[2] = u_fui(color[2]);
833 meta.clear_val[3] = u_fui(color[3]);
834
835 for (i = 0; i < rangeCount; i++) {
836 cmd_meta_clear_image(cmd, img, img->layout.format,
837 &meta, &pRanges[i]);
838 }
839}
840
841XGL_VOID XGLAPI intelCmdClearColorImageRaw(
842 XGL_CMD_BUFFER cmdBuffer,
843 XGL_IMAGE image,
844 const XGL_UINT32 color[4],
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_FORMAT format;
852 XGL_UINT i;
853
854 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800855 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800856
857 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
858 meta.samples = img->samples;
859
860 meta.clear_val[0] = color[0];
861 meta.clear_val[1] = color[1];
862 meta.clear_val[2] = color[2];
863 meta.clear_val[3] = color[3];
864
865 format = cmd_meta_img_raw_format(cmd, img->layout.format);
866
867 for (i = 0; i < rangeCount; i++)
868 cmd_meta_clear_image(cmd, img, format, &meta, &pRanges[i]);
869}
870
871XGL_VOID XGLAPI intelCmdClearDepthStencil(
872 XGL_CMD_BUFFER cmdBuffer,
873 XGL_IMAGE image,
874 XGL_FLOAT depth,
875 XGL_UINT32 stencil,
876 XGL_UINT rangeCount,
877 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
878{
879 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
880 struct intel_img *img = intel_img(image);
881 struct intel_cmd_meta meta;
882 XGL_UINT i;
883
884 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800885 meta.mode = INTEL_CMD_META_DEPTH_STENCIL_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800886
887 meta.shader_id = INTEL_DEV_META_FS_CLEAR_DEPTH;
888 meta.samples = img->samples;
889
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800890 meta.clear_val[0] = u_fui(depth);
891 meta.clear_val[1] = stencil;
892
Chia-I Wuc14d1562014-10-17 09:49:22 +0800893 for (i = 0; i < rangeCount; i++) {
894 const XGL_IMAGE_SUBRESOURCE_RANGE *range = &pRanges[i];
895
Chia-I Wuc14d1562014-10-17 09:49:22 +0800896 cmd_meta_clear_image(cmd, img, img->layout.format,
897 &meta, range);
898 }
899}
900
901XGL_VOID XGLAPI intelCmdResolveImage(
902 XGL_CMD_BUFFER cmdBuffer,
903 XGL_IMAGE srcImage,
904 XGL_IMAGE destImage,
905 XGL_UINT rectCount,
906 const XGL_IMAGE_RESOLVE* pRects)
907{
908 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
909 struct intel_img *src = intel_img(srcImage);
910 struct intel_img *dst = intel_img(destImage);
911 struct intel_cmd_meta meta;
912 XGL_FORMAT format;
913 XGL_UINT i;
914
915 if (src->samples <= 1 || dst->samples > 1 ||
916 !icd_format_is_equal(src->layout.format, dst->layout.format)) {
917 cmd->result = XGL_ERROR_UNKNOWN;
918 return;
919 }
920
921 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800922 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800923
924 switch (src->samples) {
925 case 2:
926 default:
927 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_2X;
928 break;
929 case 4:
930 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_4X;
931 break;
932 case 8:
933 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_8X;
934 break;
935 case 16:
936 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_16X;
937 break;
938 }
939
940 meta.samples = 1;
941
942 format = cmd_meta_img_raw_format(cmd, src->layout.format);
943 cmd_meta_set_src_for_img(cmd, src, format, XGL_IMAGE_ASPECT_COLOR, &meta);
944
945 for (i = 0; i < rectCount; i++) {
946 const XGL_IMAGE_RESOLVE *rect = &pRects[i];
947
948 meta.src.lod = rect->srcSubresource.mipLevel;
949 meta.src.layer = rect->srcSubresource.arraySlice;
950 meta.src.x = rect->srcOffset.x;
951 meta.src.y = rect->srcOffset.y;
952
953 meta.dst.lod = rect->destSubresource.mipLevel;
954 meta.dst.layer = rect->destSubresource.arraySlice;
955 meta.dst.x = rect->destOffset.x;
956 meta.dst.y = rect->destOffset.y;
957
958 meta.width = rect->extent.width;
959 meta.height = rect->extent.height;
960
961 cmd_meta_set_dst_for_img(cmd, dst, format,
962 meta.dst.lod, meta.dst.layer, &meta);
963
964 cmd_draw_meta(cmd, &meta);
965 }
966}