2 * Copyright © 2014-2017 Broadcom
3 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
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 DEALINGS
25 #include "util/u_blit.h"
26 #include "util/u_memory.h"
27 #include "util/u_format.h"
28 #include "util/u_inlines.h"
29 #include "util/u_surface.h"
30 #include "util/u_upload_mgr.h"
32 #include "drm_fourcc.h"
33 #include "vc5_screen.h"
34 #include "vc5_context.h"
35 #include "vc5_resource.h"
36 #include "vc5_tiling.h"
37 #include "broadcom/cle/v3d_packet_v33_pack.h"
39 #ifndef DRM_FORMAT_MOD_INVALID
40 #define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
44 vc5_resource_bo_alloc(struct vc5_resource
*rsc
)
46 struct pipe_resource
*prsc
= &rsc
->base
;
47 struct pipe_screen
*pscreen
= prsc
->screen
;
49 int layers
= (prsc
->target
== PIPE_TEXTURE_3D
?
50 prsc
->depth0
: prsc
->array_size
);
52 bo
= vc5_bo_alloc(vc5_screen(pscreen
),
53 rsc
->slices
[0].offset
+
55 rsc
->cube_map_stride
* layers
- 1,
58 DBG(V3D_DEBUG_SURFACE
, "alloc %p @ 0x%08x:\n", rsc
, bo
->offset
);
59 vc5_bo_unreference(&rsc
->bo
);
68 vc5_resource_transfer_unmap(struct pipe_context
*pctx
,
69 struct pipe_transfer
*ptrans
)
71 struct vc5_context
*vc5
= vc5_context(pctx
);
72 struct vc5_transfer
*trans
= vc5_transfer(ptrans
);
75 struct vc5_resource
*rsc
;
76 struct vc5_resource_slice
*slice
;
77 if (trans
->ss_resource
) {
78 rsc
= vc5_resource(trans
->ss_resource
);
79 slice
= &rsc
->slices
[0];
81 rsc
= vc5_resource(ptrans
->resource
);
82 slice
= &rsc
->slices
[ptrans
->level
];
85 if (ptrans
->usage
& PIPE_TRANSFER_WRITE
) {
86 vc5_store_tiled_image(rsc
->bo
->map
+ slice
->offset
+
87 ptrans
->box
.z
* rsc
->cube_map_stride
,
89 trans
->map
, ptrans
->stride
,
90 slice
->tiling
, rsc
->cpp
,
97 if (trans
->ss_resource
&& (ptrans
->usage
& PIPE_TRANSFER_WRITE
)) {
98 struct pipe_blit_info blit
;
99 memset(&blit
, 0, sizeof(blit
));
101 blit
.src
.resource
= trans
->ss_resource
;
102 blit
.src
.format
= trans
->ss_resource
->format
;
103 blit
.src
.box
.width
= trans
->ss_box
.width
;
104 blit
.src
.box
.height
= trans
->ss_box
.height
;
105 blit
.src
.box
.depth
= 1;
107 blit
.dst
.resource
= ptrans
->resource
;
108 blit
.dst
.format
= ptrans
->resource
->format
;
109 blit
.dst
.level
= ptrans
->level
;
110 blit
.dst
.box
= trans
->ss_box
;
112 blit
.mask
= util_format_get_mask(ptrans
->resource
->format
);
113 blit
.filter
= PIPE_TEX_FILTER_NEAREST
;
115 pctx
->blit(pctx
, &blit
);
117 pipe_resource_reference(&trans
->ss_resource
, NULL
);
120 pipe_resource_reference(&ptrans
->resource
, NULL
);
121 slab_free(&vc5
->transfer_pool
, ptrans
);
124 static struct pipe_resource
*
125 vc5_get_temp_resource(struct pipe_context
*pctx
,
126 struct pipe_resource
*prsc
,
127 const struct pipe_box
*box
)
129 struct pipe_resource temp_setup
;
131 memset(&temp_setup
, 0, sizeof(temp_setup
));
132 temp_setup
.target
= prsc
->target
;
133 temp_setup
.format
= prsc
->format
;
134 temp_setup
.width0
= box
->width
;
135 temp_setup
.height0
= box
->height
;
136 temp_setup
.depth0
= 1;
137 temp_setup
.array_size
= 1;
139 return pctx
->screen
->resource_create(pctx
->screen
, &temp_setup
);
143 vc5_resource_transfer_map(struct pipe_context
*pctx
,
144 struct pipe_resource
*prsc
,
145 unsigned level
, unsigned usage
,
146 const struct pipe_box
*box
,
147 struct pipe_transfer
**pptrans
)
149 struct vc5_context
*vc5
= vc5_context(pctx
);
150 struct vc5_resource
*rsc
= vc5_resource(prsc
);
151 struct vc5_transfer
*trans
;
152 struct pipe_transfer
*ptrans
;
153 enum pipe_format format
= prsc
->format
;
156 /* Upgrade DISCARD_RANGE to WHOLE_RESOURCE if the whole resource is
159 if ((usage
& PIPE_TRANSFER_DISCARD_RANGE
) &&
160 !(usage
& PIPE_TRANSFER_UNSYNCHRONIZED
) &&
161 !(prsc
->flags
& PIPE_RESOURCE_FLAG_MAP_COHERENT
) &&
162 prsc
->last_level
== 0 &&
163 prsc
->width0
== box
->width
&&
164 prsc
->height0
== box
->height
&&
165 prsc
->depth0
== box
->depth
&&
166 prsc
->array_size
== 1 &&
168 usage
|= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
;
171 if (usage
& PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE
) {
172 if (vc5_resource_bo_alloc(rsc
)) {
173 /* If it might be bound as one of our vertex buffers
174 * or UBOs, make sure we re-emit vertex buffer state
177 if (prsc
->bind
& PIPE_BIND_VERTEX_BUFFER
)
178 vc5
->dirty
|= VC5_DIRTY_VTXBUF
;
179 if (prsc
->bind
& PIPE_BIND_CONSTANT_BUFFER
)
180 vc5
->dirty
|= VC5_DIRTY_CONSTBUF
;
182 /* If we failed to reallocate, flush users so that we
183 * don't violate any syncing requirements.
185 vc5_flush_jobs_reading_resource(vc5
, prsc
);
187 } else if (!(usage
& PIPE_TRANSFER_UNSYNCHRONIZED
)) {
188 /* If we're writing and the buffer is being used by the CL, we
189 * have to flush the CL first. If we're only reading, we need
190 * to flush if the CL has written our buffer.
192 if (usage
& PIPE_TRANSFER_WRITE
)
193 vc5_flush_jobs_reading_resource(vc5
, prsc
);
195 vc5_flush_jobs_writing_resource(vc5
, prsc
);
198 if (usage
& PIPE_TRANSFER_WRITE
) {
200 rsc
->initialized_buffers
= ~0;
203 trans
= slab_alloc(&vc5
->transfer_pool
);
207 /* XXX: Handle DONTBLOCK, DISCARD_RANGE, PERSISTENT, COHERENT. */
209 /* slab_alloc_st() doesn't zero: */
210 memset(trans
, 0, sizeof(*trans
));
211 ptrans
= &trans
->base
;
213 pipe_resource_reference(&ptrans
->resource
, prsc
);
214 ptrans
->level
= level
;
215 ptrans
->usage
= usage
;
218 /* If the resource is multisampled, we need to resolve to single
219 * sample. This seems like it should be handled at a higher layer.
221 if (prsc
->nr_samples
> 1) {
222 trans
->ss_resource
= vc5_get_temp_resource(pctx
, prsc
, box
);
223 if (!trans
->ss_resource
)
225 assert(!trans
->ss_resource
->nr_samples
);
227 /* The ptrans->box gets modified for tile alignment, so save
228 * the original box for unmap time.
230 trans
->ss_box
= *box
;
232 if (usage
& PIPE_TRANSFER_READ
) {
233 struct pipe_blit_info blit
;
234 memset(&blit
, 0, sizeof(blit
));
236 blit
.src
.resource
= ptrans
->resource
;
237 blit
.src
.format
= ptrans
->resource
->format
;
238 blit
.src
.level
= ptrans
->level
;
239 blit
.src
.box
= trans
->ss_box
;
241 blit
.dst
.resource
= trans
->ss_resource
;
242 blit
.dst
.format
= trans
->ss_resource
->format
;
243 blit
.dst
.box
.width
= trans
->ss_box
.width
;
244 blit
.dst
.box
.height
= trans
->ss_box
.height
;
245 blit
.dst
.box
.depth
= 1;
247 blit
.mask
= util_format_get_mask(prsc
->format
);
248 blit
.filter
= PIPE_TEX_FILTER_NEAREST
;
250 pctx
->blit(pctx
, &blit
);
251 vc5_flush_jobs_writing_resource(vc5
, blit
.dst
.resource
);
254 /* The rest of the mapping process should use our temporary. */
255 prsc
= trans
->ss_resource
;
256 rsc
= vc5_resource(prsc
);
262 /* Note that the current kernel implementation is synchronous, so no
263 * need to do syncing stuff here yet.
266 if (usage
& PIPE_TRANSFER_UNSYNCHRONIZED
)
267 buf
= vc5_bo_map_unsynchronized(rsc
->bo
);
269 buf
= vc5_bo_map(rsc
->bo
);
271 fprintf(stderr
, "Failed to map bo\n");
277 struct vc5_resource_slice
*slice
= &rsc
->slices
[level
];
279 /* No direct mappings of tiled, since we need to manually
282 if (usage
& PIPE_TRANSFER_MAP_DIRECTLY
)
285 ptrans
->stride
= ptrans
->box
.width
* rsc
->cpp
;
286 ptrans
->layer_stride
= ptrans
->stride
* ptrans
->box
.height
;
288 trans
->map
= malloc(ptrans
->layer_stride
* ptrans
->box
.depth
);
290 if (usage
& PIPE_TRANSFER_READ
) {
291 vc5_load_tiled_image(trans
->map
, ptrans
->stride
,
292 buf
+ slice
->offset
+
293 ptrans
->box
.z
* rsc
->cube_map_stride
,
295 slice
->tiling
, rsc
->cpp
,
301 ptrans
->stride
= slice
->stride
;
302 ptrans
->layer_stride
= ptrans
->stride
;
304 return buf
+ slice
->offset
+
305 ptrans
->box
.y
/ util_format_get_blockheight(format
) * ptrans
->stride
+
306 ptrans
->box
.x
/ util_format_get_blockwidth(format
) * rsc
->cpp
+
307 ptrans
->box
.z
* rsc
->cube_map_stride
;
312 vc5_resource_transfer_unmap(pctx
, ptrans
);
317 vc5_resource_destroy(struct pipe_screen
*pscreen
,
318 struct pipe_resource
*prsc
)
320 struct vc5_resource
*rsc
= vc5_resource(prsc
);
321 vc5_bo_unreference(&rsc
->bo
);
326 vc5_resource_get_handle(struct pipe_screen
*pscreen
,
327 struct pipe_context
*pctx
,
328 struct pipe_resource
*prsc
,
329 struct winsys_handle
*whandle
,
332 struct vc5_resource
*rsc
= vc5_resource(prsc
);
333 struct vc5_bo
*bo
= rsc
->bo
;
335 whandle
->stride
= rsc
->slices
[0].stride
;
337 /* If we're passing some reference to our BO out to some other part of
338 * the system, then we can't do any optimizations about only us being
339 * the ones seeing it (like BO caching).
343 switch (whandle
->type
) {
344 case DRM_API_HANDLE_TYPE_SHARED
:
345 return vc5_bo_flink(bo
, &whandle
->handle
);
346 case DRM_API_HANDLE_TYPE_KMS
:
347 whandle
->handle
= bo
->handle
;
349 case DRM_API_HANDLE_TYPE_FD
:
350 whandle
->handle
= vc5_bo_get_dmabuf(bo
);
351 return whandle
->handle
!= -1;
358 vc5_setup_slices(struct vc5_resource
*rsc
, const char *caller
)
360 struct pipe_resource
*prsc
= &rsc
->base
;
361 uint32_t width
= prsc
->width0
;
362 uint32_t height
= prsc
->height0
;
363 uint32_t pot_width
= util_next_power_of_two(width
);
364 uint32_t pot_height
= util_next_power_of_two(height
);
366 uint32_t utile_w
= vc5_utile_width(rsc
->cpp
);
367 uint32_t utile_h
= vc5_utile_height(rsc
->cpp
);
368 uint32_t uif_block_w
= utile_w
* 2;
369 uint32_t uif_block_h
= utile_h
* 2;
370 bool msaa
= prsc
->nr_samples
> 1;
371 /* MSAA textures/renderbuffers are always laid out as single-level
374 bool uif_top
= prsc
->nr_samples
> 1;
376 for (int i
= prsc
->last_level
; i
>= 0; i
--) {
377 struct vc5_resource_slice
*slice
= &rsc
->slices
[i
];
379 uint32_t level_width
, level_height
;
381 level_width
= u_minify(width
, i
);
382 level_height
= u_minify(height
, i
);
384 level_width
= u_minify(pot_width
, i
);
385 level_height
= u_minify(pot_height
, i
);
394 slice
->tiling
= VC5_TILING_RASTER
;
396 if ((i
!= 0 || !uif_top
) &&
397 (level_width
<= utile_w
||
398 level_height
<= utile_h
)) {
399 slice
->tiling
= VC5_TILING_LINEARTILE
;
400 level_width
= align(level_width
, utile_w
);
401 level_height
= align(level_height
, utile_h
);
402 } else if ((i
!= 0 || !uif_top
) &&
403 level_width
<= uif_block_w
) {
404 slice
->tiling
= VC5_TILING_UBLINEAR_1_COLUMN
;
405 level_width
= align(level_width
, uif_block_w
);
406 level_height
= align(level_height
, uif_block_h
);
407 } else if ((i
!= 0 || !uif_top
) &&
408 level_width
<= 2 * uif_block_w
) {
409 slice
->tiling
= VC5_TILING_UBLINEAR_2_COLUMN
;
410 level_width
= align(level_width
, 2 * uif_block_w
);
411 level_height
= align(level_height
, uif_block_h
);
413 slice
->tiling
= VC5_TILING_UIF_NO_XOR
;
415 level_width
= align(level_width
,
417 level_height
= align(level_height
,
422 slice
->offset
= offset
;
423 slice
->stride
= level_width
* rsc
->cpp
;
424 slice
->size
= level_height
* slice
->stride
;
426 offset
+= slice
->size
;
428 if (V3D_DEBUG
& V3D_DEBUG_SURFACE
) {
429 static const char *const tiling_descriptions
[] = {
430 [VC5_TILING_RASTER
] = "R",
431 [VC5_TILING_LINEARTILE
] = "LT",
432 [VC5_TILING_UBLINEAR_1_COLUMN
] = "UB1",
433 [VC5_TILING_UBLINEAR_2_COLUMN
] = "UB2",
434 [VC5_TILING_UIF_NO_XOR
] = "UIF",
435 [VC5_TILING_UIF_XOR
] = "UIF^",
439 "rsc %s %p (format %s), %dx%d: "
440 "level %d (%s) %dx%d -> %dx%d, stride %d@0x%08x\n",
442 util_format_short_name(prsc
->format
),
443 prsc
->width0
, prsc
->height0
,
444 i
, tiling_descriptions
[slice
->tiling
],
445 u_minify(prsc
->width0
, i
),
446 u_minify(prsc
->height0
, i
),
447 level_width
, level_height
,
448 slice
->stride
, slice
->offset
);
452 /* UIF/UBLINEAR levels need to be aligned to UIF-blocks, and LT only
453 * needs to be aligned to utile boundaries. Since tiles are laid out
454 * from small to big in memory, we need to align the later UIF slices
455 * to UIF blocks, if they were preceded by non-UIF-block-aligned LT
458 * We additionally align to 4k, which improves UIF XOR performance.
460 uint32_t page_align_offset
= (align(rsc
->slices
[0].offset
, 4096) -
461 rsc
->slices
[0].offset
);
462 if (page_align_offset
) {
463 for (int i
= 0; i
<= prsc
->last_level
; i
++)
464 rsc
->slices
[i
].offset
+= page_align_offset
;
467 /* Arrays, cubes, and 3D textures have a stride which is the distance
468 * from one full mipmap tree to the next (64b aligned).
470 rsc
->cube_map_stride
= align(rsc
->slices
[0].offset
+
471 rsc
->slices
[0].size
, 64);
474 static struct vc5_resource
*
475 vc5_resource_setup(struct pipe_screen
*pscreen
,
476 const struct pipe_resource
*tmpl
)
478 struct vc5_resource
*rsc
= CALLOC_STRUCT(vc5_resource
);
481 struct pipe_resource
*prsc
= &rsc
->base
;
485 pipe_reference_init(&prsc
->reference
, 1);
486 prsc
->screen
= pscreen
;
488 if (prsc
->nr_samples
<= 1) {
489 rsc
->cpp
= util_format_get_blocksize(prsc
->format
);
491 assert(vc5_rt_format_supported(prsc
->format
));
492 uint32_t output_image_format
= vc5_get_rt_format(prsc
->format
);
493 uint32_t internal_type
;
494 uint32_t internal_bpp
;
495 vc5_get_internal_type_bpp_for_output_format(output_image_format
,
498 switch (internal_bpp
) {
499 case INTERNAL_BPP_32
:
502 case INTERNAL_BPP_64
:
505 case INTERNAL_BPP_128
:
517 find_modifier(uint64_t needle
, const uint64_t *haystack
, int count
)
521 for (i
= 0; i
< count
; i
++) {
522 if (haystack
[i
] == needle
)
529 static struct pipe_resource
*
530 vc5_resource_create_with_modifiers(struct pipe_screen
*pscreen
,
531 const struct pipe_resource
*tmpl
,
532 const uint64_t *modifiers
,
535 bool linear_ok
= find_modifier(DRM_FORMAT_MOD_LINEAR
, modifiers
, count
);
536 struct vc5_resource
*rsc
= vc5_resource_setup(pscreen
, tmpl
);
537 struct pipe_resource
*prsc
= &rsc
->base
;
538 /* Use a tiled layout if we can, for better 3D performance. */
539 bool should_tile
= true;
541 /* VBOs/PBOs are untiled (and 1 height). */
542 if (tmpl
->target
== PIPE_BUFFER
)
545 /* Cursors are always linear, and the user can request linear as well.
547 if (tmpl
->bind
& (PIPE_BIND_LINEAR
| PIPE_BIND_CURSOR
))
550 /* 1D and 1D_ARRAY textures are always raster-order. */
551 if (tmpl
->target
== PIPE_TEXTURE_1D
||
552 tmpl
->target
== PIPE_TEXTURE_1D_ARRAY
)
555 /* Scanout BOs for simulator need to be linear for interaction with
558 if (using_vc5_simulator
&&
559 tmpl
->bind
& (PIPE_BIND_SHARED
| PIPE_BIND_SCANOUT
))
562 /* No user-specified modifier; determine our own. */
563 if (count
== 1 && modifiers
[0] == DRM_FORMAT_MOD_INVALID
) {
565 rsc
->tiled
= should_tile
;
566 } else if (should_tile
&&
567 find_modifier(DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED
,
570 } else if (linear_ok
) {
573 fprintf(stderr
, "Unsupported modifier requested\n");
577 if (tmpl
->target
!= PIPE_BUFFER
)
578 rsc
->tex_format
= vc5_get_tex_format(prsc
->format
);
580 vc5_setup_slices(rsc
, "create");
581 if (!vc5_resource_bo_alloc(rsc
))
586 vc5_resource_destroy(pscreen
, prsc
);
590 struct pipe_resource
*
591 vc5_resource_create(struct pipe_screen
*pscreen
,
592 const struct pipe_resource
*tmpl
)
594 const uint64_t mod
= DRM_FORMAT_MOD_INVALID
;
595 return vc5_resource_create_with_modifiers(pscreen
, tmpl
, &mod
, 1);
598 static struct pipe_resource
*
599 vc5_resource_from_handle(struct pipe_screen
*pscreen
,
600 const struct pipe_resource
*tmpl
,
601 struct winsys_handle
*whandle
,
604 struct vc5_screen
*screen
= vc5_screen(pscreen
);
605 struct vc5_resource
*rsc
= vc5_resource_setup(pscreen
, tmpl
);
606 struct pipe_resource
*prsc
= &rsc
->base
;
607 struct vc5_resource_slice
*slice
= &rsc
->slices
[0];
612 switch (whandle
->modifier
) {
613 case DRM_FORMAT_MOD_LINEAR
:
619 "Attempt to import unsupported modifier 0x%llx\n",
620 (long long)whandle
->modifier
);
624 if (whandle
->offset
!= 0) {
626 "Attempt to import unsupported winsys offset %u\n",
631 switch (whandle
->type
) {
632 case DRM_API_HANDLE_TYPE_SHARED
:
633 rsc
->bo
= vc5_bo_open_name(screen
,
634 whandle
->handle
, whandle
->stride
);
636 case DRM_API_HANDLE_TYPE_FD
:
637 rsc
->bo
= vc5_bo_open_dmabuf(screen
,
638 whandle
->handle
, whandle
->stride
);
642 "Attempt to import unsupported handle type %d\n",
650 vc5_setup_slices(rsc
, "import");
652 rsc
->tex_format
= vc5_get_tex_format(prsc
->format
);
654 DBG(V3D_DEBUG_SURFACE
,
655 "rsc import %p (format %s), %dx%d: "
656 "level 0 (R) -> stride %d@0x%08x\n",
657 rsc
, util_format_short_name(prsc
->format
),
658 prsc
->width0
, prsc
->height0
,
659 slice
->stride
, slice
->offset
);
661 if (whandle
->stride
!= slice
->stride
) {
662 static bool warned
= false;
666 "Attempting to import %dx%d %s with "
667 "unsupported stride %d instead of %d\n",
668 prsc
->width0
, prsc
->height0
,
669 util_format_short_name(prsc
->format
),
679 vc5_resource_destroy(pscreen
, prsc
);
683 static struct pipe_surface
*
684 vc5_create_surface(struct pipe_context
*pctx
,
685 struct pipe_resource
*ptex
,
686 const struct pipe_surface
*surf_tmpl
)
688 struct vc5_surface
*surface
= CALLOC_STRUCT(vc5_surface
);
689 struct vc5_resource
*rsc
= vc5_resource(ptex
);
694 assert(surf_tmpl
->u
.tex
.first_layer
== surf_tmpl
->u
.tex
.last_layer
);
696 struct pipe_surface
*psurf
= &surface
->base
;
697 unsigned level
= surf_tmpl
->u
.tex
.level
;
699 pipe_reference_init(&psurf
->reference
, 1);
700 pipe_resource_reference(&psurf
->texture
, ptex
);
702 psurf
->context
= pctx
;
703 psurf
->format
= surf_tmpl
->format
;
704 psurf
->width
= u_minify(ptex
->width0
, level
);
705 psurf
->height
= u_minify(ptex
->height0
, level
);
706 psurf
->u
.tex
.level
= level
;
707 psurf
->u
.tex
.first_layer
= surf_tmpl
->u
.tex
.first_layer
;
708 psurf
->u
.tex
.last_layer
= surf_tmpl
->u
.tex
.last_layer
;
710 surface
->offset
= (rsc
->slices
[level
].offset
+
711 psurf
->u
.tex
.first_layer
* rsc
->cube_map_stride
);
712 surface
->tiling
= rsc
->slices
[level
].tiling
;
713 surface
->format
= vc5_get_rt_format(psurf
->format
);
715 if (util_format_is_depth_or_stencil(psurf
->format
)) {
716 switch (psurf
->format
) {
717 case PIPE_FORMAT_Z16_UNORM
:
718 surface
->internal_type
= INTERNAL_TYPE_DEPTH_16
;
720 case PIPE_FORMAT_Z32_FLOAT
:
721 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
:
722 surface
->internal_type
= INTERNAL_TYPE_DEPTH_32F
;
725 surface
->internal_type
= INTERNAL_TYPE_DEPTH_24
;
729 vc5_get_internal_type_bpp_for_output_format(surface
->format
,
731 surface
->internal_type
= type
;
732 surface
->internal_bpp
= bpp
;
735 return &surface
->base
;
739 vc5_surface_destroy(struct pipe_context
*pctx
, struct pipe_surface
*psurf
)
741 pipe_resource_reference(&psurf
->texture
, NULL
);
746 vc5_flush_resource(struct pipe_context
*pctx
, struct pipe_resource
*resource
)
748 /* All calls to flush_resource are followed by a flush of the context,
749 * so there's nothing to do.
754 vc5_resource_screen_init(struct pipe_screen
*pscreen
)
756 pscreen
->resource_create_with_modifiers
=
757 vc5_resource_create_with_modifiers
;
758 pscreen
->resource_create
= vc5_resource_create
;
759 pscreen
->resource_from_handle
= vc5_resource_from_handle
;
760 pscreen
->resource_get_handle
= vc5_resource_get_handle
;
761 pscreen
->resource_destroy
= vc5_resource_destroy
;
765 vc5_resource_context_init(struct pipe_context
*pctx
)
767 pctx
->transfer_map
= vc5_resource_transfer_map
;
768 pctx
->transfer_flush_region
= u_default_transfer_flush_region
;
769 pctx
->transfer_unmap
= vc5_resource_transfer_unmap
;
770 pctx
->buffer_subdata
= u_default_buffer_subdata
;
771 pctx
->texture_subdata
= u_default_texture_subdata
;
772 pctx
->create_surface
= vc5_create_surface
;
773 pctx
->surface_destroy
= vc5_surface_destroy
;
774 pctx
->resource_copy_region
= util_resource_copy_region
;
775 pctx
->blit
= vc5_blit
;
776 pctx
->flush_resource
= vc5_flush_resource
;