2 * Copyright (C) 2018 Alyssa Rosenzweig
3 * Copyright (C) 2020 Collabora Ltd.
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 #include "pan_allocate.h"
26 #include "pan_cmdstream.h"
27 #include "pan_context.h"
31 panfrost_mali_viewport_init(struct panfrost_context
*ctx
,
32 struct mali_viewport
*mvp
)
34 const struct pipe_viewport_state
*vp
= &ctx
->pipe_viewport
;
36 /* Clip bounds are encoded as floats. The viewport itself is encoded as
37 * (somewhat) asymmetric ints. */
39 const struct pipe_scissor_state
*ss
= &ctx
->scissor
;
41 memset(mvp
, 0, sizeof(*mvp
));
43 /* By default, do no viewport clipping, i.e. clip to (-inf, inf) in
44 * each direction. Clipping to the viewport in theory should work, but
45 * in practice causes issues when we're not explicitly trying to
48 *mvp
= (struct mali_viewport
) {
49 .clip_minx
= -INFINITY
,
50 .clip_miny
= -INFINITY
,
51 .clip_maxx
= INFINITY
,
52 .clip_maxy
= INFINITY
,
55 /* Always scissor to the viewport by default. */
56 float vp_minx
= (int) (vp
->translate
[0] - fabsf(vp
->scale
[0]));
57 float vp_maxx
= (int) (vp
->translate
[0] + fabsf(vp
->scale
[0]));
59 float vp_miny
= (int) (vp
->translate
[1] - fabsf(vp
->scale
[1]));
60 float vp_maxy
= (int) (vp
->translate
[1] + fabsf(vp
->scale
[1]));
62 float minz
= (vp
->translate
[2] - fabsf(vp
->scale
[2]));
63 float maxz
= (vp
->translate
[2] + fabsf(vp
->scale
[2]));
65 /* Apply the scissor test */
67 unsigned minx
, miny
, maxx
, maxy
;
69 if (ss
&& ctx
->rasterizer
&& ctx
->rasterizer
->base
.scissor
) {
70 minx
= MAX2(ss
->minx
, vp_minx
);
71 miny
= MAX2(ss
->miny
, vp_miny
);
72 maxx
= MIN2(ss
->maxx
, vp_maxx
);
73 maxy
= MIN2(ss
->maxy
, vp_maxy
);
81 /* Hardware needs the min/max to be strictly ordered, so flip if we
82 * need to. The viewport transformation in the vertex shader will
83 * handle the negatives if we don't */
103 /* Clamp to the framebuffer size as a last check */
105 minx
= MIN2(ctx
->pipe_framebuffer
.width
, minx
);
106 maxx
= MIN2(ctx
->pipe_framebuffer
.width
, maxx
);
108 miny
= MIN2(ctx
->pipe_framebuffer
.height
, miny
);
109 maxy
= MIN2(ctx
->pipe_framebuffer
.height
, maxy
);
113 mvp
->viewport0
[0] = minx
;
114 mvp
->viewport1
[0] = MALI_POSITIVE(maxx
);
116 mvp
->viewport0
[1] = miny
;
117 mvp
->viewport1
[1] = MALI_POSITIVE(maxy
);
119 mvp
->clip_minz
= minz
;
120 mvp
->clip_maxz
= maxz
;
124 panfrost_emit_viewport(struct panfrost_batch
*batch
,
125 struct midgard_payload_vertex_tiler
*tp
)
127 struct panfrost_context
*ctx
= batch
->ctx
;
128 struct mali_viewport mvp
;
130 panfrost_mali_viewport_init(batch
->ctx
, &mvp
);
132 /* Update the job, unless we're doing wallpapering (whose lack of
133 * scissor we can ignore, since if we "miss" a tile of wallpaper, it'll
134 * just... be faster :) */
136 if (!ctx
->wallpaper_batch
)
137 panfrost_batch_union_scissor(batch
, mvp
.viewport0
[0],
139 mvp
.viewport1
[0] + 1,
140 mvp
.viewport1
[1] + 1);
142 tp
->postfix
.viewport
= panfrost_upload_transient(batch
, &mvp
,