xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/llvmpipe/lp_rast_linear.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2009-2021 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include <limits.h>
29 #include "util/u_memory.h"
30 #include "util/u_math.h"
31 #include "util/u_rect.h"
32 #include "util/u_surface.h"
33 #include "util/u_pack_color.h"
34 
35 #include "lp_scene_queue.h"
36 #include "lp_debug.h"
37 #include "lp_fence.h"
38 #include "lp_perf.h"
39 #include "lp_query.h"
40 #include "lp_rast.h"
41 #include "lp_rast_priv.h"
42 #include "lp_scene.h"
43 
44 
45 static void
lp_rast_linear_clear(struct lp_rasterizer_task * task,const union lp_rast_cmd_arg arg)46 lp_rast_linear_clear(struct lp_rasterizer_task *task,
47                      const union lp_rast_cmd_arg arg)
48 {
49    LP_DBG(DEBUG_RAST, "%s\n", __func__);
50 
51    union util_color uc = arg.clear_rb->color_val;
52 
53    const struct lp_scene *scene = task->scene;
54    util_fill_rect(scene->cbufs[0].map,
55                   PIPE_FORMAT_B8G8R8A8_UNORM,
56                   scene->cbufs[0].stride,
57                   task->x,
58                   task->y,
59                   task->width,
60                   task->height,
61                   &uc);
62 }
63 
64 
65 /* Run the scanline version of the shader across the whole tile.
66  */
67 static void
lp_rast_linear_tile(struct lp_rasterizer_task * task,const union lp_rast_cmd_arg arg)68 lp_rast_linear_tile(struct lp_rasterizer_task *task,
69                     const union lp_rast_cmd_arg arg)
70 {
71    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
72    if (inputs->disable)
73       return;
74 
75    const struct lp_rast_state *state = task->state;
76    assert(state);
77    if (!state) {
78       return;
79    }
80 
81    const struct lp_fragment_shader_variant *variant = state->variant;
82    const struct lp_scene *scene = task->scene;
83 
84    if (variant->jit_linear_blit && inputs->is_blit) {
85       if (variant->jit_linear_blit(state,
86                                    task->x,
87                                    task->y,
88                                    task->width,
89                                    task->height,
90                                    GET_A0(inputs),
91                                    GET_DADX(inputs),
92                                    GET_DADY(inputs),
93                                    scene->cbufs[0].map,
94                                    scene->cbufs[0].stride))
95          return;
96    }
97 
98    if (variant->jit_linear) {
99       if (variant->jit_linear(state,
100                               task->x,
101                               task->y,
102                               task->width,
103                               task->height,
104                               GET_A0(inputs),
105                               GET_DADX(inputs),
106                               GET_DADY(inputs),
107                               scene->cbufs[0].map,
108                               scene->cbufs[0].stride))
109          return;
110    }
111 
112    {
113       struct u_rect box;
114       box.x0 = task->x;
115       box.x1 = task->x + task->width - 1;
116       box.y0 = task->y;
117       box.y1 = task->y + task->height - 1;
118       lp_rast_linear_rect_fallback(task, inputs, &box);
119    }
120 }
121 
122 
123 /* Run the scanline version of the shader on a rectangle within the
124  * tile.
125  */
126 static void
lp_rast_linear_rect(struct lp_rasterizer_task * task,const union lp_rast_cmd_arg arg)127 lp_rast_linear_rect(struct lp_rasterizer_task *task,
128                     const union lp_rast_cmd_arg arg)
129 {
130    const struct lp_scene *scene = task->scene;
131    const struct lp_rast_rectangle *rect = arg.rectangle;
132    const struct lp_rast_shader_inputs *inputs = &rect->inputs;
133 
134    if (inputs->disable)
135       return;
136 
137    struct u_rect box;
138    box.x0 = task->x;
139    box.y0 = task->y;
140    box.x1 = task->x + task->width - 1;
141    box.y1 = task->y + task->height - 1;
142 
143    u_rect_find_intersection(&rect->box, &box);
144 
145    const int width  = box.x1 - box.x0 + 1;
146    const int height = box.y1 - box.y0 + 1;
147 
148    /* Note that blit primitives can end up in the non-full-tile path,
149     * the binner currently doesn't try to classify sub-tile
150     * primitives.  Can detect them here though.
151     */
152    const struct lp_rast_state *state = task->state;
153    struct lp_fragment_shader_variant *variant = state->variant;
154    if (variant->jit_linear_blit && inputs->is_blit) {
155       if (variant->jit_linear_blit(state,
156                                    box.x0, box.y0,
157                                    width, height,
158                                    GET_A0(inputs),
159                                    GET_DADX(inputs),
160                                    GET_DADY(inputs),
161                                    scene->cbufs[0].map,
162                                    scene->cbufs[0].stride)) {
163          return;
164       }
165    }
166 
167    if (variant->jit_linear) {
168       if (variant->jit_linear(state,
169                               box.x0, box.y0,
170                               width, height,
171                               GET_A0(inputs),
172                               GET_DADX(inputs),
173                               GET_DADY(inputs),
174                               scene->cbufs[0].map,
175                               scene->cbufs[0].stride)) {
176          return;
177       }
178    }
179 
180    lp_rast_linear_rect_fallback(task, inputs, &box);
181 }
182 
183 
184 static const lp_rast_cmd_func
185 dispatch_linear[] = {
186    lp_rast_linear_clear,        /* clear_color */
187    NULL,                        /* clear_zstencil */
188    NULL,                        /* triangle_1 */
189    NULL,                        /* triangle_2 */
190    NULL,                        /* triangle_3 */
191    NULL,                        /* triangle_4 */
192    NULL,                        /* triangle_5 */
193    NULL,                        /* triangle_6 */
194    NULL,                        /* triangle_7 */
195    NULL,                        /* triangle_8 */
196    NULL,                        /* triangle_3_4 */
197    NULL,                        /* triangle_3_16 */
198    NULL,                        /* triangle_4_16 */
199    lp_rast_linear_tile,         /* shade_tile */
200    lp_rast_linear_tile,         /* shade_tile_opaque */
201    NULL,                        /* begin_query */
202    NULL,                        /* end_query */
203    lp_rast_set_state,           /* set_state */
204    NULL,                        /* lp_rast_triangle_32_1 */
205    NULL,                        /* lp_rast_triangle_32_2 */
206    NULL,                        /* lp_rast_triangle_32_3 */
207    NULL,                        /* lp_rast_triangle_32_4 */
208    NULL,                        /* lp_rast_triangle_32_5 */
209    NULL,                        /* lp_rast_triangle_32_6 */
210    NULL,                        /* lp_rast_triangle_32_7 */
211    NULL,                        /* lp_rast_triangle_32_8 */
212    NULL,                        /* lp_rast_triangle_32_3_4 */
213    NULL,                        /* lp_rast_triangle_32_3_16 */
214    NULL,                        /* lp_rast_triangle_32_4_16 */
215 
216    NULL,                        /* lp_rast_triangle_ms_1 */
217    NULL,                        /* lp_rast_triangle_ms_2 */
218    NULL,                        /* lp_rast_triangle_ms_3 */
219    NULL,                        /* lp_rast_triangle_ms_4 */
220    NULL,                        /* lp_rast_triangle_ms_5 */
221    NULL,                        /* lp_rast_triangle_ms_6 */
222    NULL,                        /* lp_rast_triangle_ms_7 */
223    NULL,                        /* lp_rast_triangle_ms_8 */
224    NULL,                        /* lp_rast_triangle_ms_3_4 */
225    NULL,                        /* lp_rast_triangle_ms_3_16 */
226    NULL,                        /* lp_rast_triangle_ms_4_16 */
227 
228    lp_rast_linear_rect,         /* rect */
229    lp_rast_linear_tile,         /* blit */
230 };
231 
232 
233 /* Assumptions for this path:
234  *   - Single color buffer, PIPE_FORMAT_B8G8R8A8_UNORM
235  *   - No depth buffer
236  *   - All primitives in bins are rect, tile, blit or clear.
237  *   - All shaders have a linear variant.
238  */
239 void
lp_linear_rasterize_bin(struct lp_rasterizer_task * task,const struct cmd_bin * bin)240 lp_linear_rasterize_bin(struct lp_rasterizer_task *task,
241                         const struct cmd_bin *bin)
242 {
243    STATIC_ASSERT(ARRAY_SIZE(dispatch_linear) == LP_RAST_OP_MAX);
244 
245    if (0) debug_printf("%s\n", __func__);
246 
247    const struct cmd_block *block;
248    for (block = bin->head; block; block = block->next) {
249       for (unsigned k = 0; k < block->count; k++) {
250          assert(dispatch_linear[block->cmd[k]]);
251          dispatch_linear[block->cmd[k]](task, block->arg[k]);
252       }
253    }
254 }
255