2 * Copyright 2018-2019 Alyssa Rosenzweig
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #include "pan_context.h"
27 #include "pan_format.h"
29 #include "util/u_format.h"
32 panfrost_sfbd_format(struct pipe_surface
*surf
)
35 return 0xb84e0281; /* RGB32, no MSAA */
40 struct panfrost_job
*job
,
41 struct mali_single_framebuffer
*sfbd
)
43 struct panfrost_context
*ctx
= job
->ctx
;
45 if (job
->clear
& PIPE_CLEAR_COLOR
) {
46 sfbd
->clear_color_1
= job
->clear_color
;
47 sfbd
->clear_color_2
= job
->clear_color
;
48 sfbd
->clear_color_3
= job
->clear_color
;
49 sfbd
->clear_color_4
= job
->clear_color
;
52 if (job
->clear
& PIPE_CLEAR_DEPTH
) {
53 sfbd
->clear_depth_1
= job
->clear_depth
;
54 sfbd
->clear_depth_2
= job
->clear_depth
;
55 sfbd
->clear_depth_3
= job
->clear_depth
;
56 sfbd
->clear_depth_4
= job
->clear_depth
;
58 sfbd
->depth_buffer
= ctx
->depth_stencil_buffer
.gpu
;
59 sfbd
->depth_buffer_enable
= MALI_DEPTH_STENCIL_ENABLE
;
62 if (job
->clear
& PIPE_CLEAR_STENCIL
) {
63 sfbd
->clear_stencil
= job
->clear_stencil
;
65 sfbd
->stencil_buffer
= ctx
->depth_stencil_buffer
.gpu
;
66 sfbd
->stencil_buffer_enable
= MALI_DEPTH_STENCIL_ENABLE
;
69 /* Set flags based on what has been cleared, for the SFBD case */
70 /* XXX: What do these flags mean? */
71 int clear_flags
= 0x101100;
73 if (!(job
->clear
& ~(PIPE_CLEAR_COLOR
| PIPE_CLEAR_DEPTH
| PIPE_CLEAR_STENCIL
))) {
74 /* On a tiler like this, it's fastest to clear all three buffers at once */
76 clear_flags
|= MALI_CLEAR_FAST
;
78 clear_flags
|= MALI_CLEAR_SLOW
;
80 if (job
->clear
& PIPE_CLEAR_STENCIL
)
81 clear_flags
|= MALI_CLEAR_SLOW_STENCIL
;
84 sfbd
->clear_flags
= clear_flags
;
88 panfrost_sfbd_set_cbuf(
89 struct mali_single_framebuffer
*fb
,
90 struct pipe_surface
*surf
,
93 struct panfrost_resource
*rsrc
= pan_resource(surf
->texture
);
95 signed stride
= rsrc
->bo
->slices
[0].stride
;
97 fb
->format
= panfrost_sfbd_format(surf
);
99 if (rsrc
->bo
->layout
== PAN_LINEAR
) {
100 mali_ptr framebuffer
= rsrc
->bo
->gpu
;
102 /* The default is upside down from OpenGL's perspective. */
104 framebuffer
+= stride
* (surf
->texture
->height0
- 1);
108 fb
->framebuffer
= framebuffer
;
111 fprintf(stderr
, "Invalid render layout\n");
116 /* Creates an SFBD for the FRAGMENT section of the bound framebuffer */
119 panfrost_sfbd_fragment(struct panfrost_context
*ctx
, bool flip_y
)
121 struct panfrost_job
*job
= panfrost_get_job_for_fbo(ctx
);
122 struct mali_single_framebuffer fb
= panfrost_emit_sfbd(ctx
);
124 panfrost_sfbd_clear(job
, &fb
);
126 /* SFBD does not support MRT natively; sanity check */
127 assert(ctx
->pipe_framebuffer
.nr_cbufs
== 1);
128 panfrost_sfbd_set_cbuf(&fb
, ctx
->pipe_framebuffer
.cbufs
[0], flip_y
);
130 if (ctx
->pipe_framebuffer
.zsbuf
) {
134 if (job
->requirements
& PAN_REQ_MSAA
)
135 fb
.format
|= MALI_FRAMEBUFFER_MSAA_A
| MALI_FRAMEBUFFER_MSAA_B
;
137 return panfrost_upload_transient(ctx
, &fb
, sizeof(fb
)) | MALI_SFBD
;