xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.cc (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2016 Rob Clark <[email protected]>
3  * Copyright © 2018 Google, Inc.
4  * SPDX-License-Identifier: MIT
5  *
6  * Authors:
7  *    Rob Clark <[email protected]>
8  */
9 
10 #define FD_BO_NO_HARDPIN 1
11 
12 #include "pipe/p_state.h"
13 #include "util/u_memory.h"
14 #include "util/u_string.h"
15 
16 #include "freedreno_state.h"
17 
18 #include "fd6_context.h"
19 #include "fd6_pack.h"
20 #include "fd6_rasterizer.h"
21 
22 template <chip CHIP>
23 struct fd_ringbuffer *
__fd6_setup_rasterizer_stateobj(struct fd_context * ctx,const struct pipe_rasterizer_state * cso,bool primitive_restart)24 __fd6_setup_rasterizer_stateobj(struct fd_context *ctx,
25                                 const struct pipe_rasterizer_state *cso,
26                                 bool primitive_restart)
27 {
28    unsigned ndwords = (CHIP >= A7XX) ? 66 : 26;
29    struct fd_ringbuffer *ring = fd_ringbuffer_new_object(ctx->pipe, ndwords * 4);
30    float psize_min, psize_max;
31 
32    if (cso->point_size_per_vertex) {
33       psize_min = util_get_min_point_size(cso);
34       psize_max = 4092;
35    } else {
36       /* Force the point size to be as if the vertex output was disabled. */
37       psize_min = cso->point_size;
38       psize_max = cso->point_size;
39    }
40 
41    OUT_REG(ring,
42            A6XX_GRAS_CL_CNTL(
43                  .znear_clip_disable = !cso->depth_clip_near,
44                  .zfar_clip_disable = !cso->depth_clip_far,
45                  .z_clamp_enable = cso->depth_clamp || CHIP >= A7XX,
46                  .zero_gb_scale_z = cso->clip_halfz,
47                  .vp_clip_code_ignore = 1,
48            ),
49    );
50 
51    OUT_REG(ring,
52            A6XX_GRAS_SU_CNTL(
53                  .cull_front = cso->cull_face & PIPE_FACE_FRONT,
54                  .cull_back = cso->cull_face & PIPE_FACE_BACK,
55                  .front_cw = !cso->front_ccw,
56                  .linehalfwidth = cso->line_width / 2.0f,
57                  .poly_offset = cso->offset_tri,
58                  .line_mode = cso->multisample ? RECTANGULAR : BRESENHAM,
59            ),
60    );
61 
62    OUT_REG(ring,
63            A6XX_GRAS_SU_POINT_MINMAX(.min = psize_min, .max = psize_max, ),
64            A6XX_GRAS_SU_POINT_SIZE(cso->point_size));
65 
66    OUT_REG(ring, A6XX_GRAS_SU_POLY_OFFSET_SCALE(cso->offset_scale),
67            A6XX_GRAS_SU_POLY_OFFSET_OFFSET(cso->offset_units),
68            A6XX_GRAS_SU_POLY_OFFSET_OFFSET_CLAMP(cso->offset_clamp));
69 
70    OUT_REG(ring,
71            A6XX_PC_PRIMITIVE_CNTL_0(
72                  .primitive_restart = primitive_restart,
73                  .provoking_vtx_last = !cso->flatshade_first,
74            ),
75    );
76 
77    if (CHIP >= A7XX) {
78       OUT_REG(ring,
79               A7XX_VPC_PRIMITIVE_CNTL_0(
80                     .primitive_restart = primitive_restart,
81                     .provoking_vtx_last = !cso->flatshade_first,
82               ),
83       );
84    }
85 
86    enum a6xx_polygon_mode mode = POLYMODE6_TRIANGLES;
87    switch (cso->fill_front) {
88    case PIPE_POLYGON_MODE_POINT:
89       mode = POLYMODE6_POINTS;
90       break;
91    case PIPE_POLYGON_MODE_LINE:
92       mode = POLYMODE6_LINES;
93       break;
94    default:
95       assert(cso->fill_front == PIPE_POLYGON_MODE_FILL);
96       break;
97    }
98 
99    OUT_REG(ring, A6XX_VPC_POLYGON_MODE(mode));
100    OUT_REG(ring, PC_POLYGON_MODE(CHIP, mode));
101 
102    if (CHIP == A7XX) {
103       OUT_REG(ring, A7XX_VPC_POLYGON_MODE2(mode));
104    }
105 
106    /* With a7xx the hw doesn't do the clamping for us.  When depth clamp
107     * is enabled, this gets emitted in fd6_emit_non_ring() due to
108     * dependency on viewport state.  But when it is disabled there is
109     * no dependency on external state (other than to know the max
110     * number of viewports, here we just assume the max) so we can emit
111     * this state here:
112     */
113    if (CHIP >= A7XX && !fd_rast_depth_clamp_enabled(cso)) {
114       /* We must assume the max: */
115       const unsigned num_viewports = 16;
116 
117       OUT_PKT4(ring, REG_A6XX_GRAS_CL_Z_CLAMP(0), num_viewports * 2);
118       for (unsigned i = 0; i < num_viewports; i++) {
119          OUT_RING(ring, fui(0.0f));
120          OUT_RING(ring, fui(1.0f));
121       }
122 
123       OUT_REG(ring,
124          A6XX_RB_Z_CLAMP_MIN(0.0f),
125          A6XX_RB_Z_CLAMP_MAX(1.0),
126       );
127    }
128 
129    if (CHIP == A6XX && ctx->screen->info->a6xx.has_shading_rate) {
130       OUT_REG(ring, A6XX_RB_UNKNOWN_8A00());
131       OUT_REG(ring, A6XX_RB_UNKNOWN_8A10());
132       OUT_REG(ring, A6XX_RB_UNKNOWN_8A20());
133       OUT_REG(ring, A6XX_RB_UNKNOWN_8A30());
134    }
135 
136    return ring;
137 }
138 FD_GENX(__fd6_setup_rasterizer_stateobj);
139 
140 void *
fd6_rasterizer_state_create(struct pipe_context * pctx,const struct pipe_rasterizer_state * cso)141 fd6_rasterizer_state_create(struct pipe_context *pctx,
142                             const struct pipe_rasterizer_state *cso)
143 {
144    struct fd6_rasterizer_stateobj *so;
145 
146    so = CALLOC_STRUCT(fd6_rasterizer_stateobj);
147    if (!so)
148       return NULL;
149 
150    so->base = *cso;
151 
152    return so;
153 }
154 
155 void
fd6_rasterizer_state_delete(struct pipe_context * pctx,void * hwcso)156 fd6_rasterizer_state_delete(struct pipe_context *pctx, void *hwcso)
157 {
158    struct fd6_rasterizer_stateobj *so = (struct fd6_rasterizer_stateobj *)hwcso;
159 
160    for (unsigned i = 0; i < ARRAY_SIZE(so->stateobjs); i++)
161       if (so->stateobjs[i])
162          fd_ringbuffer_del(so->stateobjs[i]);
163 
164    FREE(hwcso);
165 }
166