2 * Copyright (C) 2018 Rob Clark <robclark@freedesktop.org>
3 * Copyright © 2018 Google, Inc.
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 FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Rob Clark <robclark@freedesktop.org>
28 #include "drm-uapi/drm_fourcc.h"
30 #include "fd6_resource.h"
31 #include "fd6_format.h"
35 /* A subset of the valid tiled formats can be compressed. We do
36 * already require tiled in order to be compressed, but just because
37 * it can be tiled doesn't mean it can be compressed.
40 ok_ubwc_format(struct fd_resource
*rsc
, enum pipe_format pfmt
)
42 /* NOTE: both x24s8 and z24s8 map to RB6_X8Z24_UNORM, but UBWC
43 * does not seem to work properly when sampling x24s8.. possibly
44 * because we sample it as TFMT6_8_8_8_8_UINT.
46 * This could possibly be a hw limitation, or maybe something
47 * else wrong somewhere (although z24s8 blits and sampling with
48 * UBWC seem fine). Recheck on a later revision of a6xx
50 if (pfmt
== PIPE_FORMAT_X24S8_UINT
)
53 /* We don't fully understand what's going wrong with this combination, but
54 * we haven't been able to make it work. It's enough of a corner-case
55 * that we can just disable UBWC for these resources.
57 if (rsc
->base
.target
!= PIPE_TEXTURE_2D
&&
58 pfmt
== PIPE_FORMAT_Z24_UNORM_S8_UINT
)
61 switch (fd6_pipe2color(pfmt
)) {
62 case FMT6_10_10_10_2_UINT
:
63 case FMT6_10_10_10_2_UNORM_DEST
:
64 case FMT6_11_11_10_FLOAT
:
66 case FMT6_16_16_16_16_FLOAT
:
67 case FMT6_16_16_16_16_SINT
:
68 case FMT6_16_16_16_16_UINT
:
69 case FMT6_16_16_FLOAT
:
74 case FMT6_32_32_32_32_SINT
:
75 case FMT6_32_32_32_32_UINT
:
78 case FMT6_5_6_5_UNORM
:
79 case FMT6_8_8_8_8_SINT
:
80 case FMT6_8_8_8_8_UINT
:
81 case FMT6_8_8_8_8_UNORM
:
82 case FMT6_8_8_8_X8_UNORM
:
87 case FMT6_Z24_UNORM_S8_UINT
:
88 case FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8
:
96 * Ensure the rsc is in an ok state to be used with the specified format.
97 * This handles the case of UBWC buffers used with non-UBWC compatible
98 * formats, by triggering an uncompress.
101 fd6_validate_format(struct fd_context
*ctx
, struct fd_resource
*rsc
,
102 enum pipe_format format
)
104 if (!rsc
->layout
.ubwc
)
107 if (ok_ubwc_format(rsc
, format
))
110 fd_resource_uncompress(ctx
, rsc
);
114 setup_lrz(struct fd_resource
*rsc
)
116 struct fd_screen
*screen
= fd_screen(rsc
->base
.screen
);
117 const uint32_t flags
= DRM_FREEDRENO_GEM_CACHE_WCOMBINE
|
118 DRM_FREEDRENO_GEM_TYPE_KMEM
; /* TODO */
119 unsigned width0
= rsc
->base
.width0
;
120 unsigned height0
= rsc
->base
.height0
;
122 /* LRZ buffer is super-sampled: */
123 switch (rsc
->base
.nr_samples
) {
131 unsigned lrz_pitch
= align(DIV_ROUND_UP(width0
, 8), 32);
132 unsigned lrz_height
= align(DIV_ROUND_UP(height0
, 8), 16);
134 unsigned size
= lrz_pitch
* lrz_height
* 2;
136 rsc
->lrz_height
= lrz_height
;
137 rsc
->lrz_width
= lrz_pitch
;
138 rsc
->lrz_pitch
= lrz_pitch
;
139 rsc
->lrz
= fd_bo_new(screen
->dev
, size
, flags
, "lrz");
143 fd6_setup_slices(struct fd_resource
*rsc
)
145 struct pipe_resource
*prsc
= &rsc
->base
;
147 if (!(fd_mesa_debug
& FD_DBG_NOLRZ
) && has_depth(rsc
->base
.format
))
150 if (rsc
->layout
.ubwc
&& !ok_ubwc_format(rsc
, rsc
->base
.format
))
151 rsc
->layout
.ubwc
= false;
153 fdl6_layout(&rsc
->layout
, prsc
->format
, fd_resource_nr_samples(prsc
),
154 prsc
->width0
, prsc
->height0
, prsc
->depth0
,
155 prsc
->last_level
+ 1, prsc
->array_size
,
156 prsc
->target
== PIPE_TEXTURE_3D
,
159 return rsc
->layout
.size
;
163 fill_ubwc_buffer_sizes(struct fd_resource
*rsc
)
165 struct pipe_resource
*prsc
= &rsc
->base
;
166 struct fdl_slice slice
= *fd_resource_slice(rsc
, 0);
168 /* limit things to simple single level 2d for now: */
169 if ((prsc
->depth0
!= 1) || (prsc
->array_size
!= 1) || (prsc
->last_level
!= 0))
171 if (prsc
->target
!= PIPE_TEXTURE_2D
)
173 if (!ok_ubwc_format(rsc
, prsc
->format
))
176 rsc
->layout
.ubwc
= true;
177 rsc
->layout
.tile_mode
= TILE6_3
;
179 if (!fdl6_layout(&rsc
->layout
, prsc
->format
, fd_resource_nr_samples(prsc
),
180 prsc
->width0
, prsc
->height0
, prsc
->depth0
,
181 prsc
->last_level
+ 1, prsc
->array_size
, false, &slice
))
184 if (rsc
->layout
.size
> fd_bo_size(rsc
->bo
))
191 fd6_layout_resource_for_modifier(struct fd_resource
*rsc
, uint64_t modifier
)
194 case DRM_FORMAT_MOD_QCOM_COMPRESSED
:
195 return fill_ubwc_buffer_sizes(rsc
);
196 case DRM_FORMAT_MOD_LINEAR
:
197 case DRM_FORMAT_MOD_INVALID
:
204 static const uint64_t supported_modifiers
[] = {
205 DRM_FORMAT_MOD_LINEAR
,
206 DRM_FORMAT_MOD_QCOM_COMPRESSED
,
210 fd6_resource_screen_init(struct pipe_screen
*pscreen
)
212 struct fd_screen
*screen
= fd_screen(pscreen
);
214 screen
->setup_slices
= fd6_setup_slices
;
215 screen
->layout_resource_for_modifier
= fd6_layout_resource_for_modifier
;
216 screen
->supported_modifiers
= supported_modifiers
;
217 screen
->num_supported_modifiers
= ARRAY_SIZE(supported_modifiers
);