2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "core/ilo_state_vf.h"
29 #include "core/ilo_state_sol.h"
30 #include "core/ilo_state_surface.h"
32 #include "ilo_screen.h"
33 #include "ilo_format.h"
34 #include "ilo_resource.h"
37 * From the Ivy Bridge PRM, volume 1 part 1, page 105:
39 * "In addition to restrictions on maximum height, width, and depth,
40 * surfaces are also restricted to a maximum size in bytes. This
41 * maximum is 2 GB for all products and all surface types."
43 static const size_t ilo_max_resource_size
= 1u << 31;
46 resource_get_bo_name(const struct pipe_resource
*templ
)
48 static const char *target_names
[PIPE_MAX_TEXTURE_TYPES
] = {
49 [PIPE_BUFFER
] = "buf",
50 [PIPE_TEXTURE_1D
] = "tex-1d",
51 [PIPE_TEXTURE_2D
] = "tex-2d",
52 [PIPE_TEXTURE_3D
] = "tex-3d",
53 [PIPE_TEXTURE_CUBE
] = "tex-cube",
54 [PIPE_TEXTURE_RECT
] = "tex-rect",
55 [PIPE_TEXTURE_1D_ARRAY
] = "tex-1d-array",
56 [PIPE_TEXTURE_2D_ARRAY
] = "tex-2d-array",
57 [PIPE_TEXTURE_CUBE_ARRAY
] = "tex-cube-array",
59 const char *name
= target_names
[templ
->target
];
61 if (templ
->target
== PIPE_BUFFER
) {
62 switch (templ
->bind
) {
63 case PIPE_BIND_VERTEX_BUFFER
:
66 case PIPE_BIND_INDEX_BUFFER
:
69 case PIPE_BIND_CONSTANT_BUFFER
:
72 case PIPE_BIND_STREAM_OUTPUT
:
84 resource_get_cpu_init(const struct pipe_resource
*templ
)
86 return (templ
->bind
& (PIPE_BIND_DEPTH_STENCIL
|
87 PIPE_BIND_RENDER_TARGET
|
88 PIPE_BIND_STREAM_OUTPUT
)) ? false : true;
91 static enum gen_surface_type
92 get_surface_type(enum pipe_texture_target target
)
96 case PIPE_TEXTURE_1D_ARRAY
:
97 return GEN6_SURFTYPE_1D
;
99 case PIPE_TEXTURE_RECT
:
100 case PIPE_TEXTURE_2D_ARRAY
:
101 return GEN6_SURFTYPE_2D
;
102 case PIPE_TEXTURE_3D
:
103 return GEN6_SURFTYPE_3D
;
104 case PIPE_TEXTURE_CUBE
:
105 case PIPE_TEXTURE_CUBE_ARRAY
:
106 return GEN6_SURFTYPE_CUBE
;
108 assert(!"unknown texture target");
109 return GEN6_SURFTYPE_NULL
;
113 static enum pipe_format
114 resource_get_image_format(const struct pipe_resource
*templ
,
115 const struct ilo_dev
*dev
,
116 bool *separate_stencil_ret
)
118 enum pipe_format format
= templ
->format
;
119 bool separate_stencil
;
121 /* silently promote ETC1 */
122 if (templ
->format
== PIPE_FORMAT_ETC1_RGB8
)
123 format
= PIPE_FORMAT_R8G8B8X8_UNORM
;
125 /* separate stencil buffers */
126 separate_stencil
= false;
127 if ((templ
->bind
& PIPE_BIND_DEPTH_STENCIL
) &&
128 util_format_is_depth_and_stencil(templ
->format
)) {
129 switch (templ
->format
) {
130 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
:
131 /* Gen6 requires HiZ to be available for all levels */
132 if (ilo_dev_gen(dev
) >= ILO_GEN(7) || templ
->last_level
== 0) {
133 format
= PIPE_FORMAT_Z32_FLOAT
;
134 separate_stencil
= true;
137 case PIPE_FORMAT_Z24_UNORM_S8_UINT
:
138 format
= PIPE_FORMAT_Z24X8_UNORM
;
139 separate_stencil
= true;
146 if (separate_stencil_ret
)
147 *separate_stencil_ret
= separate_stencil
;
152 static inline enum gen_surface_format
153 pipe_to_surface_format(const struct ilo_dev
*dev
, enum pipe_format format
)
156 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
:
157 return GEN6_FORMAT_R32_FLOAT_X8X24_TYPELESS
;
158 case PIPE_FORMAT_Z32_FLOAT
:
159 return GEN6_FORMAT_R32_FLOAT
;
160 case PIPE_FORMAT_Z24_UNORM_S8_UINT
:
161 case PIPE_FORMAT_Z24X8_UNORM
:
162 return GEN6_FORMAT_R24_UNORM_X8_TYPELESS
;
163 case PIPE_FORMAT_Z16_UNORM
:
164 return GEN6_FORMAT_R16_UNORM
;
165 case PIPE_FORMAT_S8_UINT
:
166 return GEN6_FORMAT_R8_UINT
;
168 return ilo_format_translate_color(dev
, format
);
173 resource_get_image_info(const struct pipe_resource
*templ
,
174 const struct ilo_dev
*dev
,
175 enum pipe_format image_format
,
176 struct ilo_image_info
*info
)
178 memset(info
, 0, sizeof(*info
));
180 info
->type
= get_surface_type(templ
->target
);
182 info
->format
= pipe_to_surface_format(dev
, image_format
);
183 info
->interleaved_stencil
= util_format_is_depth_and_stencil(image_format
);
184 info
->is_integer
= util_format_is_pure_integer(image_format
);
185 info
->compressed
= util_format_is_compressed(image_format
);
186 info
->block_width
= util_format_get_blockwidth(image_format
);
187 info
->block_height
= util_format_get_blockheight(image_format
);
188 info
->block_size
= util_format_get_blocksize(image_format
);
190 info
->width
= templ
->width0
;
191 info
->height
= templ
->height0
;
192 info
->depth
= templ
->depth0
;
193 info
->array_size
= templ
->array_size
;
194 info
->level_count
= templ
->last_level
+ 1;
195 info
->sample_count
= (templ
->nr_samples
) ? templ
->nr_samples
: 1;
197 info
->aux_disable
= (templ
->usage
== PIPE_USAGE_STAGING
);
199 if (templ
->bind
& PIPE_BIND_LINEAR
)
200 info
->valid_tilings
= 1 << GEN6_TILING_NONE
;
203 * Tiled images must be mapped via GTT to get a linear view. Prefer linear
204 * images when the image size is greater than one-fourth of the mappable
207 if (templ
->usage
== PIPE_USAGE_STAGING
)
208 info
->prefer_linear_threshold
= dev
->aperture_mappable
/ 4;
210 info
->bind_surface_sampler
= (templ
->bind
& PIPE_BIND_SAMPLER_VIEW
);
211 info
->bind_surface_dp_render
= (templ
->bind
& PIPE_BIND_RENDER_TARGET
);
212 info
->bind_surface_dp_typed
= (templ
->bind
&
213 (PIPE_BIND_SHADER_IMAGE
| PIPE_BIND_COMPUTE_RESOURCE
));
214 info
->bind_zs
= (templ
->bind
& PIPE_BIND_DEPTH_STENCIL
);
215 info
->bind_scanout
= (templ
->bind
& PIPE_BIND_SCANOUT
);
216 info
->bind_cursor
= (templ
->bind
& PIPE_BIND_CURSOR
);
219 static enum gen_surface_tiling
220 winsys_to_surface_tiling(enum intel_tiling_mode tiling
)
223 case INTEL_TILING_NONE
:
224 return GEN6_TILING_NONE
;
226 return GEN6_TILING_X
;
228 return GEN6_TILING_Y
;
230 assert(!"unknown tiling");
231 return GEN6_TILING_NONE
;
235 static inline enum intel_tiling_mode
236 surface_to_winsys_tiling(enum gen_surface_tiling tiling
)
239 case GEN6_TILING_NONE
:
240 return INTEL_TILING_NONE
;
242 return INTEL_TILING_X
;
244 return INTEL_TILING_Y
;
246 assert(!"unknown tiling");
247 return GEN6_TILING_NONE
;
252 tex_free_slices(struct ilo_texture
*tex
)
254 FREE(tex
->slices
[0]);
258 tex_alloc_slices(struct ilo_texture
*tex
)
260 const struct pipe_resource
*templ
= &tex
->base
;
261 struct ilo_texture_slice
*slices
;
264 /* sum the depths of all levels */
266 for (lv
= 0; lv
<= templ
->last_level
; lv
++)
267 depth
+= u_minify(templ
->depth0
, lv
);
270 * There are (depth * tex->base.array_size) slices in total. Either depth
271 * is one (non-3D) or templ->array_size is one (non-array), but it does
274 slices
= CALLOC(depth
* templ
->array_size
, sizeof(*slices
));
278 tex
->slices
[0] = slices
;
280 /* point to the respective positions in the buffer */
281 for (lv
= 1; lv
<= templ
->last_level
; lv
++) {
282 tex
->slices
[lv
] = tex
->slices
[lv
- 1] +
283 u_minify(templ
->depth0
, lv
- 1) * templ
->array_size
;
290 tex_create_bo(struct ilo_texture
*tex
)
292 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
293 const char *name
= resource_get_bo_name(&tex
->base
);
294 const bool cpu_init
= resource_get_cpu_init(&tex
->base
);
297 bo
= intel_winsys_alloc_bo(is
->dev
.winsys
, name
,
298 tex
->image
.bo_stride
* tex
->image
.bo_height
, cpu_init
);
300 /* set the tiling for transfer and export */
301 if (bo
&& (tex
->image
.tiling
== GEN6_TILING_X
||
302 tex
->image
.tiling
== GEN6_TILING_Y
)) {
303 const enum intel_tiling_mode tiling
=
304 surface_to_winsys_tiling(tex
->image
.tiling
);
306 if (intel_bo_set_tiling(bo
, tiling
, tex
->image
.bo_stride
)) {
314 intel_bo_unref(tex
->vma
.bo
);
315 ilo_vma_set_bo(&tex
->vma
, &is
->dev
, bo
, 0);
321 tex_create_separate_stencil(struct ilo_texture
*tex
)
323 struct pipe_resource templ
= tex
->base
;
324 struct pipe_resource
*s8
;
327 * Unless PIPE_BIND_DEPTH_STENCIL is set, the resource may have other
328 * tilings. But that should be fine since it will never be bound as the
329 * stencil buffer, and our transfer code can handle all tilings.
331 templ
.format
= PIPE_FORMAT_S8_UINT
;
333 /* no stencil texturing */
334 templ
.bind
&= ~PIPE_BIND_SAMPLER_VIEW
;
336 s8
= tex
->base
.screen
->resource_create(tex
->base
.screen
, &templ
);
340 tex
->separate_s8
= ilo_texture(s8
);
342 assert(tex
->separate_s8
->image_format
== PIPE_FORMAT_S8_UINT
);
348 tex_create_hiz(struct ilo_texture
*tex
)
350 const struct pipe_resource
*templ
= &tex
->base
;
351 const uint32_t size
= tex
->image
.aux
.bo_stride
* tex
->image
.aux
.bo_height
;
352 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
355 bo
= intel_winsys_alloc_bo(is
->dev
.winsys
, "hiz texture", size
, false);
359 ilo_vma_init(&tex
->aux_vma
, &is
->dev
, size
, 4096);
360 ilo_vma_set_bo(&tex
->aux_vma
, &is
->dev
, bo
, 0);
365 for (lv
= 0; lv
<= templ
->last_level
; lv
++) {
366 if (tex
->image
.aux
.enables
& (1 << lv
)) {
367 const unsigned num_slices
= (templ
->target
== PIPE_TEXTURE_3D
) ?
368 u_minify(templ
->depth0
, lv
) : templ
->array_size
;
369 /* this will trigger HiZ resolves */
370 const unsigned flags
= ILO_TEXTURE_CPU_WRITE
;
372 ilo_texture_set_slice_flags(tex
, lv
, 0, num_slices
, flags
, flags
);
381 tex_create_mcs(struct ilo_texture
*tex
)
383 const uint32_t size
= tex
->image
.aux
.bo_stride
* tex
->image
.aux
.bo_height
;
384 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
387 assert(tex
->image
.aux
.enables
== (1 << (tex
->base
.last_level
+ 1)) - 1);
389 bo
= intel_winsys_alloc_bo(is
->dev
.winsys
, "mcs texture", size
, false);
393 ilo_vma_init(&tex
->aux_vma
, &is
->dev
, size
, 4096);
394 ilo_vma_set_bo(&tex
->aux_vma
, &is
->dev
, bo
, 0);
400 tex_destroy(struct ilo_texture
*tex
)
402 if (tex
->separate_s8
)
403 tex_destroy(tex
->separate_s8
);
405 intel_bo_unref(tex
->vma
.bo
);
406 intel_bo_unref(tex
->aux_vma
.bo
);
408 tex_free_slices(tex
);
413 tex_alloc_bos(struct ilo_texture
*tex
)
415 if (!tex
->imported
&& !tex_create_bo(tex
))
418 switch (tex
->image
.aux
.type
) {
419 case ILO_IMAGE_AUX_HIZ
:
420 if (!tex_create_hiz(tex
))
423 case ILO_IMAGE_AUX_MCS
:
424 if (!tex_create_mcs(tex
))
434 static struct intel_bo
*
435 tex_import_handle(struct ilo_texture
*tex
,
436 const struct winsys_handle
*handle
,
437 struct ilo_image_info
*info
)
439 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
440 const struct pipe_resource
*templ
= &tex
->base
;
441 const char *name
= resource_get_bo_name(&tex
->base
);
442 enum intel_tiling_mode tiling
;
446 bo
= intel_winsys_import_handle(is
->dev
.winsys
, name
, handle
,
447 tex
->image
.bo_height
, &tiling
, &pitch
);
448 /* modify image info */
450 const uint8_t valid_tilings
= 1 << winsys_to_surface_tiling(tiling
);
452 if (info
->valid_tilings
&& !(info
->valid_tilings
& valid_tilings
)) {
457 info
->valid_tilings
= valid_tilings
;
458 info
->force_bo_stride
= pitch
;
460 /* assume imported RTs are also scanouts */
461 if (!info
->bind_scanout
)
462 info
->bind_scanout
= (templ
->usage
& PIPE_BIND_RENDER_TARGET
);
469 tex_init_image(struct ilo_texture
*tex
,
470 const struct winsys_handle
*handle
,
471 bool *separate_stencil
)
473 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
474 const struct pipe_resource
*templ
= &tex
->base
;
475 struct ilo_image
*img
= &tex
->image
;
476 struct intel_bo
*imported_bo
= NULL
;
477 struct ilo_image_info info
;
479 tex
->image_format
= resource_get_image_format(templ
,
480 &is
->dev
, separate_stencil
);
481 resource_get_image_info(templ
, &is
->dev
, tex
->image_format
, &info
);
484 imported_bo
= tex_import_handle(tex
, handle
, &info
);
489 if (!ilo_image_init(img
, &is
->dev
, &info
)) {
490 intel_bo_unref(imported_bo
);
495 * HiZ requires 8x4 alignment and some levels might need HiZ disabled. It
496 * is generally fine except on Gen6, where HiZ and separate stencil must be
497 * enabled together. For PIPE_FORMAT_Z24X8_UNORM with separate stencil, we
498 * can live with stencil values being interleaved for levels where HiZ is
499 * disabled. But it is not the case for PIPE_FORMAT_Z32_FLOAT with
500 * separate stencil. If HiZ was disabled for a level, we had to change the
501 * format to PIPE_FORMAT_Z32_FLOAT_S8X24_UINT for the level and that format
502 * had a different bpp. In other words, HiZ has to be available for all
505 if (ilo_dev_gen(&is
->dev
) == ILO_GEN(6) &&
506 templ
->format
== PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
&&
507 tex
->image_format
== PIPE_FORMAT_Z32_FLOAT
&&
508 img
->aux
.enables
!= (1 << templ
->last_level
)) {
509 tex
->image_format
= templ
->format
;
510 info
.format
= pipe_to_surface_format(&is
->dev
, tex
->image_format
);
511 info
.interleaved_stencil
= true;
513 memset(img
, 0, sizeof(*img
));
514 if (!ilo_image_init(img
, &is
->dev
, &info
)) {
515 intel_bo_unref(imported_bo
);
520 if (img
->bo_height
> ilo_max_resource_size
/ img
->bo_stride
||
521 !ilo_vma_init(&tex
->vma
, &is
->dev
, img
->bo_stride
* img
->bo_height
,
523 intel_bo_unref(imported_bo
);
528 ilo_vma_set_bo(&tex
->vma
, &is
->dev
, imported_bo
, 0);
529 tex
->imported
= true;
532 if (templ
->flags
& PIPE_RESOURCE_FLAG_MAP_PERSISTENT
) {
533 /* require on-the-fly tiling/untiling or format conversion */
534 if (img
->tiling
== GEN8_TILING_W
|| *separate_stencil
||
535 tex
->image_format
!= templ
->format
)
539 if (!tex_alloc_slices(tex
))
545 static struct pipe_resource
*
546 tex_create(struct pipe_screen
*screen
,
547 const struct pipe_resource
*templ
,
548 const struct winsys_handle
*handle
)
550 struct ilo_texture
*tex
;
551 bool separate_stencil
;
553 tex
= CALLOC_STRUCT(ilo_texture
);
558 tex
->base
.screen
= screen
;
559 pipe_reference_init(&tex
->base
.reference
, 1);
561 if (!tex_init_image(tex
, handle
, &separate_stencil
)) {
566 if (!tex_alloc_bos(tex
) ||
567 (separate_stencil
&& !tex_create_separate_stencil(tex
))) {
576 tex_get_handle(struct ilo_texture
*tex
, struct winsys_handle
*handle
)
578 struct ilo_screen
*is
= ilo_screen(tex
->base
.screen
);
579 enum intel_tiling_mode tiling
;
582 /* must match what tex_create_bo() sets */
583 if (tex
->image
.tiling
== GEN8_TILING_W
)
584 tiling
= INTEL_TILING_NONE
;
586 tiling
= surface_to_winsys_tiling(tex
->image
.tiling
);
588 err
= intel_winsys_export_handle(is
->dev
.winsys
, tex
->vma
.bo
, tiling
,
589 tex
->image
.bo_stride
, tex
->image
.bo_height
, handle
);
595 buf_create_bo(struct ilo_buffer_resource
*buf
)
597 struct ilo_screen
*is
= ilo_screen(buf
->base
.screen
);
598 const char *name
= resource_get_bo_name(&buf
->base
);
599 const bool cpu_init
= resource_get_cpu_init(&buf
->base
);
602 bo
= intel_winsys_alloc_bo(is
->dev
.winsys
, name
, buf
->bo_size
, cpu_init
);
606 intel_bo_unref(buf
->vma
.bo
);
607 ilo_vma_set_bo(&buf
->vma
, &is
->dev
, bo
, 0);
613 buf_destroy(struct ilo_buffer_resource
*buf
)
615 intel_bo_unref(buf
->vma
.bo
);
619 static struct pipe_resource
*
620 buf_create(struct pipe_screen
*screen
, const struct pipe_resource
*templ
)
622 const struct ilo_screen
*is
= ilo_screen(screen
);
623 struct ilo_buffer_resource
*buf
;
627 buf
= CALLOC_STRUCT(ilo_buffer_resource
);
632 buf
->base
.screen
= screen
;
633 pipe_reference_init(&buf
->base
.reference
, 1);
635 size
= templ
->width0
;
638 * As noted in ilo_format_translate(), we treat some 3-component formats as
639 * 4-component formats to work around hardware limitations. Imagine the
640 * case where the vertex buffer holds a single PIPE_FORMAT_R16G16B16_FLOAT
641 * vertex, and buf->bo_size is 6. The hardware would fail to fetch it at
642 * boundary check because the vertex buffer is expected to hold a
643 * PIPE_FORMAT_R16G16B16A16_FLOAT vertex and that takes at least 8 bytes.
645 * For the workaround to work, we should add 2 to the bo size. But that
646 * would waste a page when the bo size is already page aligned. Let's
647 * round it to page size for now and revisit this when needed.
649 if ((templ
->bind
& PIPE_BIND_VERTEX_BUFFER
) &&
650 ilo_dev_gen(&is
->dev
) < ILO_GEN(7.5))
651 size
= align(size
, 4096);
653 if (templ
->bind
& PIPE_BIND_VERTEX_BUFFER
)
654 size
= ilo_state_vertex_buffer_size(&is
->dev
, size
, &alignment
);
655 if (templ
->bind
& PIPE_BIND_INDEX_BUFFER
)
656 size
= ilo_state_index_buffer_size(&is
->dev
, size
, &alignment
);
657 if (templ
->bind
& PIPE_BIND_STREAM_OUTPUT
)
658 size
= ilo_state_sol_buffer_size(&is
->dev
, size
, &alignment
);
661 ilo_vma_init(&buf
->vma
, &is
->dev
, buf
->bo_size
, 4096);
663 if (buf
->bo_size
< templ
->width0
|| buf
->bo_size
> ilo_max_resource_size
||
664 !buf_create_bo(buf
)) {
673 ilo_can_create_resource(struct pipe_screen
*screen
,
674 const struct pipe_resource
*templ
)
676 struct ilo_screen
*is
= ilo_screen(screen
);
677 enum pipe_format image_format
;
678 struct ilo_image_info info
;
679 struct ilo_image img
;
681 if (templ
->target
== PIPE_BUFFER
)
682 return (templ
->width0
<= ilo_max_resource_size
);
684 image_format
= resource_get_image_format(templ
, &is
->dev
, NULL
);
685 resource_get_image_info(templ
, &is
->dev
, image_format
, &info
);
687 memset(&img
, 0, sizeof(img
));
688 ilo_image_init(&img
, &ilo_screen(screen
)->dev
, &info
);
690 /* as in tex_init_image() */
691 if (ilo_dev_gen(&is
->dev
) == ILO_GEN(6) &&
692 templ
->format
== PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
&&
693 image_format
== PIPE_FORMAT_Z32_FLOAT
&&
694 img
.aux
.enables
!= (1 << templ
->last_level
)) {
695 info
.format
= pipe_to_surface_format(&is
->dev
, templ
->format
);
696 info
.interleaved_stencil
= true;
697 memset(&img
, 0, sizeof(img
));
698 ilo_image_init(&img
, &ilo_screen(screen
)->dev
, &info
);
701 return (img
.bo_height
<= ilo_max_resource_size
/ img
.bo_stride
);
704 static struct pipe_resource
*
705 ilo_resource_create(struct pipe_screen
*screen
,
706 const struct pipe_resource
*templ
)
708 if (templ
->target
== PIPE_BUFFER
)
709 return buf_create(screen
, templ
);
711 return tex_create(screen
, templ
, NULL
);
714 static struct pipe_resource
*
715 ilo_resource_from_handle(struct pipe_screen
*screen
,
716 const struct pipe_resource
*templ
,
717 struct winsys_handle
*handle
,
720 if (templ
->target
== PIPE_BUFFER
)
723 return tex_create(screen
, templ
, handle
);
727 ilo_resource_get_handle(struct pipe_screen
*screen
,
728 struct pipe_context
*ctx
,
729 struct pipe_resource
*res
,
730 struct winsys_handle
*handle
,
733 if (res
->target
== PIPE_BUFFER
)
736 return tex_get_handle(ilo_texture(res
), handle
);
741 ilo_resource_destroy(struct pipe_screen
*screen
,
742 struct pipe_resource
*res
)
744 if (res
->target
== PIPE_BUFFER
)
745 buf_destroy((struct ilo_buffer_resource
*) res
);
747 tex_destroy(ilo_texture(res
));
751 * Initialize resource-related functions.
754 ilo_init_resource_functions(struct ilo_screen
*is
)
756 is
->base
.can_create_resource
= ilo_can_create_resource
;
757 is
->base
.resource_create
= ilo_resource_create
;
758 is
->base
.resource_from_handle
= ilo_resource_from_handle
;
759 is
->base
.resource_get_handle
= ilo_resource_get_handle
;
760 is
->base
.resource_destroy
= ilo_resource_destroy
;
764 ilo_resource_rename_bo(struct pipe_resource
*res
)
766 if (res
->target
== PIPE_BUFFER
) {
767 return buf_create_bo((struct ilo_buffer_resource
*) res
);
769 struct ilo_texture
*tex
= ilo_texture(res
);
771 /* an imported texture cannot be renamed */
775 return tex_create_bo(tex
);