lima_draw.c revision 7ec681f3
1/*
2 * Copyright (c) 2011-2013 Luc Verhaegen <libv@skynet.be>
3 * Copyright (c) 2017-2019 Lima Project
4 *
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, sub license,
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:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
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 NON-INFRINGEMENT. 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
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26#include "util/format/u_format.h"
27#include "util/u_debug.h"
28#include "util/u_draw.h"
29#include "util/half_float.h"
30#include "util/u_helpers.h"
31#include "util/u_inlines.h"
32#include "util/u_pack_color.h"
33#include "util/u_split_draw.h"
34#include "util/u_upload_mgr.h"
35#include "util/u_prim.h"
36#include "util/u_vbuf.h"
37#include "util/hash_table.h"
38
39#include "lima_context.h"
40#include "lima_screen.h"
41#include "lima_resource.h"
42#include "lima_program.h"
43#include "lima_bo.h"
44#include "lima_job.h"
45#include "lima_texture.h"
46#include "lima_util.h"
47#include "lima_gpu.h"
48
49#include "pan_minmax_cache.h"
50
51#include <drm-uapi/lima_drm.h>
52
53static void
54lima_clip_scissor_to_viewport(struct lima_context *ctx)
55{
56   struct lima_context_framebuffer *fb = &ctx->framebuffer;
57   struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
58   int viewport_left, viewport_right, viewport_bottom, viewport_top;
59
60   if (ctx->rasterizer && ctx->rasterizer->base.scissor) {
61      struct pipe_scissor_state *scissor = &ctx->scissor;
62      cscissor->minx = scissor->minx;
63      cscissor->maxx = scissor->maxx;
64      cscissor->miny = scissor->miny;
65      cscissor->maxy = scissor->maxy;
66   } else {
67      cscissor->minx = 0;
68      cscissor->maxx = fb->base.width;
69      cscissor->miny = 0;
70      cscissor->maxy = fb->base.height;
71   }
72
73   viewport_left = MAX2(ctx->viewport.left, 0);
74   cscissor->minx = MAX2(cscissor->minx, viewport_left);
75   viewport_right = MIN2(MAX2(ctx->viewport.right, 0), fb->base.width);
76   cscissor->maxx = MIN2(cscissor->maxx, viewport_right);
77   if (cscissor->minx > cscissor->maxx)
78      cscissor->minx = cscissor->maxx;
79
80   viewport_bottom = MAX2(ctx->viewport.bottom, 0);
81   cscissor->miny = MAX2(cscissor->miny, viewport_bottom);
82   viewport_top = MIN2(MAX2(ctx->viewport.top, 0), fb->base.height);
83   cscissor->maxy = MIN2(cscissor->maxy, viewport_top);
84   if (cscissor->miny > cscissor->maxy)
85      cscissor->miny = cscissor->maxy;
86}
87
88static bool
89lima_is_scissor_zero(struct lima_context *ctx)
90{
91   struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
92
93   return cscissor->minx == cscissor->maxx || cscissor->miny == cscissor->maxy;
94}
95
96static void
97lima_update_job_wb(struct lima_context *ctx, unsigned buffers)
98{
99   struct lima_job *job = lima_job_get(ctx);
100   struct lima_context_framebuffer *fb = &ctx->framebuffer;
101
102   /* add to job when the buffer is dirty and resolve is clear (not added before) */
103   if (fb->base.nr_cbufs && (buffers & PIPE_CLEAR_COLOR0) &&
104       !(job->resolve & PIPE_CLEAR_COLOR0)) {
105      struct lima_resource *res = lima_resource(fb->base.cbufs[0]->texture);
106      lima_flush_job_accessing_bo(ctx, res->bo, true);
107      _mesa_hash_table_insert(ctx->write_jobs, &res->base, job);
108      lima_job_add_bo(job, LIMA_PIPE_PP, res->bo, LIMA_SUBMIT_BO_WRITE);
109   }
110
111   /* add to job when the buffer is dirty and resolve is clear (not added before) */
112   if (fb->base.zsbuf && (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
113       !(job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
114      struct lima_resource *res = lima_resource(fb->base.zsbuf->texture);
115      lima_flush_job_accessing_bo(ctx, res->bo, true);
116      _mesa_hash_table_insert(ctx->write_jobs, &res->base, job);
117      lima_job_add_bo(job, LIMA_PIPE_PP, res->bo, LIMA_SUBMIT_BO_WRITE);
118   }
119
120   job->resolve |= buffers;
121}
122
123static void
124lima_damage_rect_union(struct pipe_scissor_state *rect,
125                       unsigned minx, unsigned maxx,
126                       unsigned miny, unsigned maxy)
127{
128   rect->minx = MIN2(rect->minx, minx);
129   rect->miny = MIN2(rect->miny, miny);
130   rect->maxx = MAX2(rect->maxx, maxx);
131   rect->maxy = MAX2(rect->maxy, maxy);
132}
133
134static void
135lima_clear(struct pipe_context *pctx, unsigned buffers, const struct pipe_scissor_state *scissor_state,
136           const union pipe_color_union *color, double depth, unsigned stencil)
137{
138   struct lima_context *ctx = lima_context(pctx);
139   struct lima_job *job = lima_job_get(ctx);
140
141   /* flush if this job already contains any draw, otherwise multi clear can be
142    * combined into a single job */
143   if (lima_job_has_draw_pending(job)) {
144      lima_do_job(job);
145      job = lima_job_get(ctx);
146   }
147
148   lima_update_job_wb(ctx, buffers);
149
150   /* no need to reload if cleared */
151   if (ctx->framebuffer.base.nr_cbufs && (buffers & PIPE_CLEAR_COLOR0)) {
152      struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
153      surf->reload &= ~PIPE_CLEAR_COLOR0;
154   }
155
156   struct lima_job_clear *clear = &job->clear;
157   clear->buffers = buffers;
158
159   if (buffers & PIPE_CLEAR_COLOR0) {
160      clear->color_8pc =
161         ((uint32_t)float_to_ubyte(color->f[3]) << 24) |
162         ((uint32_t)float_to_ubyte(color->f[2]) << 16) |
163         ((uint32_t)float_to_ubyte(color->f[1]) << 8) |
164         float_to_ubyte(color->f[0]);
165
166      clear->color_16pc =
167         ((uint64_t)float_to_ushort(color->f[3]) << 48) |
168         ((uint64_t)float_to_ushort(color->f[2]) << 32) |
169         ((uint64_t)float_to_ushort(color->f[1]) << 16) |
170         float_to_ushort(color->f[0]);
171   }
172
173   struct lima_surface *zsbuf = lima_surface(ctx->framebuffer.base.zsbuf);
174
175   if (buffers & PIPE_CLEAR_DEPTH) {
176      clear->depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
177      if (zsbuf)
178         zsbuf->reload &= ~PIPE_CLEAR_DEPTH;
179   }
180
181   if (buffers & PIPE_CLEAR_STENCIL) {
182      clear->stencil = stencil;
183      if (zsbuf)
184         zsbuf->reload &= ~PIPE_CLEAR_STENCIL;
185   }
186
187   ctx->dirty |= LIMA_CONTEXT_DIRTY_CLEAR;
188
189   lima_damage_rect_union(&job->damage_rect,
190                          0, ctx->framebuffer.base.width,
191                          0, ctx->framebuffer.base.height);
192}
193
194enum lima_attrib_type {
195   LIMA_ATTRIB_FLOAT = 0x000,
196   LIMA_ATTRIB_I32   = 0x001,
197   LIMA_ATTRIB_U32   = 0x002,
198   LIMA_ATTRIB_FP16  = 0x003,
199   LIMA_ATTRIB_I16   = 0x004,
200   LIMA_ATTRIB_U16   = 0x005,
201   LIMA_ATTRIB_I8    = 0x006,
202   LIMA_ATTRIB_U8    = 0x007,
203   LIMA_ATTRIB_I8N   = 0x008,
204   LIMA_ATTRIB_U8N   = 0x009,
205   LIMA_ATTRIB_I16N  = 0x00A,
206   LIMA_ATTRIB_U16N  = 0x00B,
207   LIMA_ATTRIB_I32N  = 0x00D,
208   LIMA_ATTRIB_U32N  = 0x00E,
209   LIMA_ATTRIB_FIXED = 0x101
210};
211
212static enum lima_attrib_type
213lima_pipe_format_to_attrib_type(enum pipe_format format)
214{
215   const struct util_format_description *desc = util_format_description(format);
216   int i = util_format_get_first_non_void_channel(format);
217   const struct util_format_channel_description *c = desc->channel + i;
218
219   switch (c->type) {
220   case UTIL_FORMAT_TYPE_FLOAT:
221      if (c->size == 16)
222         return LIMA_ATTRIB_FP16;
223      else
224         return LIMA_ATTRIB_FLOAT;
225   case UTIL_FORMAT_TYPE_FIXED:
226      return LIMA_ATTRIB_FIXED;
227   case UTIL_FORMAT_TYPE_SIGNED:
228      if (c->size == 8) {
229         if (c->normalized)
230            return LIMA_ATTRIB_I8N;
231         else
232            return LIMA_ATTRIB_I8;
233      }
234      else if (c->size == 16) {
235         if (c->normalized)
236            return LIMA_ATTRIB_I16N;
237         else
238            return LIMA_ATTRIB_I16;
239      }
240      else if (c->size == 32) {
241         if (c->normalized)
242            return LIMA_ATTRIB_I32N;
243         else
244            return LIMA_ATTRIB_I32;
245      }
246      break;
247   case UTIL_FORMAT_TYPE_UNSIGNED:
248      if (c->size == 8) {
249         if (c->normalized)
250            return LIMA_ATTRIB_U8N;
251         else
252            return LIMA_ATTRIB_U8;
253      }
254      else if (c->size == 16) {
255         if (c->normalized)
256            return LIMA_ATTRIB_U16N;
257         else
258            return LIMA_ATTRIB_U16;
259      }
260      else if (c->size == 32) {
261         if (c->normalized)
262            return LIMA_ATTRIB_U32N;
263         else
264            return LIMA_ATTRIB_U32;
265      }
266      break;
267   }
268
269   return LIMA_ATTRIB_FLOAT;
270}
271
272static void
273lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info,
274                 const struct pipe_draw_start_count_bias *draw)
275{
276   struct lima_context_constant_buffer *ccb =
277      ctx->const_buffer + PIPE_SHADER_VERTEX;
278   struct lima_vs_compiled_shader *vs = ctx->vs;
279   struct lima_job *job = lima_job_get(ctx);
280
281   VS_CMD_BEGIN(&job->vs_cmd_array, 24);
282
283   if (!info->index_size) {
284      VS_CMD_ARRAYS_SEMAPHORE_BEGIN_1();
285      VS_CMD_ARRAYS_SEMAPHORE_BEGIN_2();
286   }
287   int uniform_size = MIN2(vs->state.uniform_size, ccb->size);
288
289   int size = uniform_size + vs->state.constant_size + 32;
290   VS_CMD_UNIFORMS_ADDRESS(
291      lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform),
292      align(size, 16));
293
294   VS_CMD_SHADER_ADDRESS(ctx->vs->bo->va, ctx->vs->state.shader_size);
295   VS_CMD_SHADER_INFO(ctx->vs->state.prefetch, ctx->vs->state.shader_size);
296
297   int num_outputs = ctx->vs->state.num_outputs;
298   int num_attributes = ctx->vertex_elements->num_elements;
299   VS_CMD_VARYING_ATTRIBUTE_COUNT(num_outputs, MAX2(1, num_attributes));
300
301   VS_CMD_UNKNOWN1();
302
303   VS_CMD_ATTRIBUTES_ADDRESS(
304      lima_ctx_buff_va(ctx, lima_ctx_buff_gp_attribute_info),
305      MAX2(1, num_attributes));
306
307   VS_CMD_VARYINGS_ADDRESS(
308      lima_ctx_buff_va(ctx, lima_ctx_buff_gp_varying_info),
309      num_outputs);
310
311   unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : draw->count;
312   VS_CMD_DRAW(num, info->index_size);
313
314   VS_CMD_UNKNOWN2();
315
316   VS_CMD_ARRAYS_SEMAPHORE_END(info->index_size);
317
318   VS_CMD_END();
319}
320
321static void
322lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info,
323                   const struct pipe_draw_start_count_bias *draw)
324{
325   struct lima_vs_compiled_shader *vs = ctx->vs;
326   struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
327   struct lima_job *job = lima_job_get(ctx);
328   PLBU_CMD_BEGIN(&job->plbu_cmd_array, 32);
329
330   PLBU_CMD_VIEWPORT_LEFT(fui(ctx->viewport.left));
331   PLBU_CMD_VIEWPORT_RIGHT(fui(ctx->viewport.right));
332   PLBU_CMD_VIEWPORT_BOTTOM(fui(ctx->viewport.bottom));
333   PLBU_CMD_VIEWPORT_TOP(fui(ctx->viewport.top));
334
335   if (!info->index_size)
336      PLBU_CMD_ARRAYS_SEMAPHORE_BEGIN();
337
338   int cf = ctx->rasterizer->base.cull_face;
339   int ccw = ctx->rasterizer->base.front_ccw;
340   uint32_t cull = 0;
341   bool force_point_size = false;
342
343   if (cf != PIPE_FACE_NONE) {
344      if (cf & PIPE_FACE_FRONT)
345         cull |= ccw ? 0x00040000 : 0x00020000;
346      if (cf & PIPE_FACE_BACK)
347         cull |= ccw ? 0x00020000 : 0x00040000;
348   }
349
350   /* Specify point size with PLBU command if shader doesn't write */
351   if (info->mode == PIPE_PRIM_POINTS && ctx->vs->state.point_size_idx == -1)
352      force_point_size = true;
353
354   /* Specify line width with PLBU command for lines */
355   if (info->mode > PIPE_PRIM_POINTS && info->mode < PIPE_PRIM_TRIANGLES)
356      force_point_size = true;
357
358   PLBU_CMD_PRIMITIVE_SETUP(force_point_size, cull, info->index_size);
359
360   PLBU_CMD_RSW_VERTEX_ARRAY(
361      lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw),
362      ctx->gp_output->va);
363
364   /* TODO
365    * - we should set it only for the first draw that enabled the scissor and for
366    *   latter draw only if scissor is dirty
367    */
368
369   assert(cscissor->minx < cscissor->maxx && cscissor->miny < cscissor->maxy);
370   PLBU_CMD_SCISSORS(cscissor->minx, cscissor->maxx, cscissor->miny, cscissor->maxy);
371
372   lima_damage_rect_union(&job->damage_rect, cscissor->minx, cscissor->maxx,
373                          cscissor->miny, cscissor->maxy);
374
375   PLBU_CMD_UNKNOWN1();
376
377   PLBU_CMD_DEPTH_RANGE_NEAR(fui(ctx->viewport.near));
378   PLBU_CMD_DEPTH_RANGE_FAR(fui(ctx->viewport.far));
379
380   if ((info->mode == PIPE_PRIM_POINTS && ctx->vs->state.point_size_idx == -1) ||
381       ((info->mode >= PIPE_PRIM_LINES) && (info->mode < PIPE_PRIM_TRIANGLES)))
382   {
383      uint32_t v = info->mode == PIPE_PRIM_POINTS ?
384         fui(ctx->rasterizer->base.point_size) : fui(ctx->rasterizer->base.line_width);
385      PLBU_CMD_LOW_PRIM_SIZE(v);
386   }
387
388   if (info->index_size) {
389      PLBU_CMD_INDEXED_DEST(ctx->gp_output->va);
390      if (vs->state.point_size_idx != -1)
391         PLBU_CMD_INDEXED_PT_SIZE(ctx->gp_output->va + ctx->gp_output_point_size_offt);
392
393      PLBU_CMD_INDICES(ctx->index_res->bo->va + draw->start * info->index_size + ctx->index_offset);
394   }
395   else {
396      /* can this make the attribute info static? */
397      PLBU_CMD_DRAW_ARRAYS(info->mode, draw->start, draw->count);
398   }
399
400   PLBU_CMD_ARRAYS_SEMAPHORE_END();
401
402   if (info->index_size)
403      PLBU_CMD_DRAW_ELEMENTS(info->mode, ctx->min_index, draw->count);
404
405   PLBU_CMD_END();
406}
407
408static int
409lima_blend_func(enum pipe_blend_func pipe)
410{
411   switch (pipe) {
412   case PIPE_BLEND_ADD:
413      return 2;
414   case PIPE_BLEND_SUBTRACT:
415      return 0;
416   case PIPE_BLEND_REVERSE_SUBTRACT:
417      return 1;
418   case PIPE_BLEND_MIN:
419      return 4;
420   case PIPE_BLEND_MAX:
421      return 5;
422   }
423   return -1;
424}
425
426static int
427lima_blend_factor_has_alpha(enum pipe_blendfactor pipe)
428{
429   /* Bit 4 is set if the blendfactor uses alpha */
430   switch (pipe) {
431   case PIPE_BLENDFACTOR_SRC_ALPHA:
432   case PIPE_BLENDFACTOR_DST_ALPHA:
433   case PIPE_BLENDFACTOR_CONST_ALPHA:
434   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
435   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
436   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
437      return 1;
438
439   case PIPE_BLENDFACTOR_SRC_COLOR:
440   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
441   case PIPE_BLENDFACTOR_DST_COLOR:
442   case PIPE_BLENDFACTOR_INV_DST_COLOR:
443   case PIPE_BLENDFACTOR_CONST_COLOR:
444   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
445   case PIPE_BLENDFACTOR_ZERO:
446   case PIPE_BLENDFACTOR_ONE:
447   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
448      return 0;
449
450   case PIPE_BLENDFACTOR_SRC1_COLOR:
451   case PIPE_BLENDFACTOR_SRC1_ALPHA:
452   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
453   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
454      return -1; /* not supported */
455   }
456   return -1;
457}
458
459static int
460lima_blend_factor_is_inv(enum pipe_blendfactor pipe)
461{
462   /* Bit 3 is set if the blendfactor type is inverted */
463   switch (pipe) {
464   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
465   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
466   case PIPE_BLENDFACTOR_INV_DST_COLOR:
467   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
468   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
469   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
470   case PIPE_BLENDFACTOR_ONE:
471      return 1;
472
473   case PIPE_BLENDFACTOR_SRC_COLOR:
474   case PIPE_BLENDFACTOR_SRC_ALPHA:
475   case PIPE_BLENDFACTOR_DST_COLOR:
476   case PIPE_BLENDFACTOR_DST_ALPHA:
477   case PIPE_BLENDFACTOR_CONST_COLOR:
478   case PIPE_BLENDFACTOR_CONST_ALPHA:
479   case PIPE_BLENDFACTOR_ZERO:
480   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
481      return 0;
482
483   case PIPE_BLENDFACTOR_SRC1_COLOR:
484   case PIPE_BLENDFACTOR_SRC1_ALPHA:
485   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
486   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
487      return -1; /* not supported */
488   }
489   return -1;
490}
491
492static int
493lima_blend_factor(enum pipe_blendfactor pipe)
494{
495   /* Bits 0-2 indicate the blendfactor type */
496   switch (pipe) {
497   case PIPE_BLENDFACTOR_SRC_COLOR:
498   case PIPE_BLENDFACTOR_SRC_ALPHA:
499   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
500   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
501      return 0;
502
503   case PIPE_BLENDFACTOR_DST_COLOR:
504   case PIPE_BLENDFACTOR_DST_ALPHA:
505   case PIPE_BLENDFACTOR_INV_DST_COLOR:
506   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
507      return 1;
508
509   case PIPE_BLENDFACTOR_CONST_COLOR:
510   case PIPE_BLENDFACTOR_CONST_ALPHA:
511   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
512   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
513      return 2;
514
515   case PIPE_BLENDFACTOR_ZERO:
516   case PIPE_BLENDFACTOR_ONE:
517      return 3;
518
519   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
520      return 4;
521
522   case PIPE_BLENDFACTOR_SRC1_COLOR:
523   case PIPE_BLENDFACTOR_SRC1_ALPHA:
524   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
525   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
526      return -1; /* not supported */
527   }
528   return -1;
529}
530
531static int
532lima_calculate_alpha_blend(enum pipe_blend_func rgb_func, enum pipe_blend_func alpha_func,
533                           enum pipe_blendfactor rgb_src_factor, enum pipe_blendfactor rgb_dst_factor,
534                           enum pipe_blendfactor alpha_src_factor, enum pipe_blendfactor alpha_dst_factor)
535{
536   /* PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE has to be changed to PIPE_BLENDFACTOR_ONE
537    * if it is set for alpha_src.
538    */
539   if (alpha_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
540      alpha_src_factor = PIPE_BLENDFACTOR_ONE;
541
542   return lima_blend_func(rgb_func) |
543      (lima_blend_func(alpha_func) << 3) |
544
545      (lima_blend_factor(rgb_src_factor) << 6) |
546      (lima_blend_factor_is_inv(rgb_src_factor) << 9) |
547      (lima_blend_factor_has_alpha(rgb_src_factor) << 10) |
548
549      (lima_blend_factor(rgb_dst_factor) << 11) |
550      (lima_blend_factor_is_inv(rgb_dst_factor) << 14) |
551      (lima_blend_factor_has_alpha(rgb_dst_factor) << 15) |
552
553      (lima_blend_factor(alpha_src_factor) << 16) |
554      (lima_blend_factor_is_inv(alpha_src_factor) << 19) |
555
556      (lima_blend_factor(alpha_dst_factor) << 20) |
557      (lima_blend_factor_is_inv(alpha_dst_factor) << 23) |
558      0x0C000000; /* need to check if this is GLESv1 glAlphaFunc */
559}
560
561static int
562lima_stencil_op(enum pipe_stencil_op pipe)
563{
564   switch (pipe) {
565   case PIPE_STENCIL_OP_KEEP:
566      return 0;
567   case PIPE_STENCIL_OP_ZERO:
568      return 2;
569   case PIPE_STENCIL_OP_REPLACE:
570      return 1;
571   case PIPE_STENCIL_OP_INCR:
572      return 6;
573   case PIPE_STENCIL_OP_DECR:
574      return 7;
575   case PIPE_STENCIL_OP_INCR_WRAP:
576      return 4;
577   case PIPE_STENCIL_OP_DECR_WRAP:
578      return 5;
579   case PIPE_STENCIL_OP_INVERT:
580      return 3;
581   }
582   return -1;
583}
584
585static unsigned
586lima_calculate_depth_test(struct pipe_depth_stencil_alpha_state *depth,
587                          struct pipe_rasterizer_state *rst)
588{
589   int offset_scale = 0, offset_units = 0;
590   enum pipe_compare_func func = (depth->depth_enabled ? depth->depth_func : PIPE_FUNC_ALWAYS);
591
592   offset_scale = CLAMP(rst->offset_scale * 4, -128, 127);
593   if (offset_scale < 0)
594      offset_scale += 0x100;
595
596   offset_units = CLAMP(rst->offset_units * 2, -128, 127);
597   if (offset_units < 0)
598      offset_units += 0x100;
599
600   return (depth->depth_enabled && depth->depth_writemask) |
601      ((int)func << 1) |
602      (offset_scale << 16) |
603      (offset_units << 24);
604}
605
606static void
607lima_pack_render_state(struct lima_context *ctx, const struct pipe_draw_info *info)
608{
609   struct lima_fs_compiled_shader *fs = ctx->fs;
610   struct lima_render_state *render =
611      lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_plb_rsw,
612                          sizeof(*render));
613   bool early_z = true;
614   bool pixel_kill = true;
615
616   /* do hw support RGBA independ blend?
617    * PIPE_CAP_INDEP_BLEND_ENABLE
618    *
619    * how to handle the no cbuf only zbuf case?
620    */
621   struct pipe_rt_blend_state *rt = ctx->blend->base.rt;
622   render->blend_color_bg = float_to_ubyte(ctx->blend_color.color[2]) |
623      (float_to_ubyte(ctx->blend_color.color[1]) << 16);
624   render->blend_color_ra = float_to_ubyte(ctx->blend_color.color[0]) |
625      (float_to_ubyte(ctx->blend_color.color[3]) << 16);
626
627   if (rt->blend_enable) {
628      render->alpha_blend = lima_calculate_alpha_blend(rt->rgb_func, rt->alpha_func,
629         rt->rgb_src_factor, rt->rgb_dst_factor,
630         rt->alpha_src_factor, rt->alpha_dst_factor);
631   }
632   else {
633      /*
634       * Special handling for blending disabled.
635       * Binary driver is generating the same alpha_value,
636       * as when we would just enable blending, without changing/setting any blend equation/params.
637       * Normaly in this case mesa would set all rt fields (func/factor) to zero.
638       */
639      render->alpha_blend = lima_calculate_alpha_blend(PIPE_BLEND_ADD, PIPE_BLEND_ADD,
640         PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO,
641         PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO);
642   }
643
644   render->alpha_blend |= (rt->colormask & PIPE_MASK_RGBA) << 28;
645
646   struct pipe_rasterizer_state *rst = &ctx->rasterizer->base;
647   render->depth_test = lima_calculate_depth_test(&ctx->zsa->base, rst);
648
649   if (!rst->depth_clip_near || ctx->viewport.near == 0.0f)
650      render->depth_test |= 0x10; /* don't clip depth near */
651   if (!rst->depth_clip_far || ctx->viewport.far == 1.0f)
652      render->depth_test |= 0x20; /* don't clip depth far */
653
654   ushort far, near;
655
656   near = float_to_ushort(ctx->viewport.near);
657   far = float_to_ushort(ctx->viewport.far);
658
659   /* overlap with plbu? any place can remove one? */
660   render->depth_range = near | (far << 16);
661
662   struct pipe_stencil_state *stencil = ctx->zsa->base.stencil;
663   struct pipe_stencil_ref *ref = &ctx->stencil_ref;
664
665   if (stencil[0].enabled) { /* stencil is enabled */
666      render->stencil_front = stencil[0].func |
667         (lima_stencil_op(stencil[0].fail_op) << 3) |
668         (lima_stencil_op(stencil[0].zfail_op) << 6) |
669         (lima_stencil_op(stencil[0].zpass_op) << 9) |
670         (ref->ref_value[0] << 16) |
671         (stencil[0].valuemask << 24);
672      render->stencil_back = render->stencil_front;
673      render->stencil_test = (stencil[0].writemask & 0xff) | (stencil[0].writemask & 0xff) << 8;
674      if (stencil[1].enabled) { /* two-side is enabled */
675         render->stencil_back = stencil[1].func |
676            (lima_stencil_op(stencil[1].fail_op) << 3) |
677            (lima_stencil_op(stencil[1].zfail_op) << 6) |
678            (lima_stencil_op(stencil[1].zpass_op) << 9) |
679            (ref->ref_value[1] << 16) |
680            (stencil[1].valuemask << 24);
681         render->stencil_test = (stencil[0].writemask & 0xff) | (stencil[1].writemask & 0xff) << 8;
682      }
683      /* TODO: Find out, what (render->stecil_test & 0xff000000) is */
684   }
685   else {
686      /* Default values, when stencil is disabled:
687       * stencil[0|1].valuemask = 0xff
688       * stencil[0|1].func = PIPE_FUNC_ALWAYS
689       * stencil[0|1].writemask = 0xff
690       */
691      render->stencil_front = 0xff000007;
692      render->stencil_back = 0xff000007;
693      render->stencil_test = 0x0000ffff;
694   }
695
696   /* need more investigation */
697   if (info->mode == PIPE_PRIM_POINTS)
698      render->multi_sample = 0x0000F000;
699   else if (info->mode < PIPE_PRIM_TRIANGLES)
700      render->multi_sample = 0x0000F400;
701   else
702      render->multi_sample = 0x0000F800;
703   if (ctx->framebuffer.base.samples)
704      render->multi_sample |= 0x68;
705
706   /* alpha test */
707   if (ctx->zsa->base.alpha_enabled) {
708      render->multi_sample |= ctx->zsa->base.alpha_func;
709      render->stencil_test |= float_to_ubyte(ctx->zsa->base.alpha_ref_value) << 16;
710   } else {
711      /* func = PIPE_FUNC_ALWAYS */
712      render->multi_sample |= 0x7;
713   }
714
715   render->shader_address =
716      ctx->fs->bo->va | (((uint32_t *)ctx->fs->bo->map)[0] & 0x1F);
717
718   /* seems not needed */
719   render->uniforms_address = 0x00000000;
720
721   render->textures_address = 0x00000000;
722
723   render->aux0 = (ctx->vs->state.varying_stride >> 3);
724   render->aux1 = 0x00000000;
725   if (ctx->rasterizer->base.front_ccw)
726      render->aux1 = 0x00001000;
727
728   if (ctx->blend->base.dither)
729      render->aux1 |= 0x00002000;
730
731   if (fs->state.uses_discard ||
732       ctx->zsa->base.alpha_enabled) {
733      early_z = false;
734      pixel_kill = false;
735   }
736
737   if (rt->blend_enable)
738      pixel_kill = false;
739
740   if ((rt->colormask & PIPE_MASK_RGBA) != PIPE_MASK_RGBA)
741      pixel_kill = false;
742
743   if (early_z)
744      render->aux0 |= 0x300;
745
746   if (pixel_kill)
747      render->aux0 |= 0x1000;
748
749   if (ctx->tex_stateobj.num_samplers) {
750      render->textures_address =
751         lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc);
752      render->aux0 |= ctx->tex_stateobj.num_samplers << 14;
753      render->aux0 |= 0x20;
754   }
755
756   if (ctx->const_buffer[PIPE_SHADER_FRAGMENT].buffer) {
757      render->uniforms_address =
758         lima_ctx_buff_va(ctx, lima_ctx_buff_pp_uniform_array);
759      uint32_t size = ctx->buffer_state[lima_ctx_buff_pp_uniform].size;
760      uint32_t bits = 0;
761      if (size >= 8) {
762         bits = util_last_bit(size >> 3) - 1;
763         bits += size & u_bit_consecutive(0, bits + 3) ? 1 : 0;
764      }
765      render->uniforms_address |= bits > 0xf ? 0xf : bits;
766
767      render->aux0 |= 0x80;
768      render->aux1 |= 0x10000;
769   }
770
771   if (ctx->vs->state.num_varyings) {
772      render->varying_types = 0x00000000;
773      render->varyings_address = ctx->gp_output->va +
774                                 ctx->gp_output_varyings_offt;
775      for (int i = 0, index = 0; i < ctx->vs->state.num_outputs; i++) {
776         int val;
777
778         if (i == ctx->vs->state.gl_pos_idx ||
779             i == ctx->vs->state.point_size_idx)
780            continue;
781
782         struct lima_varying_info *v = ctx->vs->state.varying + i;
783         if (v->component_size == 4)
784            val = v->components > 2 ? 0 : 1;
785         else
786            val = v->components > 2 ? 2 : 3;
787
788         if (index < 10)
789            render->varying_types |= val << (3 * index);
790         else if (index == 10) {
791            render->varying_types |= val << 30;
792            render->varyings_address |= val >> 2;
793         }
794         else if (index == 11)
795            render->varyings_address |= val << 1;
796
797         index++;
798      }
799   }
800   else {
801      render->varying_types = 0x00000000;
802      render->varyings_address = 0x00000000;
803   }
804
805   struct lima_job *job = lima_job_get(ctx);
806
807   lima_dump_command_stream_print(
808      job->dump, render, sizeof(*render),
809      false, "add render state at va %x\n",
810      lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw));
811
812   lima_dump_rsw_command_stream_print(
813      job->dump, render, sizeof(*render),
814      lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw));
815}
816
817static void
818lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_info *info,
819                              const struct pipe_draw_start_count_bias *draw)
820{
821   struct lima_job *job = lima_job_get(ctx);
822   struct lima_vertex_element_state *ve = ctx->vertex_elements;
823   struct lima_context_vertex_buffer *vb = &ctx->vertex_buffers;
824
825   uint32_t *attribute =
826      lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_attribute_info,
827                          MAX2(1, ve->num_elements) * 8);
828
829   int n = 0;
830   for (int i = 0; i < ve->num_elements; i++) {
831      struct pipe_vertex_element *pve = ve->pipe + i;
832
833      assert(pve->vertex_buffer_index < vb->count);
834      assert(vb->enabled_mask & (1 << pve->vertex_buffer_index));
835
836      struct pipe_vertex_buffer *pvb = vb->vb + pve->vertex_buffer_index;
837      struct lima_resource *res = lima_resource(pvb->buffer.resource);
838
839      lima_job_add_bo(job, LIMA_PIPE_GP, res->bo, LIMA_SUBMIT_BO_READ);
840
841      unsigned start = info->index_size ? (ctx->min_index + draw->index_bias) : draw->start;
842      attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
843         + start * pvb->stride;
844      attribute[n++] = (pvb->stride << 11) |
845         (lima_pipe_format_to_attrib_type(pve->src_format) << 2) |
846         (util_format_get_nr_components(pve->src_format) - 1);
847   }
848
849   lima_dump_command_stream_print(
850      job->dump, attribute, n * 4, false, "update attribute info at va %x\n",
851      lima_ctx_buff_va(ctx, lima_ctx_buff_gp_attribute_info));
852}
853
854static void
855lima_update_gp_uniform(struct lima_context *ctx)
856{
857   struct lima_context_constant_buffer *ccb =
858      ctx->const_buffer + PIPE_SHADER_VERTEX;
859   struct lima_vs_compiled_shader *vs = ctx->vs;
860   int uniform_size = MIN2(vs->state.uniform_size, ccb->size);
861
862   int size = uniform_size + vs->state.constant_size + 32;
863   void *vs_const_buff =
864      lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_uniform, size);
865
866   if (ccb->buffer)
867      memcpy(vs_const_buff, ccb->buffer, uniform_size);
868
869   memcpy(vs_const_buff + uniform_size,
870          ctx->viewport.transform.scale,
871          sizeof(ctx->viewport.transform.scale));
872   memcpy(vs_const_buff + uniform_size + 16,
873          ctx->viewport.transform.translate,
874          sizeof(ctx->viewport.transform.translate));
875
876   if (vs->constant)
877      memcpy(vs_const_buff + uniform_size + 32,
878             vs->constant, vs->state.constant_size);
879
880   struct lima_job *job = lima_job_get(ctx);
881
882   if (lima_debug & LIMA_DEBUG_GP) {
883      float *vs_const_buff_f = vs_const_buff;
884      printf("gp uniforms:\n");
885      for (int i = 0; i < (size / sizeof(float)); i++) {
886         if ((i % 4) == 0)
887            printf("%4d:", i / 4);
888         printf(" %8.4f", vs_const_buff_f[i]);
889         if ((i % 4) == 3)
890            printf("\n");
891      }
892      printf("\n");
893   }
894
895   lima_dump_command_stream_print(
896      job->dump, vs_const_buff, size, true,
897      "update gp uniform at va %x\n",
898      lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform));
899}
900
901static void
902lima_update_pp_uniform(struct lima_context *ctx)
903{
904   const float *const_buff = ctx->const_buffer[PIPE_SHADER_FRAGMENT].buffer;
905   size_t const_buff_size = ctx->const_buffer[PIPE_SHADER_FRAGMENT].size / sizeof(float);
906
907   if (!const_buff)
908      return;
909
910   uint16_t *fp16_const_buff =
911      lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_uniform,
912                          const_buff_size * sizeof(uint16_t));
913
914   uint32_t *array =
915      lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_uniform_array, 4);
916
917   for (int i = 0; i < const_buff_size; i++)
918       fp16_const_buff[i] = _mesa_float_to_half(const_buff[i]);
919
920   *array = lima_ctx_buff_va(ctx, lima_ctx_buff_pp_uniform);
921
922   struct lima_job *job = lima_job_get(ctx);
923
924   lima_dump_command_stream_print(
925      job->dump, fp16_const_buff, const_buff_size * 2,
926      false, "add pp uniform data at va %x\n",
927      lima_ctx_buff_va(ctx, lima_ctx_buff_pp_uniform));
928   lima_dump_command_stream_print(
929      job->dump, array, 4, false, "add pp uniform info at va %x\n",
930      lima_ctx_buff_va(ctx, lima_ctx_buff_pp_uniform_array));
931}
932
933static void
934lima_update_varying(struct lima_context *ctx, const struct pipe_draw_info *info,
935                    const struct pipe_draw_start_count_bias *draw)
936{
937   struct lima_job *job = lima_job_get(ctx);
938   struct lima_screen *screen = lima_screen(ctx->base.screen);
939   struct lima_vs_compiled_shader *vs = ctx->vs;
940   uint32_t gp_output_size;
941   unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : draw->count;
942
943   uint32_t *varying =
944      lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_varying_info,
945                          vs->state.num_outputs * 8);
946   int n = 0;
947
948   int offset = 0;
949
950   for (int i = 0; i < vs->state.num_outputs; i++) {
951      struct lima_varying_info *v = vs->state.varying + i;
952
953      if (i == vs->state.gl_pos_idx ||
954          i == vs->state.point_size_idx)
955         continue;
956
957      int size = v->component_size * 4;
958
959      /* does component_size == 2 need to be 16 aligned? */
960      if (v->component_size == 4)
961         offset = align(offset, 16);
962
963      v->offset = offset;
964      offset += size;
965   }
966
967   vs->state.varying_stride = align(offset, 16);
968
969   /* gl_Position is always present, allocate space for it */
970   gp_output_size = align(4 * 4 * num, 0x40);
971
972   /* Allocate space for varyings if there're any */
973   if (vs->state.num_varyings) {
974      ctx->gp_output_varyings_offt = gp_output_size;
975      gp_output_size += align(vs->state.varying_stride * num, 0x40);
976   }
977
978   /* Allocate space for gl_PointSize if it's there */
979   if (vs->state.point_size_idx != -1) {
980      ctx->gp_output_point_size_offt = gp_output_size;
981      gp_output_size += 4 * num;
982   }
983
984   /* gp_output can be too large for the suballocator, so create a
985    * separate bo for it. The bo cache should prevent performance hit.
986    */
987   ctx->gp_output = lima_bo_create(screen, gp_output_size, 0);
988   assert(ctx->gp_output);
989   lima_job_add_bo(job, LIMA_PIPE_GP, ctx->gp_output, LIMA_SUBMIT_BO_WRITE);
990   lima_job_add_bo(job, LIMA_PIPE_PP, ctx->gp_output, LIMA_SUBMIT_BO_READ);
991
992   for (int i = 0; i < vs->state.num_outputs; i++) {
993      struct lima_varying_info *v = vs->state.varying + i;
994
995      if (i == vs->state.gl_pos_idx) {
996         /* gl_Position */
997         varying[n++] = ctx->gp_output->va;
998         varying[n++] = 0x8020;
999      } else if (i == vs->state.point_size_idx) {
1000         /* gl_PointSize */
1001         varying[n++] = ctx->gp_output->va + ctx->gp_output_point_size_offt;
1002         varying[n++] = 0x2021;
1003      } else {
1004         /* Varying */
1005         varying[n++] = ctx->gp_output->va + ctx->gp_output_varyings_offt +
1006                        v->offset;
1007         varying[n++] = (vs->state.varying_stride << 11) | (v->components - 1) |
1008            (v->component_size == 2 ? 0x0C : 0);
1009      }
1010   }
1011
1012   lima_dump_command_stream_print(
1013      job->dump, varying, n * 4, false, "update varying info at va %x\n",
1014      lima_ctx_buff_va(ctx, lima_ctx_buff_gp_varying_info));
1015}
1016
1017static void
1018lima_draw_vbo_update(struct pipe_context *pctx,
1019                     const struct pipe_draw_info *info,
1020                     const struct pipe_draw_start_count_bias *draw)
1021{
1022   struct lima_context *ctx = lima_context(pctx);
1023   struct lima_context_framebuffer *fb = &ctx->framebuffer;
1024   unsigned buffers = 0;
1025
1026   if (fb->base.zsbuf) {
1027      if (ctx->zsa->base.depth_enabled)
1028         buffers |= PIPE_CLEAR_DEPTH;
1029      if (ctx->zsa->base.stencil[0].enabled ||
1030          ctx->zsa->base.stencil[1].enabled)
1031         buffers |= PIPE_CLEAR_STENCIL;
1032   }
1033
1034   if (fb->base.nr_cbufs)
1035      buffers |= PIPE_CLEAR_COLOR0;
1036
1037   lima_update_job_wb(ctx, buffers);
1038
1039   lima_update_gp_attribute_info(ctx, info, draw);
1040
1041   if ((ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
1042        ctx->const_buffer[PIPE_SHADER_VERTEX].dirty) ||
1043       ctx->dirty & LIMA_CONTEXT_DIRTY_VIEWPORT ||
1044       ctx->dirty & LIMA_CONTEXT_DIRTY_COMPILED_VS) {
1045      lima_update_gp_uniform(ctx);
1046      ctx->const_buffer[PIPE_SHADER_VERTEX].dirty = false;
1047   }
1048
1049   lima_update_varying(ctx, info, draw);
1050
1051   lima_pack_vs_cmd(ctx, info, draw);
1052
1053   if (ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
1054       ctx->const_buffer[PIPE_SHADER_FRAGMENT].dirty) {
1055      lima_update_pp_uniform(ctx);
1056      ctx->const_buffer[PIPE_SHADER_FRAGMENT].dirty = false;
1057   }
1058
1059   lima_update_textures(ctx);
1060
1061   lima_pack_render_state(ctx, info);
1062   lima_pack_plbu_cmd(ctx, info, draw);
1063
1064   if (ctx->gp_output) {
1065      lima_bo_unreference(ctx->gp_output); /* held by job */
1066      ctx->gp_output = NULL;
1067   }
1068
1069   ctx->dirty = 0;
1070}
1071
1072static void
1073lima_draw_vbo_indexed(struct pipe_context *pctx,
1074                      const struct pipe_draw_info *info,
1075                      const struct pipe_draw_start_count_bias *draw)
1076{
1077   struct lima_context *ctx = lima_context(pctx);
1078   struct lima_job *job = lima_job_get(ctx);
1079   struct pipe_resource *indexbuf = NULL;
1080   bool needs_indices = true;
1081
1082   /* Mali Utgard GPU always need min/max index info for index draw,
1083    * compute it if upper layer does not do for us */
1084   if (info->index_bounds_valid) {
1085      ctx->min_index = info->min_index;
1086      ctx->max_index = info->max_index;
1087      needs_indices = false;
1088   }
1089
1090   if (info->has_user_indices) {
1091      util_upload_index_buffer(&ctx->base, info, draw, &indexbuf, &ctx->index_offset, 0x40);
1092      ctx->index_res = lima_resource(indexbuf);
1093   }
1094   else {
1095      ctx->index_res = lima_resource(info->index.resource);
1096      ctx->index_offset = 0;
1097      needs_indices = !panfrost_minmax_cache_get(ctx->index_res->index_cache, draw->start,
1098                                                 draw->count, &ctx->min_index, &ctx->max_index);
1099   }
1100
1101   if (needs_indices) {
1102      u_vbuf_get_minmax_index(pctx, info, draw, &ctx->min_index, &ctx->max_index);
1103      if (!info->has_user_indices)
1104         panfrost_minmax_cache_add(ctx->index_res->index_cache, draw->start, draw->count,
1105                                   ctx->min_index, ctx->max_index);
1106   }
1107
1108   lima_job_add_bo(job, LIMA_PIPE_GP, ctx->index_res->bo, LIMA_SUBMIT_BO_READ);
1109   lima_job_add_bo(job, LIMA_PIPE_PP, ctx->index_res->bo, LIMA_SUBMIT_BO_READ);
1110   lima_draw_vbo_update(pctx, info, draw);
1111
1112   if (indexbuf)
1113      pipe_resource_reference(&indexbuf, NULL);
1114}
1115
1116static void
1117lima_draw_vbo_count(struct pipe_context *pctx,
1118                    const struct pipe_draw_info *info,
1119                    const struct pipe_draw_start_count_bias *draw)
1120{
1121   static const uint32_t max_verts = 65535;
1122
1123   struct pipe_draw_start_count_bias local_draw = *draw;
1124   unsigned start = draw->start;
1125   unsigned count = draw->count;
1126
1127   while (count) {
1128      unsigned this_count = count;
1129      unsigned step;
1130
1131      u_split_draw(info, max_verts, &this_count, &step);
1132
1133      local_draw.start = start;
1134      local_draw.count = this_count;
1135
1136      lima_draw_vbo_update(pctx, info, &local_draw);
1137
1138      count -= step;
1139      start += step;
1140   }
1141}
1142
1143static void
1144lima_draw_vbo(struct pipe_context *pctx,
1145              const struct pipe_draw_info *info,
1146              unsigned drawid_offset,
1147              const struct pipe_draw_indirect_info *indirect,
1148              const struct pipe_draw_start_count_bias *draws,
1149              unsigned num_draws)
1150{
1151   if (num_draws > 1) {
1152      util_draw_multi(pctx, info, drawid_offset, indirect, draws, num_draws);
1153      return;
1154   }
1155
1156   /* check if draw mode and vertex/index count match,
1157    * otherwise gp will hang */
1158   if (!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count)) {
1159      debug_printf("draw mode and vertex/index count mismatch\n");
1160      return;
1161   }
1162
1163   struct lima_context *ctx = lima_context(pctx);
1164
1165   if (!ctx->uncomp_fs || !ctx->uncomp_vs) {
1166      debug_warn_once("no shader, skip draw\n");
1167      return;
1168   }
1169
1170   lima_clip_scissor_to_viewport(ctx);
1171   if (lima_is_scissor_zero(ctx))
1172      return;
1173
1174   if (!lima_update_fs_state(ctx) || !lima_update_vs_state(ctx))
1175      return;
1176
1177   struct lima_job *job = lima_job_get(ctx);
1178   job->pp_max_stack_size = MAX2(job->pp_max_stack_size, ctx->fs->state.stack_size);
1179
1180   lima_dump_command_stream_print(
1181      job->dump, ctx->vs->bo->map, ctx->vs->state.shader_size, false,
1182      "add vs at va %x\n", ctx->vs->bo->va);
1183   lima_dump_shader(job->dump, ctx->vs->bo->map, ctx->vs->state.shader_size, false);
1184
1185   lima_dump_command_stream_print(
1186      job->dump, ctx->fs->bo->map, ctx->fs->state.shader_size, false,
1187      "add fs at va %x\n", ctx->fs->bo->va);
1188   lima_dump_shader(job->dump, ctx->fs->bo->map, ctx->fs->state.shader_size, true);
1189
1190   lima_job_add_bo(job, LIMA_PIPE_GP, ctx->vs->bo, LIMA_SUBMIT_BO_READ);
1191   lima_job_add_bo(job, LIMA_PIPE_PP, ctx->fs->bo, LIMA_SUBMIT_BO_READ);
1192
1193   if (info->index_size)
1194      lima_draw_vbo_indexed(pctx, info, &draws[0]);
1195   else
1196      lima_draw_vbo_count(pctx, info, &draws[0]);
1197
1198   job->draws++;
1199   /* Flush job if we hit the limit of draws per job otherwise we may
1200    * hit tile heap size limit */
1201   if (job->draws > MAX_DRAWS_PER_JOB) {
1202      unsigned resolve = job->resolve;
1203      lima_do_job(job);
1204      job = lima_job_get(ctx);
1205      /* Subsequent job will need to resolve the same buffers */
1206      lima_update_job_wb(ctx, resolve);
1207   }
1208}
1209
1210void
1211lima_draw_init(struct lima_context *ctx)
1212{
1213   ctx->base.clear = lima_clear;
1214   ctx->base.draw_vbo = lima_draw_vbo;
1215}
1216