xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_state_need_swtnl.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "util/u_inlines.h"
9 #include "pipe/p_state.h"
10 #include "svga_context.h"
11 #include "svga_shader.h"
12 #include "svga_state.h"
13 #include "svga_debug.h"
14 #include "svga_hw_reg.h"
15 
16 
17 static enum pipe_error
update_need_swvfetch(struct svga_context * svga,uint64_t dirty)18 update_need_swvfetch(struct svga_context *svga, uint64_t dirty)
19 {
20    if (!svga->curr.velems) {
21       /* No vertex elements bound. */
22       return PIPE_OK;
23    }
24 
25    if (svga->state.sw.need_swvfetch != svga->curr.velems->need_swvfetch) {
26       svga->state.sw.need_swvfetch = svga->curr.velems->need_swvfetch;
27       svga->dirty |= SVGA_NEW_NEED_SWVFETCH;
28    }
29 
30    return PIPE_OK;
31 }
32 
33 struct svga_tracked_state svga_update_need_swvfetch =
34 {
35    "update need_swvfetch",
36    ( SVGA_NEW_VELEMENT ),
37    update_need_swvfetch
38 };
39 
40 
41 
42 static enum pipe_error
update_need_pipeline(struct svga_context * svga,uint64_t dirty)43 update_need_pipeline(struct svga_context *svga, uint64_t dirty)
44 {
45    bool need_pipeline = false;
46    struct svga_vertex_shader *vs = svga->curr.vs;
47    const char *reason = "";
48 
49    /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
50     */
51    if (svga->curr.rast &&
52        (svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim))) {
53       SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (0x%x) & prim (0x%x)\n",
54                  __func__,
55                  svga->curr.rast->need_pipeline,
56                  (1 << svga->curr.reduced_prim) );
57       SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline tris (%s), lines (%s), points (%s)\n",
58                  __func__,
59                  svga->curr.rast->need_pipeline_tris_str,
60                  svga->curr.rast->need_pipeline_lines_str,
61                  svga->curr.rast->need_pipeline_points_str);
62       need_pipeline = true;
63 
64       switch (svga->curr.reduced_prim) {
65       case MESA_PRIM_POINTS:
66          reason = svga->curr.rast->need_pipeline_points_str;
67          break;
68       case MESA_PRIM_LINES:
69          reason = svga->curr.rast->need_pipeline_lines_str;
70          break;
71       case MESA_PRIM_TRIANGLES:
72          reason = svga->curr.rast->need_pipeline_tris_str;
73          break;
74       default:
75          assert(!"Unexpected reduced prim type");
76       }
77    }
78 
79    /* EDGEFLAGS
80     */
81     if (vs && vs->base.info.writes_edgeflag) {
82       SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __func__);
83       need_pipeline = true;
84       reason = "edge flags";
85    }
86 
87    /* SVGA_NEW_FS, SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
88     */
89    if (svga->curr.rast && svga->curr.reduced_prim == MESA_PRIM_POINTS) {
90       unsigned sprite_coord_gen = svga->curr.rast->templ.sprite_coord_enable;
91       unsigned generic_inputs =
92          svga->curr.fs ? svga->curr.fs->generic_inputs : 0;
93 
94       if (!svga_have_vgpu10(svga) && sprite_coord_gen &&
95           (generic_inputs & ~sprite_coord_gen)) {
96          /* The fragment shader is using some generic inputs that are
97           * not being replaced by auto-generated point/sprite coords (and
98           * auto sprite coord generation is turned on).
99           * The SVGA3D interface does not support that: if we enable
100           * SVGA3D_RS_POINTSPRITEENABLE it gets enabled for _all_
101           * texture coordinate sets.
102           * To solve this, we have to use the draw-module's wide/sprite
103           * point stage.
104           */
105          need_pipeline = true;
106          reason = "point sprite coordinate generation";
107       }
108    }
109 
110    if (need_pipeline != svga->state.sw.need_pipeline) {
111       svga->state.sw.need_pipeline = need_pipeline;
112       svga->dirty |= SVGA_NEW_NEED_PIPELINE;
113    }
114 
115    /* debug */
116    if (0 && svga->state.sw.need_pipeline)
117       debug_printf("sw.need_pipeline = %d\n", svga->state.sw.need_pipeline);
118 
119    if (svga->state.sw.need_pipeline) {
120       assert(reason);
121       util_debug_message(&svga->debug.callback, FALLBACK,
122                          "Using semi-fallback for %s", reason);
123    }
124 
125    return PIPE_OK;
126 }
127 
128 
129 struct svga_tracked_state svga_update_need_pipeline =
130 {
131    "need pipeline",
132    (SVGA_NEW_RAST |
133     SVGA_NEW_FS |
134     SVGA_NEW_VS |
135     SVGA_NEW_REDUCED_PRIMITIVE),
136    update_need_pipeline
137 };
138 
139 
140 static enum pipe_error
update_need_swtnl(struct svga_context * svga,uint64_t dirty)141 update_need_swtnl(struct svga_context *svga, uint64_t dirty)
142 {
143    bool need_swtnl;
144 
145    if (svga->debug.no_swtnl) {
146       svga->state.sw.need_swvfetch = false;
147       svga->state.sw.need_pipeline = false;
148    }
149 
150    need_swtnl = (svga->state.sw.need_swvfetch ||
151                  svga->state.sw.need_pipeline);
152 
153    if (svga->debug.force_swtnl) {
154       need_swtnl = true;
155    }
156 
157    /*
158     * Some state changes the draw module does makes us believe we
159     * we don't need swtnl. This causes the vdecl code to pickup
160     * the wrong buffers and vertex formats. Try trivial/line-wide.
161     */
162    if (svga->state.sw.in_swtnl_draw)
163       need_swtnl = true;
164 
165    if (need_swtnl != svga->state.sw.need_swtnl) {
166       SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF,
167                "%s: need_swvfetch %s, need_pipeline %s\n",
168                __func__,
169                svga->state.sw.need_swvfetch ? "true" : "false",
170                svga->state.sw.need_pipeline ? "true" : "false");
171 
172       svga->state.sw.need_swtnl = need_swtnl;
173       svga->dirty |= SVGA_NEW_NEED_SWTNL;
174       svga->swtnl.new_vdecl = true;
175    }
176 
177    return PIPE_OK;
178 }
179 
180 
181 struct svga_tracked_state svga_update_need_swtnl =
182 {
183    "need swtnl",
184    (SVGA_NEW_NEED_PIPELINE |
185     SVGA_NEW_NEED_SWVFETCH),
186    update_need_swtnl
187 };
188