2 * Copyright © 2017 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * @file iris_resource.c
27 * Resources are images, buffers, and other objects used by the GPU.
29 * XXX: explain resources
34 #include "pipe/p_defines.h"
35 #include "pipe/p_state.h"
36 #include "pipe/p_context.h"
37 #include "pipe/p_screen.h"
38 #include "util/os_memory.h"
39 #include "util/u_cpu_detect.h"
40 #include "util/u_inlines.h"
41 #include "util/u_format.h"
42 #include "util/u_transfer.h"
43 #include "util/u_upload_mgr.h"
44 #include "util/ralloc.h"
45 #include "iris_batch.h"
46 #include "iris_context.h"
47 #include "iris_resource.h"
48 #include "iris_screen.h"
49 #include "intel/common/gen_debug.h"
51 #include "drm-uapi/drm_fourcc.h"
52 #include "drm-uapi/i915_drm.h"
54 // XXX: u_transfer_helper...for separate stencil...
56 enum modifier_priority
{
57 MODIFIER_PRIORITY_INVALID
= 0,
58 MODIFIER_PRIORITY_LINEAR
,
61 MODIFIER_PRIORITY_Y_CCS
,
64 static const uint64_t priority_to_modifier
[] = {
65 [MODIFIER_PRIORITY_INVALID
] = DRM_FORMAT_MOD_INVALID
,
66 [MODIFIER_PRIORITY_LINEAR
] = DRM_FORMAT_MOD_LINEAR
,
67 [MODIFIER_PRIORITY_X
] = I915_FORMAT_MOD_X_TILED
,
68 [MODIFIER_PRIORITY_Y
] = I915_FORMAT_MOD_Y_TILED
,
69 [MODIFIER_PRIORITY_Y_CCS
] = I915_FORMAT_MOD_Y_TILED_CCS
,
73 modifier_is_supported(const struct gen_device_info
*devinfo
,
76 /* XXX: do something real */
78 case I915_FORMAT_MOD_Y_TILED
:
79 case I915_FORMAT_MOD_X_TILED
:
80 case DRM_FORMAT_MOD_LINEAR
:
82 case I915_FORMAT_MOD_Y_TILED_CCS
:
83 case DRM_FORMAT_MOD_INVALID
:
90 select_best_modifier(struct gen_device_info
*devinfo
,
91 const uint64_t *modifiers
,
94 enum modifier_priority prio
= MODIFIER_PRIORITY_INVALID
;
96 for (int i
= 0; i
< count
; i
++) {
97 if (!modifier_is_supported(devinfo
, modifiers
[i
]))
100 switch (modifiers
[i
]) {
101 case I915_FORMAT_MOD_Y_TILED_CCS
:
102 prio
= MAX2(prio
, MODIFIER_PRIORITY_Y_CCS
);
104 case I915_FORMAT_MOD_Y_TILED
:
105 prio
= MAX2(prio
, MODIFIER_PRIORITY_Y
);
107 case I915_FORMAT_MOD_X_TILED
:
108 prio
= MAX2(prio
, MODIFIER_PRIORITY_X
);
110 case DRM_FORMAT_MOD_LINEAR
:
111 prio
= MAX2(prio
, MODIFIER_PRIORITY_LINEAR
);
113 case DRM_FORMAT_MOD_INVALID
:
119 return priority_to_modifier
[prio
];
122 static enum isl_surf_dim
123 target_to_isl_surf_dim(enum pipe_texture_target target
)
127 case PIPE_TEXTURE_1D
:
128 case PIPE_TEXTURE_1D_ARRAY
:
129 return ISL_SURF_DIM_1D
;
130 case PIPE_TEXTURE_2D
:
131 case PIPE_TEXTURE_CUBE
:
132 case PIPE_TEXTURE_RECT
:
133 case PIPE_TEXTURE_2D_ARRAY
:
134 case PIPE_TEXTURE_CUBE_ARRAY
:
135 return ISL_SURF_DIM_2D
;
136 case PIPE_TEXTURE_3D
:
137 return ISL_SURF_DIM_3D
;
138 case PIPE_MAX_TEXTURE_TYPES
:
141 unreachable("invalid texture type");
144 static isl_surf_usage_flags_t
145 pipe_bind_to_isl_usage(unsigned bindings
)
147 isl_surf_usage_flags_t usage
= 0;
149 if (bindings
& PIPE_BIND_RENDER_TARGET
)
150 usage
|= ISL_SURF_USAGE_RENDER_TARGET_BIT
;
152 if (bindings
& PIPE_BIND_SAMPLER_VIEW
)
153 usage
|= ISL_SURF_USAGE_TEXTURE_BIT
;
155 if (bindings
& (PIPE_BIND_SHADER_IMAGE
| PIPE_BIND_SHADER_BUFFER
))
156 usage
|= ISL_SURF_USAGE_STORAGE_BIT
;
158 if (bindings
& PIPE_BIND_DISPLAY_TARGET
)
159 usage
|= ISL_SURF_USAGE_DISPLAY_BIT
;
165 iris_resource_destroy(struct pipe_screen
*screen
,
166 struct pipe_resource
*resource
)
168 struct iris_resource
*res
= (struct iris_resource
*)resource
;
170 iris_bo_unreference(res
->bo
);
174 static struct iris_resource
*
175 iris_alloc_resource(struct pipe_screen
*pscreen
,
176 const struct pipe_resource
*templ
)
178 struct iris_resource
*res
= calloc(1, sizeof(struct iris_resource
));
183 res
->base
.screen
= pscreen
;
184 pipe_reference_init(&res
->base
.reference
, 1);
189 static struct pipe_resource
*
190 iris_resource_create_with_modifiers(struct pipe_screen
*pscreen
,
191 const struct pipe_resource
*templ
,
192 const uint64_t *modifiers
,
195 struct iris_screen
*screen
= (struct iris_screen
*)pscreen
;
196 struct gen_device_info
*devinfo
= &screen
->devinfo
;
197 struct iris_resource
*res
= iris_alloc_resource(pscreen
, templ
);
201 bool depth
= util_format_is_depth_or_stencil(templ
->format
);
203 uint64_t modifier
= DRM_FORMAT_MOD_INVALID
;
205 if (modifiers_count
== 0 || !modifiers
) {
207 modifier
= I915_FORMAT_MOD_Y_TILED
;
208 } else if (templ
->bind
& PIPE_BIND_DISPLAY_TARGET
) {
209 /* Display is X-tiled for historical reasons. */
210 modifier
= I915_FORMAT_MOD_X_TILED
;
212 modifier
= I915_FORMAT_MOD_Y_TILED
;
214 /* XXX: make sure this doesn't do stupid things for internal textures */
217 if (templ
->target
== PIPE_BUFFER
|| templ
->usage
== PIPE_USAGE_STAGING
)
218 modifier
= DRM_FORMAT_MOD_LINEAR
;
220 if (templ
->bind
& (PIPE_BIND_LINEAR
| PIPE_BIND_CURSOR
))
221 modifier
= DRM_FORMAT_MOD_LINEAR
;
223 if (modifier
== DRM_FORMAT_MOD_INVALID
) {
224 /* User requested specific modifiers */
225 modifier
= select_best_modifier(devinfo
, modifiers
, modifiers_count
);
226 if (modifier
== DRM_FORMAT_MOD_INVALID
)
230 const struct isl_drm_modifier_info
*mod_info
=
231 isl_drm_modifier_get_info(modifier
);
233 isl_surf_usage_flags_t usage
= pipe_bind_to_isl_usage(templ
->bind
);
235 if (templ
->target
== PIPE_TEXTURE_CUBE
||
236 templ
->target
== PIPE_TEXTURE_CUBE_ARRAY
)
237 usage
|= ISL_SURF_USAGE_CUBE_BIT
;
239 // XXX: separate stencil...
240 enum pipe_format pfmt
= templ
->format
;
242 if (util_format_is_depth_or_stencil(pfmt
) &&
243 templ
->usage
!= PIPE_USAGE_STAGING
)
244 usage
|= ISL_SURF_USAGE_DEPTH_BIT
;
246 if (util_format_is_depth_and_stencil(pfmt
)) {
248 pfmt
= PIPE_FORMAT_Z24X8_UNORM
;
251 enum isl_format isl_format
= iris_isl_format_for_pipe_format(pfmt
);
252 assert(isl_format
!= ISL_FORMAT_UNSUPPORTED
);
254 UNUSED
const bool isl_surf_created_successfully
=
255 isl_surf_init(&screen
->isl_dev
, &res
->surf
,
256 .dim
= target_to_isl_surf_dim(templ
->target
),
257 .format
= isl_format
,
258 .width
= templ
->width0
,
259 .height
= templ
->height0
,
260 .depth
= templ
->depth0
,
261 .levels
= templ
->last_level
+ 1,
262 .array_len
= templ
->array_size
,
263 .samples
= MAX2(templ
->nr_samples
, 1),
264 .min_alignment_B
= 0,
267 .tiling_flags
= 1 << mod_info
->tiling
);
268 assert(isl_surf_created_successfully
);
270 enum iris_memory_zone memzone
= IRIS_MEMZONE_OTHER
;
271 const char *name
= templ
->target
== PIPE_BUFFER
? "buffer" : "miptree";
272 if (templ
->flags
& IRIS_RESOURCE_FLAG_SHADER_MEMZONE
) {
273 memzone
= IRIS_MEMZONE_SHADER
;
274 name
= "shader kernels";
275 } else if (templ
->flags
& IRIS_RESOURCE_FLAG_SURFACE_MEMZONE
) {
276 memzone
= IRIS_MEMZONE_SURFACE
;
277 name
= "surface state";
278 } else if (templ
->flags
& IRIS_RESOURCE_FLAG_DYNAMIC_MEMZONE
) {
279 memzone
= IRIS_MEMZONE_DYNAMIC
;
280 name
= "dynamic state";
283 res
->bo
= iris_bo_alloc_tiled(screen
->bufmgr
, name
, res
->surf
.size_B
,
285 isl_tiling_to_i915_tiling(res
->surf
.tiling
),
286 res
->surf
.row_pitch_B
, 0);
293 iris_resource_destroy(pscreen
, &res
->base
);
297 static struct pipe_resource
*
298 iris_resource_create(struct pipe_screen
*pscreen
,
299 const struct pipe_resource
*templ
)
301 return iris_resource_create_with_modifiers(pscreen
, templ
, NULL
, 0);
305 tiling_to_modifier(uint32_t tiling
)
307 static const uint64_t map
[] = {
308 [I915_TILING_NONE
] = DRM_FORMAT_MOD_LINEAR
,
309 [I915_TILING_X
] = I915_FORMAT_MOD_X_TILED
,
310 [I915_TILING_Y
] = I915_FORMAT_MOD_Y_TILED
,
313 assert(tiling
< ARRAY_SIZE(map
));
318 static struct pipe_resource
*
319 iris_resource_from_handle(struct pipe_screen
*pscreen
,
320 const struct pipe_resource
*templ
,
321 struct winsys_handle
*whandle
,
324 struct iris_screen
*screen
= (struct iris_screen
*)pscreen
;
325 struct iris_bufmgr
*bufmgr
= screen
->bufmgr
;
326 struct iris_resource
*res
= iris_alloc_resource(pscreen
, templ
);
330 if (whandle
->offset
!= 0) {
331 dbg_printf("Attempt to import unsupported winsys offset %u\n",
336 switch (whandle
->type
) {
337 case WINSYS_HANDLE_TYPE_FD
:
338 res
->bo
= iris_bo_import_dmabuf(bufmgr
, whandle
->handle
);
340 case WINSYS_HANDLE_TYPE_SHARED
:
341 res
->bo
= iris_bo_gem_create_from_name(bufmgr
, "winsys image",
345 unreachable("invalid winsys handle type");
350 uint64_t modifier
= whandle
->modifier
;
351 if (modifier
== DRM_FORMAT_MOD_INVALID
) {
352 modifier
= tiling_to_modifier(res
->bo
->tiling_mode
);
354 const struct isl_drm_modifier_info
*mod_info
=
355 isl_drm_modifier_get_info(modifier
);
359 isl_surf_usage_flags_t isl_usage
= ISL_SURF_USAGE_DISPLAY_BIT
;
361 isl_surf_init(&screen
->isl_dev
, &res
->surf
,
362 .dim
= target_to_isl_surf_dim(templ
->target
),
363 .format
= iris_isl_format_for_pipe_format(templ
->format
),
364 .width
= templ
->width0
,
365 .height
= templ
->height0
,
366 .depth
= templ
->depth0
,
367 .levels
= templ
->last_level
+ 1,
368 .array_len
= templ
->array_size
,
369 .samples
= MAX2(templ
->nr_samples
, 1),
370 .min_alignment_B
= 0,
373 .tiling_flags
= 1 << mod_info
->tiling
);
375 assert(res
->bo
->tiling_mode
== isl_tiling_to_i915_tiling(res
->surf
.tiling
));
380 iris_resource_destroy(pscreen
, &res
->base
);
385 iris_resource_get_handle(struct pipe_screen
*pscreen
,
386 struct pipe_context
*ctx
,
387 struct pipe_resource
*resource
,
388 struct winsys_handle
*whandle
,
391 struct iris_resource
*res
= (struct iris_resource
*)resource
;
393 whandle
->stride
= res
->surf
.row_pitch_B
;
394 whandle
->modifier
= tiling_to_modifier(res
->bo
->tiling_mode
);
396 switch (whandle
->type
) {
397 case WINSYS_HANDLE_TYPE_SHARED
:
398 return iris_bo_flink(res
->bo
, &whandle
->handle
) == 0;
399 case WINSYS_HANDLE_TYPE_KMS
:
400 return iris_bo_export_gem_handle(res
->bo
) != 0;
401 case WINSYS_HANDLE_TYPE_FD
:
402 return iris_bo_export_dmabuf(res
->bo
, (int *) &whandle
->handle
) == 0;
408 /* Compute extent parameters for use with tiled_memcpy functions.
409 * xs are in units of bytes and ys are in units of strides.
412 tile_extents(struct isl_surf
*surf
,
413 const struct pipe_box
*box
,
415 unsigned int *x1_B
, unsigned int *x2_B
,
416 unsigned int *y1_el
, unsigned int *y2_el
)
418 const struct isl_format_layout
*fmtl
= isl_format_get_layout(surf
->format
);
419 const unsigned cpp
= fmtl
->bpb
/ 8;
421 assert(box
->x
% fmtl
->bw
== 0);
422 assert(box
->y
% fmtl
->bh
== 0);
424 unsigned x0_el
, y0_el
;
425 if (surf
->dim
== ISL_SURF_DIM_3D
) {
426 isl_surf_get_image_offset_el(surf
, level
, 0, box
->z
, &x0_el
, &y0_el
);
428 isl_surf_get_image_offset_el(surf
, level
, box
->z
, 0, &x0_el
, &y0_el
);
431 *x1_B
= (box
->x
/ fmtl
->bw
+ x0_el
) * cpp
;
432 *y1_el
= box
->y
/ fmtl
->bh
+ y0_el
;
433 *x2_B
= (DIV_ROUND_UP(box
->x
+ box
->width
, fmtl
->bw
) + x0_el
) * cpp
;
434 *y2_el
= DIV_ROUND_UP(box
->y
+ box
->height
, fmtl
->bh
) + y0_el
;
438 iris_unmap_tiled_memcpy(struct iris_transfer
*map
)
440 struct pipe_transfer
*xfer
= &map
->base
;
441 struct pipe_box box
= xfer
->box
;
442 struct iris_resource
*res
= (struct iris_resource
*) xfer
->resource
;
443 struct isl_surf
*surf
= &res
->surf
;
445 const bool has_swizzling
= false; // XXX: swizzling?
447 if (xfer
->usage
& PIPE_TRANSFER_WRITE
) {
448 char *dst
= iris_bo_map(map
->dbg
, res
->bo
, xfer
->usage
| MAP_RAW
);
450 for (int s
= 0; s
< box
.depth
; s
++) {
451 unsigned int x1
, x2
, y1
, y2
;
452 tile_extents(surf
, &box
, xfer
->level
, &x1
, &x2
, &y1
, &y2
);
454 void *ptr
= map
->ptr
+ box
.z
* xfer
->layer_stride
;
456 isl_memcpy_linear_to_tiled(x1
, x2
, y1
, y2
, dst
, ptr
,
457 surf
->row_pitch_B
, xfer
->stride
,
458 has_swizzling
, surf
->tiling
, ISL_MEMCPY
);
462 os_free_aligned(map
->buffer
);
463 map
->buffer
= map
->ptr
= NULL
;
467 iris_map_tiled_memcpy(struct iris_transfer
*map
)
469 struct pipe_transfer
*xfer
= &map
->base
;
470 struct iris_resource
*res
= (struct iris_resource
*) xfer
->resource
;
471 struct isl_surf
*surf
= &res
->surf
;
473 xfer
->stride
= ALIGN(surf
->row_pitch_B
, 16);
474 xfer
->layer_stride
= xfer
->stride
* xfer
->box
.height
;
476 unsigned x1
, x2
, y1
, y2
;
477 tile_extents(surf
, &xfer
->box
, xfer
->level
, &x1
, &x2
, &y1
, &y2
);
479 /* The tiling and detiling functions require that the linear buffer has
480 * a 16-byte alignment (that is, its `x0` is 16-byte aligned). Here we
481 * over-allocate the linear buffer to get the proper alignment.
484 os_malloc_aligned(xfer
->layer_stride
* xfer
->box
.depth
, 16);
486 map
->ptr
= (char *)map
->buffer
+ (x1
& 0xf);
488 const bool has_swizzling
= false; // XXX: swizzling?
490 // XXX: PIPE_TRANSFER_READ?
491 if (!(xfer
->usage
& PIPE_TRANSFER_DISCARD_RANGE
)) {
492 char *src
= iris_bo_map(map
->dbg
, res
->bo
, xfer
->usage
| MAP_RAW
);
494 struct pipe_box box
= xfer
->box
;
496 for (int s
= 0; s
< box
.depth
; s
++) {
497 unsigned int x1
, x2
, y1
, y2
;
498 tile_extents(surf
, &box
, xfer
->level
, &x1
, &x2
, &y1
, &y2
);
500 isl_memcpy_tiled_to_linear(x1
, x2
, y1
, y2
, map
->ptr
, src
,
501 xfer
->stride
, surf
->row_pitch_B
,
502 has_swizzling
, surf
->tiling
, ISL_MEMCPY
);
507 map
->unmap
= iris_unmap_tiled_memcpy
;
511 iris_map_direct(struct iris_transfer
*map
)
513 struct pipe_transfer
*xfer
= &map
->base
;
514 struct pipe_box
*box
= &xfer
->box
;
515 struct iris_resource
*res
= (struct iris_resource
*) xfer
->resource
;
516 struct isl_surf
*surf
= &res
->surf
;
517 const struct isl_format_layout
*fmtl
= isl_format_get_layout(surf
->format
);
518 const unsigned cpp
= fmtl
->bpb
/ 8;
520 xfer
->stride
= isl_surf_get_row_pitch_B(surf
);
521 xfer
->layer_stride
= isl_surf_get_array_pitch(surf
);
523 void *ptr
= iris_bo_map(map
->dbg
, res
->bo
, xfer
->usage
);
525 // XXX: level, layer, etc
526 assert(xfer
->level
== 0);
529 map
->ptr
= ptr
+ box
->y
* xfer
->stride
+ box
->x
* cpp
;
533 iris_transfer_map(struct pipe_context
*ctx
,
534 struct pipe_resource
*resource
,
536 enum pipe_transfer_usage usage
,
537 const struct pipe_box
*box
,
538 struct pipe_transfer
**ptransfer
)
540 struct iris_context
*ice
= (struct iris_context
*)ctx
;
541 struct iris_resource
*res
= (struct iris_resource
*)resource
;
542 struct isl_surf
*surf
= &res
->surf
;
544 if (surf
->tiling
!= ISL_TILING_LINEAR
&&
545 (usage
& PIPE_TRANSFER_MAP_DIRECTLY
))
548 if (!(usage
& PIPE_TRANSFER_UNSYNCHRONIZED
) &&
549 iris_batch_references(&ice
->render_batch
, res
->bo
)) {
550 iris_batch_flush(&ice
->render_batch
);
553 if ((usage
& PIPE_TRANSFER_DONTBLOCK
) && iris_bo_busy(res
->bo
))
556 struct iris_transfer
*map
= slab_alloc(&ice
->transfer_pool
);
557 struct pipe_transfer
*xfer
= &map
->base
;
559 // PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
560 // PIPE_TRANSFER_DISCARD_RANGE
565 memset(map
, 0, sizeof(*map
));
566 map
->dbg
= &ice
->dbg
;
568 pipe_resource_reference(&xfer
->resource
, resource
);
574 xfer
->usage
&= (PIPE_TRANSFER_READ
|
575 PIPE_TRANSFER_WRITE
|
576 PIPE_TRANSFER_UNSYNCHRONIZED
|
577 PIPE_TRANSFER_PERSISTENT
|
578 PIPE_TRANSFER_COHERENT
|
579 PIPE_TRANSFER_DISCARD_RANGE
);
581 if (surf
->tiling
!= ISL_TILING_LINEAR
) {
582 iris_map_tiled_memcpy(map
);
584 iris_map_direct(map
);
591 iris_transfer_flush_region(struct pipe_context
*pipe
,
592 struct pipe_transfer
*transfer
,
593 const struct pipe_box
*box
)
598 iris_transfer_unmap(struct pipe_context
*ctx
, struct pipe_transfer
*xfer
)
600 struct iris_context
*ice
= (struct iris_context
*)ctx
;
601 struct iris_transfer
*map
= (void *) xfer
;
602 struct iris_resource
*res
= (struct iris_resource
*) xfer
->resource
;
603 struct isl_surf
*surf
= &res
->surf
;
608 /* XXX: big ol' hack! need to re-emit UBOs. want bind_history? */
609 if (surf
->tiling
== ISL_TILING_LINEAR
) {
610 ice
->state
.dirty
|= IRIS_DIRTY_CONSTANTS_VS
| IRIS_DIRTY_BINDINGS_VS
611 | IRIS_DIRTY_CONSTANTS_TCS
| IRIS_DIRTY_BINDINGS_TCS
612 | IRIS_DIRTY_CONSTANTS_TES
| IRIS_DIRTY_BINDINGS_TES
613 | IRIS_DIRTY_CONSTANTS_GS
| IRIS_DIRTY_BINDINGS_GS
614 | IRIS_DIRTY_CONSTANTS_FS
| IRIS_DIRTY_BINDINGS_FS
;
617 pipe_resource_reference(&xfer
->resource
, NULL
);
618 slab_free(&ice
->transfer_pool
, map
);
622 iris_flush_resource(struct pipe_context
*ctx
, struct pipe_resource
*resource
)
627 iris_init_screen_resource_functions(struct pipe_screen
*pscreen
)
629 pscreen
->resource_create_with_modifiers
=
630 iris_resource_create_with_modifiers
;
631 pscreen
->resource_create
= iris_resource_create
;
632 pscreen
->resource_from_handle
= iris_resource_from_handle
;
633 pscreen
->resource_get_handle
= iris_resource_get_handle
;
634 pscreen
->resource_destroy
= iris_resource_destroy
;
638 iris_init_resource_functions(struct pipe_context
*ctx
)
640 ctx
->flush_resource
= iris_flush_resource
;
641 ctx
->transfer_map
= iris_transfer_map
;
642 ctx
->transfer_flush_region
= iris_transfer_flush_region
;
643 ctx
->transfer_unmap
= iris_transfer_unmap
;
644 ctx
->buffer_subdata
= u_default_buffer_subdata
;
645 ctx
->texture_subdata
= u_default_texture_subdata
;