blob: f59e64fa4650d8828132e48370a6ecf4fd19b9ba [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
Chia-I Wubc7a30c2014-12-13 15:54:10 +080050 /*
51 * We do not rely on the hardware to avoid out-of-bound access. But we do
52 * not want the hardware to ignore the last element either.
53 */
54 if (info.range % info.stride)
55 info.range += info.stride - (info.range % info.stride);
56
Chia-I Wuc14d1562014-10-17 09:49:22 +080057 intel_mem_view_init(view, cmd->dev, &info);
58}
59
60static void cmd_meta_set_src_for_mem(struct intel_cmd *cmd,
61 const struct intel_mem *mem,
62 XGL_FORMAT format,
63 struct intel_cmd_meta *meta)
64{
65 struct intel_mem_view view;
66
67 cmd_meta_init_mem_view(cmd, (XGL_GPU_MEMORY) mem, mem->size, format,
68 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
69
70 meta->src.valid = true;
71
72 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
73 meta->src.surface_len = view.cmd_len;
74
75 meta->src.reloc_target = (intptr_t) mem->bo;
76 meta->src.reloc_offset = 0;
77 meta->src.reloc_flags = 0;
78}
79
80static void cmd_meta_set_dst_for_mem(struct intel_cmd *cmd,
81 const struct intel_mem *mem,
82 XGL_FORMAT format,
83 struct intel_cmd_meta *meta)
84{
85 struct intel_mem_view view;
86
87 cmd_meta_init_mem_view(cmd, (XGL_GPU_MEMORY) mem, mem->size, format,
88 XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY, &view);
89
90 meta->dst.valid = true;
91
92 memcpy(meta->dst.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
93 meta->dst.surface_len = view.cmd_len;
94
95 meta->dst.reloc_target = (intptr_t) mem->bo;
96 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +080097 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +080098}
99
100static void cmd_meta_set_src_for_img(struct intel_cmd *cmd,
101 const struct intel_img *img,
102 XGL_FORMAT format,
103 XGL_IMAGE_ASPECT aspect,
104 struct intel_cmd_meta *meta)
105{
106 XGL_IMAGE_VIEW_CREATE_INFO info;
107 struct intel_img_view *view;
108 XGL_RESULT ret;
109
110 memset(&info, 0, sizeof(info));
111 info.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
112 info.image = (XGL_IMAGE) img;
113
114 switch (img->type) {
115 case XGL_IMAGE_1D:
116 info.viewType = XGL_IMAGE_VIEW_1D;
117 break;
118 case XGL_IMAGE_2D:
119 info.viewType = XGL_IMAGE_VIEW_2D;
120 break;
121 case XGL_IMAGE_3D:
122 info.viewType = XGL_IMAGE_VIEW_3D;
123 break;
124 default:
125 break;
126 }
127
128 info.format = format;
129 info.channels.r = XGL_CHANNEL_SWIZZLE_R;
130 info.channels.g = XGL_CHANNEL_SWIZZLE_G;
131 info.channels.b = XGL_CHANNEL_SWIZZLE_B;
132 info.channels.a = XGL_CHANNEL_SWIZZLE_A;
133 info.subresourceRange.aspect = aspect;
134 info.subresourceRange.baseMipLevel = 0;
135 info.subresourceRange.mipLevels = XGL_LAST_MIP_OR_SLICE;
136 info.subresourceRange.baseArraySlice = 0;
137 info.subresourceRange.arraySize = XGL_LAST_MIP_OR_SLICE;
138
139 ret = intel_img_view_create(cmd->dev, &info, &view);
140 if (ret != XGL_SUCCESS) {
141 cmd->result = ret;
142 return;
143 }
144
145 meta->src.valid = true;
146
147 memcpy(meta->src.surface, view->cmd,
148 sizeof(view->cmd[0]) * view->cmd_len);
149 meta->src.surface_len = view->cmd_len;
150
151 meta->src.reloc_target = (intptr_t) img->obj.mem->bo;
152 meta->src.reloc_offset = 0;
153 meta->src.reloc_flags = 0;
154
155 intel_img_view_destroy(view);
156}
157
Chia-I Wu83084ba2014-12-04 12:49:52 +0800158static void cmd_meta_adjust_compressed_dst(struct intel_cmd *cmd,
159 const struct intel_img *img,
160 struct intel_cmd_meta *meta)
161{
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800162 XGL_INT w, h, layer;
163 unsigned x_offset, y_offset;
Chia-I Wu83084ba2014-12-04 12:49:52 +0800164
165 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
166 w = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_WIDTH);
167 h = GEN_EXTRACT(meta->dst.surface[2], GEN7_SURFACE_DW2_HEIGHT);
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800168 layer = GEN_EXTRACT(meta->dst.surface[4],
169 GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800170 } else {
171 w = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_WIDTH);
172 h = GEN_EXTRACT(meta->dst.surface[2], GEN6_SURFACE_DW2_HEIGHT);
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800173 layer = GEN_EXTRACT(meta->dst.surface[4],
174 GEN6_SURFACE_DW4_MIN_ARRAY_ELEMENT);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800175 }
176
177 /* note that the width/height fields have the real values minus 1 */
178 w = (w + img->layout.block_width) / img->layout.block_width - 1;
179 h = (h + img->layout.block_height) / img->layout.block_height - 1;
180
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800181 /* adjust width and height */
Chia-I Wu83084ba2014-12-04 12:49:52 +0800182 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800183 meta->dst.surface[2] &= ~(GEN7_SURFACE_DW2_WIDTH__MASK |
184 GEN7_SURFACE_DW2_HEIGHT__MASK);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800185 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN7_SURFACE_DW2_WIDTH) |
186 GEN_SHIFT32(h, GEN7_SURFACE_DW2_HEIGHT);
187 } else {
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800188 meta->dst.surface[2] &= ~(GEN6_SURFACE_DW2_WIDTH__MASK |
189 GEN6_SURFACE_DW2_HEIGHT__MASK);
Chia-I Wu83084ba2014-12-04 12:49:52 +0800190 meta->dst.surface[2] |= GEN_SHIFT32(w, GEN6_SURFACE_DW2_WIDTH) |
191 GEN_SHIFT32(h, GEN6_SURFACE_DW2_HEIGHT);
192 }
Chia-I Wu0d8c2ee2014-12-04 13:06:45 +0800193
194 if (!layer)
195 return;
196
197 meta->dst.reloc_offset = intel_layout_get_slice_tile_offset(&img->layout,
198 0, layer, &x_offset, &y_offset);
199
200 /*
201 * The lower 2 bits (or 1 bit for Y) are missing. This may be a problem
202 * for small images (16x16 or smaller). We will need to adjust the
203 * drawing rectangle instead.
204 */
205 x_offset = (x_offset / img->layout.block_width) >> 2;
206 y_offset = (y_offset / img->layout.block_height) >> 1;
207
208 /* adjust min array element and X/Y offsets */
209 if (cmd_gen(cmd) >= INTEL_GEN(7)) {
210 meta->dst.surface[4] &= ~GEN7_SURFACE_DW4_MIN_ARRAY_ELEMENT__MASK;
211 meta->dst.surface[5] |= GEN_SHIFT32(x_offset, GEN7_SURFACE_DW5_X_OFFSET) |
212 GEN_SHIFT32(y_offset, GEN7_SURFACE_DW5_Y_OFFSET);
213 } else {
214 meta->dst.surface[4] &= ~GEN6_SURFACE_DW4_MIN_ARRAY_ELEMENT__MASK;
215 meta->dst.surface[5] |= GEN_SHIFT32(x_offset, GEN6_SURFACE_DW5_X_OFFSET) |
216 GEN_SHIFT32(y_offset, GEN6_SURFACE_DW5_Y_OFFSET);
217 }
Chia-I Wu83084ba2014-12-04 12:49:52 +0800218}
219
Chia-I Wuc14d1562014-10-17 09:49:22 +0800220static void cmd_meta_set_dst_for_img(struct intel_cmd *cmd,
221 const struct intel_img *img,
222 XGL_FORMAT format,
223 XGL_UINT lod, XGL_UINT layer,
224 struct intel_cmd_meta *meta)
225{
226 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO info;
227 struct intel_rt_view *rt;
228 XGL_RESULT ret;
229
230 memset(&info, 0, sizeof(info));
231 info.sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO;
232 info.image = (XGL_IMAGE) img;
233 info.format = format;
234 info.mipLevel = lod;
235 info.baseArraySlice = layer;
236 info.arraySize = 1;
237
238 ret = intel_rt_view_create(cmd->dev, &info, &rt);
239 if (ret != XGL_SUCCESS) {
240 cmd->result = ret;
241 return;
242 }
243
244 meta->dst.valid = true;
245
246 memcpy(meta->dst.surface, rt->cmd, sizeof(rt->cmd[0]) * rt->cmd_len);
247 meta->dst.surface_len = rt->cmd_len;
248
249 meta->dst.reloc_target = (intptr_t) img->obj.mem->bo;
250 meta->dst.reloc_offset = 0;
Chia-I Wuc5e2ae32014-11-25 11:00:12 +0800251 meta->dst.reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800252
Chia-I Wu83084ba2014-12-04 12:49:52 +0800253 if (icd_format_is_compressed(img->layout.format))
254 cmd_meta_adjust_compressed_dst(cmd, img, meta);
255
Chia-I Wuc14d1562014-10-17 09:49:22 +0800256 intel_rt_view_destroy(rt);
257}
258
259static void cmd_meta_set_src_for_writer(struct intel_cmd *cmd,
260 enum intel_cmd_writer_type writer,
261 XGL_GPU_SIZE size,
262 XGL_FORMAT format,
263 struct intel_cmd_meta *meta)
264{
265 struct intel_mem_view view;
266
267 cmd_meta_init_mem_view(cmd, XGL_NULL_HANDLE, size, format,
268 XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY, &view);
269
270 meta->src.valid = true;
271
272 memcpy(meta->src.surface, view.cmd, sizeof(view.cmd[0]) * view.cmd_len);
273 meta->src.surface_len = view.cmd_len;
274
275 meta->src.reloc_target = (intptr_t) writer;
276 meta->src.reloc_offset = 0;
277 meta->src.reloc_flags = INTEL_CMD_RELOC_TARGET_IS_WRITER;
278}
279
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800280static void cmd_meta_set_ds_view(struct intel_cmd *cmd,
281 const struct intel_img *img,
282 XGL_UINT lod, XGL_UINT layer,
283 struct intel_cmd_meta *meta)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800284{
285 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO info;
286 struct intel_ds_view *ds;
287 XGL_RESULT ret;
288
289 memset(&info, 0, sizeof(info));
290 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
291 info.image = (XGL_IMAGE) img;
292 info.mipLevel = lod;
293 info.baseArraySlice = layer;
294 info.arraySize = 1;
295
296 ret = intel_ds_view_create(cmd->dev, &info, &ds);
297 if (ret != XGL_SUCCESS) {
298 cmd->result = ret;
299 return;
300 }
301
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800302 meta->ds.view = ds;
303}
304
305static void cmd_meta_set_ds_state(struct intel_cmd *cmd,
306 XGL_IMAGE_ASPECT aspect,
307 XGL_UINT32 stencil_ref,
308 struct intel_cmd_meta *meta)
309{
310 XGL_DEPTH_STENCIL_STATE_CREATE_INFO info;
311 struct intel_ds_state *state;
312 XGL_RESULT ret;
313
314 memset(&info, 0, sizeof(info));
315 info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO;
316
317 if (aspect == XGL_IMAGE_ASPECT_DEPTH) {
318 info.depthWriteEnable = XGL_TRUE;
319 }
320 else if (aspect == XGL_IMAGE_ASPECT_STENCIL) {
321 info.stencilTestEnable = XGL_TRUE;
322 info.stencilReadMask = 0xff;
323 info.stencilWriteMask = 0xff;
324 info.front.stencilFailOp = XGL_STENCIL_OP_KEEP;
325 info.front.stencilPassOp = XGL_STENCIL_OP_REPLACE;
326 info.front.stencilDepthFailOp = XGL_STENCIL_OP_KEEP;
327 info.front.stencilFunc = XGL_COMPARE_ALWAYS;
328 info.front.stencilRef = stencil_ref;
329 info.back = info.front;
330 }
331
332 ret = intel_ds_state_create(cmd->dev, &info, &state);
333 if (ret != XGL_SUCCESS) {
334 cmd->result = ret;
335 return;
336 }
337
338 meta->ds.state = state;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800339}
340
341static enum intel_dev_meta_shader get_shader_id(const struct intel_dev *dev,
342 const struct intel_img *img,
343 bool copy_array)
344{
345 enum intel_dev_meta_shader shader_id;
346
347 switch (img->type) {
348 case XGL_IMAGE_1D:
349 shader_id = (copy_array) ?
350 INTEL_DEV_META_FS_COPY_1D_ARRAY : INTEL_DEV_META_FS_COPY_1D;
351 break;
352 case XGL_IMAGE_2D:
353 shader_id = (img->samples > 1) ? INTEL_DEV_META_FS_COPY_2D_MS :
354 (copy_array) ? INTEL_DEV_META_FS_COPY_2D_ARRAY :
355 INTEL_DEV_META_FS_COPY_2D;
356 break;
357 case XGL_IMAGE_3D:
358 default:
359 shader_id = INTEL_DEV_META_FS_COPY_2D_ARRAY;
360 break;
361 }
362
363 return shader_id;
364}
365
Chia-I Wuf3a27252014-11-24 15:27:01 +0800366static bool cmd_meta_mem_dword_aligned(const struct intel_cmd *cmd,
367 XGL_GPU_SIZE src_offset,
368 XGL_GPU_SIZE dst_offset,
369 XGL_GPU_SIZE size)
Chia-I Wuc14d1562014-10-17 09:49:22 +0800370{
Chia-I Wuf3a27252014-11-24 15:27:01 +0800371 return !((src_offset | dst_offset | size) & 0x3);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800372}
373
374static XGL_FORMAT cmd_meta_img_raw_format(const struct intel_cmd *cmd,
375 XGL_FORMAT format)
376{
377 format.numericFormat = XGL_NUM_FMT_UINT;
378
Chia-I Wuffdde352014-12-20 15:12:16 +0800379 switch (icd_format_get_size(format)) {
380 case 1:
381 format.channelFormat = XGL_CH_FMT_R8;
382 break;
383 case 2:
384 format.channelFormat = XGL_CH_FMT_R16;
385 break;
386 case 4:
387 format.channelFormat = XGL_CH_FMT_R32;
388 break;
389 case 8:
390 format.channelFormat = XGL_CH_FMT_R32G32;
391 break;
392 case 16:
393 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
394 break;
395 default:
396 assert(!"unsupported image format for raw blit op");
397 format.channelFormat = XGL_CH_FMT_UNDEFINED;
398 format.numericFormat = XGL_NUM_FMT_UNDEFINED;
399 break;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800400 }
401
402 return format;
403}
404
405XGL_VOID XGLAPI intelCmdCopyMemory(
406 XGL_CMD_BUFFER cmdBuffer,
407 XGL_GPU_MEMORY srcMem,
408 XGL_GPU_MEMORY destMem,
409 XGL_UINT regionCount,
410 const XGL_MEMORY_COPY* pRegions)
411{
412 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
413 struct intel_mem *src = intel_mem(srcMem);
414 struct intel_mem *dst = intel_mem(destMem);
415 struct intel_cmd_meta meta;
416 XGL_FORMAT format;
417 XGL_UINT i;
418
419 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800420 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800421
Chia-I Wuc14d1562014-10-17 09:49:22 +0800422 meta.height = 1;
423 meta.samples = 1;
424
425 format.channelFormat = XGL_CH_FMT_UNDEFINED;
426 format.numericFormat = XGL_NUM_FMT_UINT;
427
428 for (i = 0; i < regionCount; i++) {
429 const XGL_MEMORY_COPY *region = &pRegions[i];
430 XGL_CHANNEL_FORMAT ch;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800431
Chia-I Wuf3a27252014-11-24 15:27:01 +0800432 meta.src.x = region->srcOffset;
433 meta.dst.x = region->destOffset;
434 meta.width = region->copySize;
435
436 if (cmd_meta_mem_dword_aligned(cmd, region->srcOffset,
437 region->destOffset, region->copySize)) {
438 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
439 meta.src.x /= 4;
440 meta.dst.x /= 4;
441 meta.width /= 4;
442
443 /*
444 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to
445 * be 16
446 */
447 ch = XGL_CH_FMT_R32G32B32A32;
448 } else {
449 if (cmd_gen(cmd) == INTEL_GEN(6)) {
450 intel_dev_log(cmd->dev, XGL_DBG_MSG_ERROR,
451 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
452 "unaligned xglCmdCopyMemory unsupported");
453 cmd->result = XGL_ERROR_UNKNOWN;
454 continue;
455 }
456
457 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM_UNALIGNED;
458
459 /*
460 * INTEL_DEV_META_VS_COPY_MEM_UNALIGNED is untyped but expects the
461 * stride to be 4
462 */
463 ch = XGL_CH_FMT_R8G8B8A8;
464 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800465
466 if (format.channelFormat != ch) {
467 format.channelFormat = ch;
468
469 cmd_meta_set_src_for_mem(cmd, src, format, &meta);
470 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
471 }
472
Chia-I Wuc14d1562014-10-17 09:49:22 +0800473 cmd_draw_meta(cmd, &meta);
474 }
475}
476
477XGL_VOID XGLAPI intelCmdCopyImage(
478 XGL_CMD_BUFFER cmdBuffer,
479 XGL_IMAGE srcImage,
480 XGL_IMAGE destImage,
481 XGL_UINT regionCount,
482 const XGL_IMAGE_COPY* pRegions)
483{
484 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
485 struct intel_img *src = intel_img(srcImage);
486 struct intel_img *dst = intel_img(destImage);
487 struct intel_cmd_meta meta;
488 XGL_FORMAT raw_format;
489 bool raw_copy;
490 XGL_UINT i;
491
492 if (src->type != dst->type) {
493 cmd->result = XGL_ERROR_UNKNOWN;
494 return;
495 }
496
497 if (icd_format_is_equal(src->layout.format, dst->layout.format)) {
498 raw_copy = true;
499 raw_format = cmd_meta_img_raw_format(cmd, src->layout.format);
500 } else if (icd_format_is_compressed(src->layout.format) ||
501 icd_format_is_compressed(dst->layout.format)) {
502 cmd->result = XGL_ERROR_UNKNOWN;
503 return;
504 }
505
506 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800507 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800508
509 cmd_meta_set_src_for_img(cmd, src,
510 (raw_copy) ? raw_format : src->layout.format,
511 XGL_IMAGE_ASPECT_COLOR, &meta);
512
513 meta.samples = dst->samples;
514
515 for (i = 0; i < regionCount; i++) {
516 const XGL_IMAGE_COPY *region = &pRegions[i];
517 XGL_UINT j;
518
519 meta.shader_id = get_shader_id(cmd->dev, src,
520 (region->extent.depth > 1));
521
522 meta.src.lod = region->srcSubresource.mipLevel;
523 meta.src.layer = region->srcSubresource.arraySlice +
524 region->srcOffset.z;
525 meta.src.x = region->srcOffset.x;
526 meta.src.y = region->srcOffset.y;
527
528 meta.dst.lod = region->destSubresource.mipLevel;
529 meta.dst.layer = region->destSubresource.arraySlice +
530 region->destOffset.z;
531 meta.dst.x = region->destOffset.x;
532 meta.dst.y = region->destOffset.y;
533
534 meta.width = region->extent.width;
535 meta.height = region->extent.height;
536
537 for (j = 0; j < region->extent.depth; j++) {
538 cmd_meta_set_dst_for_img(cmd, dst,
539 (raw_copy) ? raw_format : dst->layout.format,
540 meta.dst.lod, meta.dst.layer, &meta);
541
542 cmd_draw_meta(cmd, &meta);
543
544 meta.src.layer++;
545 meta.dst.layer++;
546 }
547 }
548}
549
550XGL_VOID XGLAPI intelCmdCopyMemoryToImage(
551 XGL_CMD_BUFFER cmdBuffer,
552 XGL_GPU_MEMORY srcMem,
553 XGL_IMAGE destImage,
554 XGL_UINT regionCount,
555 const XGL_MEMORY_IMAGE_COPY* pRegions)
556{
557 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
558 struct intel_mem *mem = intel_mem(srcMem);
559 struct intel_img *img = intel_img(destImage);
560 struct intel_cmd_meta meta;
561 XGL_FORMAT format;
562 XGL_UINT i;
563
564 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800565 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800566
567 meta.shader_id = INTEL_DEV_META_FS_COPY_MEM_TO_IMG;
568 meta.samples = img->samples;
569
570 format = cmd_meta_img_raw_format(cmd, img->layout.format);
571 cmd_meta_set_src_for_mem(cmd, mem, format, &meta);
572
573 for (i = 0; i < regionCount; i++) {
574 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
575 XGL_UINT j;
576
577 meta.src.x = region->memOffset / icd_format_get_size(format);
578
579 meta.dst.lod = region->imageSubresource.mipLevel;
580 meta.dst.layer = region->imageSubresource.arraySlice +
581 region->imageOffset.z;
582 meta.dst.x = region->imageOffset.x;
583 meta.dst.y = region->imageOffset.y;
584
585 meta.width = region->imageExtent.width;
586 meta.height = region->imageExtent.height;
587
588 for (j = 0; j < region->imageExtent.depth; j++) {
589 cmd_meta_set_dst_for_img(cmd, img, format,
590 meta.dst.lod, meta.dst.layer, &meta);
591
592 cmd_draw_meta(cmd, &meta);
593
594 meta.src.x += meta.width * meta.height;
595 meta.dst.layer++;
596 }
597 }
598}
599
600XGL_VOID XGLAPI intelCmdCopyImageToMemory(
601 XGL_CMD_BUFFER cmdBuffer,
602 XGL_IMAGE srcImage,
603 XGL_GPU_MEMORY destMem,
604 XGL_UINT regionCount,
605 const XGL_MEMORY_IMAGE_COPY* pRegions)
606{
607 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
608 struct intel_img *img = intel_img(srcImage);
609 struct intel_mem *mem = intel_mem(destMem);
610 struct intel_cmd_meta meta;
Chia-I Wua44b6482014-12-20 14:58:01 +0800611 XGL_FORMAT img_format, mem_format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800612 XGL_UINT i;
613
614 memset(&meta, 0, sizeof(meta));
Chia-I Wua44b6482014-12-20 14:58:01 +0800615 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800616
Chia-I Wua44b6482014-12-20 14:58:01 +0800617 img_format = cmd_meta_img_raw_format(cmd, img->layout.format);
618 mem_format.numericFormat = XGL_NUM_FMT_UINT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800619
Chia-I Wua44b6482014-12-20 14:58:01 +0800620 /* mem_format is ignored by hw, but we derive stride from it */
621 switch (img_format.channelFormat) {
622 case XGL_CH_FMT_R8:
623 meta.shader_id = INTEL_DEV_META_VS_COPY_R8_TO_MEM;
624 mem_format.channelFormat = XGL_CH_FMT_R8G8B8A8;
625 break;
626 case XGL_CH_FMT_R16:
627 meta.shader_id = INTEL_DEV_META_VS_COPY_R16_TO_MEM;
628 mem_format.channelFormat = XGL_CH_FMT_R8G8B8A8;
629 break;
630 case XGL_CH_FMT_R32:
631 meta.shader_id = INTEL_DEV_META_VS_COPY_R32_TO_MEM;
632 mem_format.channelFormat = XGL_CH_FMT_R32G32B32A32;
633 break;
634 case XGL_CH_FMT_R32G32:
635 meta.shader_id = INTEL_DEV_META_VS_COPY_R32G32_TO_MEM;
636 mem_format.channelFormat = XGL_CH_FMT_R32G32B32A32;
637 break;
638 case XGL_CH_FMT_R32G32B32A32:
639 meta.shader_id = INTEL_DEV_META_VS_COPY_R32G32B32A32_TO_MEM;
640 mem_format.channelFormat = XGL_CH_FMT_R32G32B32A32;
641 break;
642 default:
643 break;
644 }
645
646 if (img_format.channelFormat == XGL_CH_FMT_UNDEFINED ||
647 (cmd_gen(cmd) == INTEL_GEN(6) &&
648 icd_format_get_size(img_format) < 4)) {
649 intel_dev_log(cmd->dev, XGL_DBG_MSG_ERROR,
650 XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0, 0,
651 "xglCmdCopyImageToMemory with bpp %d unsupported",
652 icd_format_get_size(img->layout.format));
653 cmd->result = XGL_ERROR_UNKNOWN;
654 return;
655 }
656
657 cmd_meta_set_src_for_img(cmd, img, img_format,
658 XGL_IMAGE_ASPECT_COLOR, &meta);
659 cmd_meta_set_dst_for_mem(cmd, mem, mem_format, &meta);
660
Chia-I Wuc14d1562014-10-17 09:49:22 +0800661 meta.samples = 1;
662
663 for (i = 0; i < regionCount; i++) {
664 const XGL_MEMORY_IMAGE_COPY *region = &pRegions[i];
665 XGL_UINT j;
666
Chia-I Wuc14d1562014-10-17 09:49:22 +0800667 meta.src.lod = region->imageSubresource.mipLevel;
668 meta.src.layer = region->imageSubresource.arraySlice +
669 region->imageOffset.z;
670 meta.src.x = region->imageOffset.x;
671 meta.src.y = region->imageOffset.y;
672
Chia-I Wua44b6482014-12-20 14:58:01 +0800673 meta.dst.x = region->memOffset / icd_format_get_size(img_format);
674 meta.width = region->imageExtent.width;
675 meta.height = region->imageExtent.height;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800676
677 for (j = 0; j < region->imageExtent.depth; j++) {
678 cmd_draw_meta(cmd, &meta);
679
680 meta.src.layer++;
Chia-I Wua44b6482014-12-20 14:58:01 +0800681 meta.dst.x += meta.width * meta.height;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800682 }
683 }
684}
685
686XGL_VOID XGLAPI intelCmdCloneImageData(
687 XGL_CMD_BUFFER cmdBuffer,
688 XGL_IMAGE srcImage,
689 XGL_IMAGE_STATE srcImageState,
690 XGL_IMAGE destImage,
691 XGL_IMAGE_STATE destImageState)
692{
Chia-I Wud788fc62014-12-22 14:24:11 +0800693 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
694 struct intel_img *src = intel_img(srcImage);
695 struct intel_img *dst = intel_img(destImage);
696 XGL_MEMORY_COPY region;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800697
698 memset(&region, 0, sizeof(region));
Chia-I Wud788fc62014-12-22 14:24:11 +0800699 region.copySize = src->obj.mem->size;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800700
Chia-I Wud788fc62014-12-22 14:24:11 +0800701 cmd_batch_flush(cmd, GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH);
702 intelCmdCopyMemory(cmdBuffer, (XGL_GPU_MEMORY) src->obj.mem,
703 (XGL_GPU_MEMORY) dst->obj.mem, 1, &region);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800704}
705
706XGL_VOID XGLAPI intelCmdUpdateMemory(
707 XGL_CMD_BUFFER cmdBuffer,
708 XGL_GPU_MEMORY destMem,
709 XGL_GPU_SIZE destOffset,
710 XGL_GPU_SIZE dataSize,
711 const XGL_UINT32* pData)
712{
713 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
714 struct intel_mem *dst = intel_mem(destMem);
715 struct intel_cmd_meta meta;
716 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800717 uint32_t *ptr;
718 uint32_t offset;
719
Chia-I Wuf3a27252014-11-24 15:27:01 +0800720 /* must be 4-byte aligned */
721 if ((destOffset | dataSize) & 3) {
722 cmd->result = XGL_ERROR_UNKNOWN;
723 return;
724 }
725
Chia-I Wuc14d1562014-10-17 09:49:22 +0800726 /* write to dynamic state writer first */
727 offset = cmd_state_pointer(cmd, INTEL_CMD_ITEM_BLOB, 32,
728 (dataSize + 3) / 4, &ptr);
729 memcpy(ptr, pData, dataSize);
730
Chia-I Wuc14d1562014-10-17 09:49:22 +0800731 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800732 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800733
Chia-I Wuf3a27252014-11-24 15:27:01 +0800734 meta.shader_id = INTEL_DEV_META_VS_COPY_MEM;
735
736 meta.src.x = offset / 4;
737 meta.dst.x = destOffset / 4;
738 meta.width = dataSize / 4;
739 meta.height = 1;
740 meta.samples = 1;
741
742 /*
743 * INTEL_DEV_META_VS_COPY_MEM is untyped but expects the stride to be 16
744 */
745 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
746 format.numericFormat = XGL_NUM_FMT_UINT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800747
748 cmd_meta_set_src_for_writer(cmd, INTEL_CMD_WRITER_STATE,
749 offset + dataSize, format, &meta);
750 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
751
Chia-I Wuc14d1562014-10-17 09:49:22 +0800752 cmd_draw_meta(cmd, &meta);
753}
754
755XGL_VOID XGLAPI intelCmdFillMemory(
756 XGL_CMD_BUFFER cmdBuffer,
757 XGL_GPU_MEMORY destMem,
758 XGL_GPU_SIZE destOffset,
759 XGL_GPU_SIZE fillSize,
760 XGL_UINT32 data)
761{
762 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
763 struct intel_mem *dst = intel_mem(destMem);
764 struct intel_cmd_meta meta;
765 XGL_FORMAT format;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800766
767 /* must be 4-byte aligned */
768 if ((destOffset | fillSize) & 3) {
769 cmd->result = XGL_ERROR_UNKNOWN;
770 return;
771 }
772
773 memset(&meta, 0, sizeof(meta));
Chia-I Wuf3a27252014-11-24 15:27:01 +0800774 meta.mode = INTEL_CMD_META_VS_POINTS;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800775
Chia-I Wuf3a27252014-11-24 15:27:01 +0800776 meta.shader_id = INTEL_DEV_META_VS_FILL_MEM;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800777
778 meta.clear_val[0] = data;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800779
Chia-I Wuf3a27252014-11-24 15:27:01 +0800780 meta.dst.x = destOffset / 4;
781 meta.width = fillSize / 4;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800782 meta.height = 1;
783 meta.samples = 1;
784
Chia-I Wuf3a27252014-11-24 15:27:01 +0800785 /*
786 * INTEL_DEV_META_VS_FILL_MEM is untyped but expects the stride to be 16
787 */
788 format.channelFormat = XGL_CH_FMT_R32G32B32A32;
789 format.numericFormat = XGL_NUM_FMT_UINT;
790
791 cmd_meta_set_dst_for_mem(cmd, dst, format, &meta);
792
Chia-I Wuc14d1562014-10-17 09:49:22 +0800793 cmd_draw_meta(cmd, &meta);
794}
795
796static void cmd_meta_clear_image(struct intel_cmd *cmd,
797 struct intel_img *img,
798 XGL_FORMAT format,
799 struct intel_cmd_meta *meta,
800 const XGL_IMAGE_SUBRESOURCE_RANGE *range)
801{
802 XGL_UINT mip_levels, array_size;
803 XGL_UINT i, j;
804
805 if (range->baseMipLevel >= img->mip_levels ||
806 range->baseArraySlice >= img->array_size)
807 return;
808
809 mip_levels = img->mip_levels - range->baseMipLevel;
810 if (mip_levels > range->mipLevels)
811 mip_levels = range->mipLevels;
812
813 array_size = img->array_size - range->baseArraySlice;
814 if (array_size > range->arraySize)
815 array_size = range->arraySize;
816
Chia-I Wuc14d1562014-10-17 09:49:22 +0800817 for (i = 0; i < mip_levels; i++) {
Chia-I Wufaaed472014-10-28 14:17:43 +0800818 meta->dst.lod = range->baseMipLevel + i;
819 meta->dst.layer = range->baseArraySlice;
820
Chia-I Wuc14d1562014-10-17 09:49:22 +0800821 meta->width = u_minify(img->layout.width0, meta->dst.lod);
822 meta->height = u_minify(img->layout.height0, meta->dst.lod);
823
824 for (j = 0; j < array_size; j++) {
825 if (range->aspect == XGL_IMAGE_ASPECT_COLOR) {
826 cmd_meta_set_dst_for_img(cmd, img, format,
827 meta->dst.lod, meta->dst.layer, meta);
828
829 cmd_draw_meta(cmd, meta);
830 } else {
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800831 cmd_meta_set_ds_view(cmd, img, meta->dst.lod,
Chia-I Wuc14d1562014-10-17 09:49:22 +0800832 meta->dst.layer, meta);
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800833 cmd_meta_set_ds_state(cmd, range->aspect,
834 meta->clear_val[1], meta);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800835
836 cmd_draw_meta(cmd, meta);
837
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800838 intel_ds_view_destroy(meta->ds.view);
839 intel_ds_state_destroy(meta->ds.state);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800840 }
841
842 meta->dst.layer++;
843 }
Chia-I Wuc14d1562014-10-17 09:49:22 +0800844 }
845}
846
847XGL_VOID XGLAPI intelCmdClearColorImage(
848 XGL_CMD_BUFFER cmdBuffer,
849 XGL_IMAGE image,
850 const XGL_FLOAT color[4],
851 XGL_UINT rangeCount,
852 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
853{
854 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
855 struct intel_img *img = intel_img(image);
856 struct intel_cmd_meta meta;
857 XGL_UINT i;
858
859 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800860 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800861
862 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
863 meta.samples = img->samples;
864
865 meta.clear_val[0] = u_fui(color[0]);
866 meta.clear_val[1] = u_fui(color[1]);
867 meta.clear_val[2] = u_fui(color[2]);
868 meta.clear_val[3] = u_fui(color[3]);
869
870 for (i = 0; i < rangeCount; i++) {
871 cmd_meta_clear_image(cmd, img, img->layout.format,
872 &meta, &pRanges[i]);
873 }
874}
875
876XGL_VOID XGLAPI intelCmdClearColorImageRaw(
877 XGL_CMD_BUFFER cmdBuffer,
878 XGL_IMAGE image,
879 const XGL_UINT32 color[4],
880 XGL_UINT rangeCount,
881 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
882{
883 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
884 struct intel_img *img = intel_img(image);
885 struct intel_cmd_meta meta;
886 XGL_FORMAT format;
887 XGL_UINT i;
888
889 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800890 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800891
892 meta.shader_id = INTEL_DEV_META_FS_CLEAR_COLOR;
893 meta.samples = img->samples;
894
Chia-I Wuffdde352014-12-20 15:12:16 +0800895 icd_format_get_raw_value(img->layout.format, color, meta.clear_val);
Chia-I Wuc14d1562014-10-17 09:49:22 +0800896 format = cmd_meta_img_raw_format(cmd, img->layout.format);
897
898 for (i = 0; i < rangeCount; i++)
899 cmd_meta_clear_image(cmd, img, format, &meta, &pRanges[i]);
900}
901
902XGL_VOID XGLAPI intelCmdClearDepthStencil(
903 XGL_CMD_BUFFER cmdBuffer,
904 XGL_IMAGE image,
905 XGL_FLOAT depth,
906 XGL_UINT32 stencil,
907 XGL_UINT rangeCount,
908 const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
909{
910 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
911 struct intel_img *img = intel_img(image);
912 struct intel_cmd_meta meta;
913 XGL_UINT i;
914
915 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800916 meta.mode = INTEL_CMD_META_DEPTH_STENCIL_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800917
918 meta.shader_id = INTEL_DEV_META_FS_CLEAR_DEPTH;
919 meta.samples = img->samples;
920
Chia-I Wu429a0aa2014-10-24 11:57:51 +0800921 meta.clear_val[0] = u_fui(depth);
922 meta.clear_val[1] = stencil;
923
Chia-I Wuc14d1562014-10-17 09:49:22 +0800924 for (i = 0; i < rangeCount; i++) {
925 const XGL_IMAGE_SUBRESOURCE_RANGE *range = &pRanges[i];
926
Chia-I Wuc14d1562014-10-17 09:49:22 +0800927 cmd_meta_clear_image(cmd, img, img->layout.format,
928 &meta, range);
929 }
930}
931
932XGL_VOID XGLAPI intelCmdResolveImage(
933 XGL_CMD_BUFFER cmdBuffer,
934 XGL_IMAGE srcImage,
935 XGL_IMAGE destImage,
936 XGL_UINT rectCount,
937 const XGL_IMAGE_RESOLVE* pRects)
938{
939 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
940 struct intel_img *src = intel_img(srcImage);
941 struct intel_img *dst = intel_img(destImage);
942 struct intel_cmd_meta meta;
943 XGL_FORMAT format;
944 XGL_UINT i;
945
946 if (src->samples <= 1 || dst->samples > 1 ||
947 !icd_format_is_equal(src->layout.format, dst->layout.format)) {
948 cmd->result = XGL_ERROR_UNKNOWN;
949 return;
950 }
951
952 memset(&meta, 0, sizeof(meta));
Chia-I Wu29e6f502014-11-24 14:27:29 +0800953 meta.mode = INTEL_CMD_META_FS_RECT;
Chia-I Wuc14d1562014-10-17 09:49:22 +0800954
955 switch (src->samples) {
956 case 2:
957 default:
958 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_2X;
959 break;
960 case 4:
961 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_4X;
962 break;
963 case 8:
964 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_8X;
965 break;
966 case 16:
967 meta.shader_id = INTEL_DEV_META_FS_RESOLVE_16X;
968 break;
969 }
970
971 meta.samples = 1;
972
973 format = cmd_meta_img_raw_format(cmd, src->layout.format);
974 cmd_meta_set_src_for_img(cmd, src, format, XGL_IMAGE_ASPECT_COLOR, &meta);
975
976 for (i = 0; i < rectCount; i++) {
977 const XGL_IMAGE_RESOLVE *rect = &pRects[i];
978
979 meta.src.lod = rect->srcSubresource.mipLevel;
980 meta.src.layer = rect->srcSubresource.arraySlice;
981 meta.src.x = rect->srcOffset.x;
982 meta.src.y = rect->srcOffset.y;
983
984 meta.dst.lod = rect->destSubresource.mipLevel;
985 meta.dst.layer = rect->destSubresource.arraySlice;
986 meta.dst.x = rect->destOffset.x;
987 meta.dst.y = rect->destOffset.y;
988
989 meta.width = rect->extent.width;
990 meta.height = rect->extent.height;
991
992 cmd_meta_set_dst_for_img(cmd, dst, format,
993 meta.dst.lod, meta.dst.layer, &meta);
994
995 cmd_draw_meta(cmd, &meta);
996 }
997}