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