1 /*
2  * Copyright © 2014-2017 Broadcom
3  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
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, sublicense,
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 next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * 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 NONINFRINGEMENT.  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 DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include "pipe/p_state.h"
26 #include "util/format/u_format.h"
27 #include "util/u_framebuffer.h"
28 #include "util/u_inlines.h"
29 #include "util/u_math.h"
30 #include "util/u_memory.h"
31 #include "util/half_float.h"
32 #include "util/u_helpers.h"
33 #include "util/u_upload_mgr.h"
34 
35 #include "v3d_context.h"
36 #include "v3d_tiling.h"
37 #include "broadcom/common/v3d_macros.h"
38 #include "broadcom/compiler/v3d_compiler.h"
39 #include "broadcom/cle/v3dx_pack.h"
40 
41 static void
v3d_generic_cso_state_delete(struct pipe_context * pctx,void * hwcso)42 v3d_generic_cso_state_delete(struct pipe_context *pctx, void *hwcso)
43 {
44         free(hwcso);
45 }
46 
47 static void
v3d_set_blend_color(struct pipe_context * pctx,const struct pipe_blend_color * blend_color)48 v3d_set_blend_color(struct pipe_context *pctx,
49                     const struct pipe_blend_color *blend_color)
50 {
51         struct v3d_context *v3d = v3d_context(pctx);
52         v3d->blend_color.f = *blend_color;
53         for (int i = 0; i < 4; i++) {
54                 v3d->blend_color.hf[i] =
55                         _mesa_float_to_half(blend_color->color[i]);
56         }
57         v3d->dirty |= VC5_DIRTY_BLEND_COLOR;
58 }
59 
60 static void
v3d_set_stencil_ref(struct pipe_context * pctx,const struct pipe_stencil_ref * stencil_ref)61 v3d_set_stencil_ref(struct pipe_context *pctx,
62                     const struct pipe_stencil_ref *stencil_ref)
63 {
64         struct v3d_context *v3d = v3d_context(pctx);
65         v3d->stencil_ref = *stencil_ref;
66         v3d->dirty |= VC5_DIRTY_STENCIL_REF;
67 }
68 
69 static void
v3d_set_clip_state(struct pipe_context * pctx,const struct pipe_clip_state * clip)70 v3d_set_clip_state(struct pipe_context *pctx,
71                    const struct pipe_clip_state *clip)
72 {
73         struct v3d_context *v3d = v3d_context(pctx);
74         v3d->clip = *clip;
75         v3d->dirty |= VC5_DIRTY_CLIP;
76 }
77 
78 static void
v3d_set_sample_mask(struct pipe_context * pctx,unsigned sample_mask)79 v3d_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
80 {
81         struct v3d_context *v3d = v3d_context(pctx);
82         v3d->sample_mask = sample_mask & ((1 << V3D_MAX_SAMPLES) - 1);
83         v3d->dirty |= VC5_DIRTY_SAMPLE_STATE;
84 }
85 
86 static void *
v3d_create_rasterizer_state(struct pipe_context * pctx,const struct pipe_rasterizer_state * cso)87 v3d_create_rasterizer_state(struct pipe_context *pctx,
88                             const struct pipe_rasterizer_state *cso)
89 {
90         struct v3d_rasterizer_state *so;
91 
92         so = CALLOC_STRUCT(v3d_rasterizer_state);
93         if (!so)
94                 return NULL;
95 
96         so->base = *cso;
97 
98         /* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835,
99          * BCM21553).
100          */
101         so->point_size = MAX2(cso->point_size, .125f);
102 
103         STATIC_ASSERT(sizeof(so->depth_offset) >=
104                       cl_packet_length(DEPTH_OFFSET));
105         v3dx_pack(&so->depth_offset, DEPTH_OFFSET, depth) {
106                 depth.depth_offset_factor = cso->offset_scale;
107                 depth.depth_offset_units = cso->offset_units;
108         }
109 
110         /* The HW treats polygon offset units based on a Z24 buffer, so we
111          * need to scale up offset_units if we're only Z16.
112          */
113         v3dx_pack(&so->depth_offset_z16, DEPTH_OFFSET, depth) {
114                 depth.depth_offset_factor = cso->offset_scale;
115                 depth.depth_offset_units = cso->offset_units * 256.0;
116         }
117 
118         return so;
119 }
120 
121 /* Blend state is baked into shaders. */
122 static void *
v3d_create_blend_state(struct pipe_context * pctx,const struct pipe_blend_state * cso)123 v3d_create_blend_state(struct pipe_context *pctx,
124                        const struct pipe_blend_state *cso)
125 {
126         struct v3d_blend_state *so;
127 
128         so = CALLOC_STRUCT(v3d_blend_state);
129         if (!so)
130                 return NULL;
131 
132         so->base = *cso;
133 
134         if (cso->independent_blend_enable) {
135                 for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) {
136                         so->blend_enables |= cso->rt[i].blend_enable << i;
137 
138                         /* V3D 4.x is when we got independent blend enables. */
139                         assert(V3D_VERSION >= 40 ||
140                                cso->rt[i].blend_enable == cso->rt[0].blend_enable);
141                 }
142         } else {
143                 if (cso->rt[0].blend_enable)
144                         so->blend_enables = (1 << V3D_MAX_DRAW_BUFFERS) - 1;
145         }
146 
147         return so;
148 }
149 
150 static uint32_t
translate_stencil_op(enum pipe_stencil_op op)151 translate_stencil_op(enum pipe_stencil_op op)
152 {
153         switch (op) {
154         case PIPE_STENCIL_OP_KEEP:      return V3D_STENCIL_OP_KEEP;
155         case PIPE_STENCIL_OP_ZERO:      return V3D_STENCIL_OP_ZERO;
156         case PIPE_STENCIL_OP_REPLACE:   return V3D_STENCIL_OP_REPLACE;
157         case PIPE_STENCIL_OP_INCR:      return V3D_STENCIL_OP_INCR;
158         case PIPE_STENCIL_OP_DECR:      return V3D_STENCIL_OP_DECR;
159         case PIPE_STENCIL_OP_INCR_WRAP: return V3D_STENCIL_OP_INCWRAP;
160         case PIPE_STENCIL_OP_DECR_WRAP: return V3D_STENCIL_OP_DECWRAP;
161         case PIPE_STENCIL_OP_INVERT:    return V3D_STENCIL_OP_INVERT;
162         }
163         unreachable("bad stencil op");
164 }
165 
166 static void *
v3d_create_depth_stencil_alpha_state(struct pipe_context * pctx,const struct pipe_depth_stencil_alpha_state * cso)167 v3d_create_depth_stencil_alpha_state(struct pipe_context *pctx,
168                                      const struct pipe_depth_stencil_alpha_state *cso)
169 {
170         struct v3d_depth_stencil_alpha_state *so;
171 
172         so = CALLOC_STRUCT(v3d_depth_stencil_alpha_state);
173         if (!so)
174                 return NULL;
175 
176         so->base = *cso;
177 
178         if (cso->depth.enabled) {
179                 switch (cso->depth.func) {
180                 case PIPE_FUNC_LESS:
181                 case PIPE_FUNC_LEQUAL:
182                         so->ez_state = VC5_EZ_LT_LE;
183                         break;
184                 case PIPE_FUNC_GREATER:
185                 case PIPE_FUNC_GEQUAL:
186                         so->ez_state = VC5_EZ_GT_GE;
187                         break;
188                 case PIPE_FUNC_NEVER:
189                 case PIPE_FUNC_EQUAL:
190                         so->ez_state = VC5_EZ_UNDECIDED;
191                         break;
192                 default:
193                         so->ez_state = VC5_EZ_DISABLED;
194                         break;
195                 }
196 
197                 /* If stencil is enabled and it's not a no-op, then it would
198                  * break EZ updates.
199                  */
200                 if (cso->stencil[0].enabled &&
201                     (cso->stencil[0].zfail_op != PIPE_STENCIL_OP_KEEP ||
202                      cso->stencil[0].func != PIPE_FUNC_ALWAYS ||
203                      (cso->stencil[1].enabled &&
204                       (cso->stencil[1].zfail_op != PIPE_STENCIL_OP_KEEP &&
205                        cso->stencil[1].func != PIPE_FUNC_ALWAYS)))) {
206                         so->ez_state = VC5_EZ_DISABLED;
207                 }
208         }
209 
210         const struct pipe_stencil_state *front = &cso->stencil[0];
211         const struct pipe_stencil_state *back = &cso->stencil[1];
212 
213         if (front->enabled) {
214                 STATIC_ASSERT(sizeof(so->stencil_front) >=
215                               cl_packet_length(STENCIL_CFG));
216                 v3dx_pack(&so->stencil_front, STENCIL_CFG, config) {
217                         config.front_config = true;
218                         /* If !back->enabled, then the front values should be
219                          * used for both front and back-facing primitives.
220                          */
221                         config.back_config = !back->enabled;
222 
223                         config.stencil_write_mask = front->writemask;
224                         config.stencil_test_mask = front->valuemask;
225 
226                         config.stencil_test_function = front->func;
227                         config.stencil_pass_op =
228                                 translate_stencil_op(front->zpass_op);
229                         config.depth_test_fail_op =
230                                 translate_stencil_op(front->zfail_op);
231                         config.stencil_test_fail_op =
232                                 translate_stencil_op(front->fail_op);
233                 }
234         }
235         if (back->enabled) {
236                 STATIC_ASSERT(sizeof(so->stencil_back) >=
237                               cl_packet_length(STENCIL_CFG));
238                 v3dx_pack(&so->stencil_back, STENCIL_CFG, config) {
239                         config.front_config = false;
240                         config.back_config = true;
241 
242                         config.stencil_write_mask = back->writemask;
243                         config.stencil_test_mask = back->valuemask;
244 
245                         config.stencil_test_function = back->func;
246                         config.stencil_pass_op =
247                                 translate_stencil_op(back->zpass_op);
248                         config.depth_test_fail_op =
249                                 translate_stencil_op(back->zfail_op);
250                         config.stencil_test_fail_op =
251                                 translate_stencil_op(back->fail_op);
252                 }
253         }
254 
255         return so;
256 }
257 
258 static void
v3d_set_polygon_stipple(struct pipe_context * pctx,const struct pipe_poly_stipple * stipple)259 v3d_set_polygon_stipple(struct pipe_context *pctx,
260                         const struct pipe_poly_stipple *stipple)
261 {
262         struct v3d_context *v3d = v3d_context(pctx);
263         v3d->stipple = *stipple;
264         v3d->dirty |= VC5_DIRTY_STIPPLE;
265 }
266 
267 static void
v3d_set_scissor_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * scissor)268 v3d_set_scissor_states(struct pipe_context *pctx,
269                        unsigned start_slot,
270                        unsigned num_scissors,
271                        const struct pipe_scissor_state *scissor)
272 {
273         struct v3d_context *v3d = v3d_context(pctx);
274 
275         v3d->scissor = *scissor;
276         v3d->dirty |= VC5_DIRTY_SCISSOR;
277 }
278 
279 static void
v3d_set_viewport_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * viewport)280 v3d_set_viewport_states(struct pipe_context *pctx,
281                         unsigned start_slot,
282                         unsigned num_viewports,
283                         const struct pipe_viewport_state *viewport)
284 {
285         struct v3d_context *v3d = v3d_context(pctx);
286         v3d->viewport = *viewport;
287         v3d->dirty |= VC5_DIRTY_VIEWPORT;
288 }
289 
290 static void
v3d_set_vertex_buffers(struct pipe_context * pctx,unsigned start_slot,unsigned count,const struct pipe_vertex_buffer * vb)291 v3d_set_vertex_buffers(struct pipe_context *pctx,
292                        unsigned start_slot, unsigned count,
293                        const struct pipe_vertex_buffer *vb)
294 {
295         struct v3d_context *v3d = v3d_context(pctx);
296         struct v3d_vertexbuf_stateobj *so = &v3d->vertexbuf;
297 
298         util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb,
299                                      start_slot, count);
300         so->count = util_last_bit(so->enabled_mask);
301 
302         v3d->dirty |= VC5_DIRTY_VTXBUF;
303 }
304 
305 static void
v3d_blend_state_bind(struct pipe_context * pctx,void * hwcso)306 v3d_blend_state_bind(struct pipe_context *pctx, void *hwcso)
307 {
308         struct v3d_context *v3d = v3d_context(pctx);
309         v3d->blend = hwcso;
310         v3d->dirty |= VC5_DIRTY_BLEND;
311 }
312 
313 static void
v3d_rasterizer_state_bind(struct pipe_context * pctx,void * hwcso)314 v3d_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
315 {
316         struct v3d_context *v3d = v3d_context(pctx);
317         v3d->rasterizer = hwcso;
318         v3d->dirty |= VC5_DIRTY_RASTERIZER;
319 }
320 
321 static void
v3d_zsa_state_bind(struct pipe_context * pctx,void * hwcso)322 v3d_zsa_state_bind(struct pipe_context *pctx, void *hwcso)
323 {
324         struct v3d_context *v3d = v3d_context(pctx);
325         v3d->zsa = hwcso;
326         v3d->dirty |= VC5_DIRTY_ZSA;
327 }
328 
329 static void *
v3d_vertex_state_create(struct pipe_context * pctx,unsigned num_elements,const struct pipe_vertex_element * elements)330 v3d_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,
331                         const struct pipe_vertex_element *elements)
332 {
333         struct v3d_context *v3d = v3d_context(pctx);
334         struct v3d_vertex_stateobj *so = CALLOC_STRUCT(v3d_vertex_stateobj);
335 
336         if (!so)
337                 return NULL;
338 
339         memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
340         so->num_elements = num_elements;
341 
342         for (int i = 0; i < so->num_elements; i++) {
343                 const struct pipe_vertex_element *elem = &elements[i];
344                 const struct util_format_description *desc =
345                         util_format_description(elem->src_format);
346                 uint32_t r_size = desc->channel[0].size;
347 
348                 const uint32_t size =
349                         cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD);
350 
351                 v3dx_pack(&so->attrs[i * size],
352                           GL_SHADER_STATE_ATTRIBUTE_RECORD, attr) {
353                         /* vec_size == 0 means 4 */
354                         attr.vec_size = desc->nr_channels & 3;
355                         attr.signed_int_type = (desc->channel[0].type ==
356                                                 UTIL_FORMAT_TYPE_SIGNED);
357 
358                         attr.normalized_int_type = desc->channel[0].normalized;
359                         attr.read_as_int_uint = desc->channel[0].pure_integer;
360                         attr.instance_divisor = MIN2(elem->instance_divisor,
361                                                      0xffff);
362 
363                         switch (desc->channel[0].type) {
364                         case UTIL_FORMAT_TYPE_FLOAT:
365                                 if (r_size == 32) {
366                                         attr.type = ATTRIBUTE_FLOAT;
367                                 } else {
368                                         assert(r_size == 16);
369                                         attr.type = ATTRIBUTE_HALF_FLOAT;
370                                 }
371                                 break;
372 
373                         case UTIL_FORMAT_TYPE_SIGNED:
374                         case UTIL_FORMAT_TYPE_UNSIGNED:
375                                 switch (r_size) {
376                                 case 32:
377                                         attr.type = ATTRIBUTE_INT;
378                                         break;
379                                 case 16:
380                                         attr.type = ATTRIBUTE_SHORT;
381                                         break;
382                                 case 10:
383                                         attr.type = ATTRIBUTE_INT2_10_10_10;
384                                         break;
385                                 case 8:
386                                         attr.type = ATTRIBUTE_BYTE;
387                                         break;
388                                 default:
389                                         fprintf(stderr,
390                                                 "format %s unsupported\n",
391                                                 desc->name);
392                                         attr.type = ATTRIBUTE_BYTE;
393                                         abort();
394                                 }
395                                 break;
396 
397                         default:
398                                 fprintf(stderr,
399                                         "format %s unsupported\n",
400                                         desc->name);
401                                 abort();
402                         }
403                 }
404         }
405 
406         /* Set up the default attribute values in case any of the vertex
407          * elements use them.
408          */
409         uint32_t *attrs;
410         u_upload_alloc(v3d->state_uploader, 0,
411                        V3D_MAX_VS_INPUTS * sizeof(float), 16,
412                        &so->defaults_offset, &so->defaults, (void **)&attrs);
413 
414         for (int i = 0; i < V3D_MAX_VS_INPUTS / 4; i++) {
415                 attrs[i * 4 + 0] = 0;
416                 attrs[i * 4 + 1] = 0;
417                 attrs[i * 4 + 2] = 0;
418                 if (i < so->num_elements &&
419                     util_format_is_pure_integer(so->pipe[i].src_format)) {
420                         attrs[i * 4 + 3] = 1;
421                 } else {
422                         attrs[i * 4 + 3] = fui(1.0);
423                 }
424         }
425 
426         u_upload_unmap(v3d->state_uploader);
427         return so;
428 }
429 
430 static void
v3d_vertex_state_delete(struct pipe_context * pctx,void * hwcso)431 v3d_vertex_state_delete(struct pipe_context *pctx, void *hwcso)
432 {
433         struct v3d_vertex_stateobj *so = hwcso;
434 
435         pipe_resource_reference(&so->defaults, NULL);
436         free(so);
437 }
438 
439 static void
v3d_vertex_state_bind(struct pipe_context * pctx,void * hwcso)440 v3d_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
441 {
442         struct v3d_context *v3d = v3d_context(pctx);
443         v3d->vtx = hwcso;
444         v3d->dirty |= VC5_DIRTY_VTXSTATE;
445 }
446 
447 static void
v3d_set_constant_buffer(struct pipe_context * pctx,uint shader,uint index,const struct pipe_constant_buffer * cb)448 v3d_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index,
449                         const struct pipe_constant_buffer *cb)
450 {
451         struct v3d_context *v3d = v3d_context(pctx);
452         struct v3d_constbuf_stateobj *so = &v3d->constbuf[shader];
453 
454         util_copy_constant_buffer(&so->cb[index], cb);
455 
456         /* Note that the gallium frontend can unbind constant buffers by
457          * passing NULL here.
458          */
459         if (unlikely(!cb)) {
460                 so->enabled_mask &= ~(1 << index);
461                 so->dirty_mask &= ~(1 << index);
462                 return;
463         }
464 
465         so->enabled_mask |= 1 << index;
466         so->dirty_mask |= 1 << index;
467         v3d->dirty |= VC5_DIRTY_CONSTBUF;
468 }
469 
470 static void
v3d_set_framebuffer_state(struct pipe_context * pctx,const struct pipe_framebuffer_state * framebuffer)471 v3d_set_framebuffer_state(struct pipe_context *pctx,
472                           const struct pipe_framebuffer_state *framebuffer)
473 {
474         struct v3d_context *v3d = v3d_context(pctx);
475         struct pipe_framebuffer_state *cso = &v3d->framebuffer;
476 
477         v3d->job = NULL;
478 
479         util_copy_framebuffer_state(cso, framebuffer);
480 
481         v3d->swap_color_rb = 0;
482         v3d->blend_dst_alpha_one = 0;
483         for (int i = 0; i < v3d->framebuffer.nr_cbufs; i++) {
484                 struct pipe_surface *cbuf = v3d->framebuffer.cbufs[i];
485                 if (!cbuf)
486                         continue;
487                 struct v3d_surface *v3d_cbuf = v3d_surface(cbuf);
488 
489                 const struct util_format_description *desc =
490                         util_format_description(cbuf->format);
491 
492                 /* For BGRA8 formats (DRI window system default format), we
493                  * need to swap R and B, since the HW's format is RGBA8.  On
494                  * V3D 4.1+, the RCL can swap R and B on load/store.
495                  */
496                 if (v3d->screen->devinfo.ver < 41 && v3d_cbuf->swap_rb)
497                         v3d->swap_color_rb |= 1 << i;
498 
499                 if (desc->swizzle[3] == PIPE_SWIZZLE_1)
500                         v3d->blend_dst_alpha_one |= 1 << i;
501         }
502 
503         v3d->dirty |= VC5_DIRTY_FRAMEBUFFER;
504 }
505 
V3DX(Wrap_Mode)506 static enum V3DX(Wrap_Mode)
507 translate_wrap(uint32_t pipe_wrap, bool using_nearest)
508 {
509         switch (pipe_wrap) {
510         case PIPE_TEX_WRAP_REPEAT:
511                 return V3D_WRAP_MODE_REPEAT;
512         case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
513                 return V3D_WRAP_MODE_CLAMP;
514         case PIPE_TEX_WRAP_MIRROR_REPEAT:
515                 return V3D_WRAP_MODE_MIRROR;
516         case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
517                 return V3D_WRAP_MODE_BORDER;
518         case PIPE_TEX_WRAP_CLAMP:
519                 return (using_nearest ?
520                         V3D_WRAP_MODE_CLAMP :
521                         V3D_WRAP_MODE_BORDER);
522         default:
523                 unreachable("Unknown wrap mode");
524         }
525 }
526 
527 #if V3D_VERSION >= 40
528 static void
v3d_upload_sampler_state_variant(void * map,const struct pipe_sampler_state * cso,enum v3d_sampler_state_variant variant,bool either_nearest)529 v3d_upload_sampler_state_variant(void *map,
530                                  const struct pipe_sampler_state *cso,
531                                  enum v3d_sampler_state_variant variant,
532                                  bool either_nearest)
533 {
534         v3dx_pack(map, SAMPLER_STATE, sampler) {
535                 sampler.wrap_i_border = false;
536 
537                 sampler.wrap_s = translate_wrap(cso->wrap_s, either_nearest);
538                 sampler.wrap_t = translate_wrap(cso->wrap_t, either_nearest);
539                 sampler.wrap_r = translate_wrap(cso->wrap_r, either_nearest);
540 
541                 sampler.fixed_bias = cso->lod_bias;
542                 sampler.depth_compare_function = cso->compare_func;
543 
544                 sampler.min_filter_nearest =
545                         cso->min_img_filter == PIPE_TEX_FILTER_NEAREST;
546                 sampler.mag_filter_nearest =
547                         cso->mag_img_filter == PIPE_TEX_FILTER_NEAREST;
548                 sampler.mip_filter_nearest =
549                         cso->min_mip_filter != PIPE_TEX_MIPFILTER_LINEAR;
550 
551                 sampler.min_level_of_detail = MIN2(MAX2(0, cso->min_lod),
552                                                    15);
553                 sampler.max_level_of_detail = MIN2(cso->max_lod, 15);
554 
555                 /* If we're not doing inter-miplevel filtering, we need to
556                  * clamp the LOD so that we only sample from baselevel.
557                  * However, we need to still allow the calculated LOD to be
558                  * fractionally over the baselevel, so that the HW can decide
559                  * between the min and mag filters.
560                  */
561                 if (cso->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
562                         sampler.min_level_of_detail =
563                                 MIN2(sampler.min_level_of_detail, 1.0 / 256.0);
564                         sampler.max_level_of_detail =
565                                 MIN2(sampler.max_level_of_detail, 1.0 / 256.0);
566                 }
567 
568                 if (cso->max_anisotropy) {
569                         sampler.anisotropy_enable = true;
570 
571                         if (cso->max_anisotropy > 8)
572                                 sampler.maximum_anisotropy = 3;
573                         else if (cso->max_anisotropy > 4)
574                                 sampler.maximum_anisotropy = 2;
575                         else if (cso->max_anisotropy > 2)
576                                 sampler.maximum_anisotropy = 1;
577                 }
578 
579                 if (variant == V3D_SAMPLER_STATE_BORDER_0) {
580                         sampler.border_color_mode = V3D_BORDER_COLOR_0000;
581                 } else {
582                         sampler.border_color_mode = V3D_BORDER_COLOR_FOLLOWS;
583 
584                         union pipe_color_union border;
585 
586                         /* First, reswizzle the border color for any
587                          * mismatching we're doing between the texture's
588                          * channel order in hardware (R) versus what it is at
589                          * the GL level (ALPHA)
590                          */
591                         switch (variant) {
592                         case V3D_SAMPLER_STATE_F16_BGRA:
593                         case V3D_SAMPLER_STATE_F16_BGRA_UNORM:
594                         case V3D_SAMPLER_STATE_F16_BGRA_SNORM:
595                                 border.i[0] = cso->border_color.i[2];
596                                 border.i[1] = cso->border_color.i[1];
597                                 border.i[2] = cso->border_color.i[0];
598                                 border.i[3] = cso->border_color.i[3];
599                                 break;
600 
601                         case V3D_SAMPLER_STATE_F16_A:
602                         case V3D_SAMPLER_STATE_F16_A_UNORM:
603                         case V3D_SAMPLER_STATE_F16_A_SNORM:
604                         case V3D_SAMPLER_STATE_32_A:
605                         case V3D_SAMPLER_STATE_32_A_UNORM:
606                         case V3D_SAMPLER_STATE_32_A_SNORM:
607                                 border.i[0] = cso->border_color.i[3];
608                                 border.i[1] = 0;
609                                 border.i[2] = 0;
610                                 border.i[3] = 0;
611                                 break;
612 
613                         case V3D_SAMPLER_STATE_F16_LA:
614                         case V3D_SAMPLER_STATE_F16_LA_UNORM:
615                         case V3D_SAMPLER_STATE_F16_LA_SNORM:
616                                 border.i[0] = cso->border_color.i[0];
617                                 border.i[1] = cso->border_color.i[3];
618                                 border.i[2] = 0;
619                                 border.i[3] = 0;
620                                 break;
621 
622                         default:
623                                 border = cso->border_color;
624                         }
625 
626                         /* Perform any clamping. */
627                         switch (variant) {
628                         case V3D_SAMPLER_STATE_F16_UNORM:
629                         case V3D_SAMPLER_STATE_F16_BGRA_UNORM:
630                         case V3D_SAMPLER_STATE_F16_A_UNORM:
631                         case V3D_SAMPLER_STATE_F16_LA_UNORM:
632                         case V3D_SAMPLER_STATE_32_UNORM:
633                         case V3D_SAMPLER_STATE_32_A_UNORM:
634                                 for (int i = 0; i < 4; i++)
635                                         border.f[i] = CLAMP(border.f[i], 0, 1);
636                                 break;
637 
638                         case V3D_SAMPLER_STATE_F16_SNORM:
639                         case V3D_SAMPLER_STATE_F16_BGRA_SNORM:
640                         case V3D_SAMPLER_STATE_F16_A_SNORM:
641                         case V3D_SAMPLER_STATE_F16_LA_SNORM:
642                         case V3D_SAMPLER_STATE_32_SNORM:
643                         case V3D_SAMPLER_STATE_32_A_SNORM:
644                                 for (int i = 0; i < 4; i++)
645                                         border.f[i] = CLAMP(border.f[i], -1, 1);
646                                 break;
647 
648                         case V3D_SAMPLER_STATE_1010102U:
649                                 border.ui[0] = CLAMP(border.ui[0],
650                                                      0, (1 << 10) - 1);
651                                 border.ui[1] = CLAMP(border.ui[1],
652                                                      0, (1 << 10) - 1);
653                                 border.ui[2] = CLAMP(border.ui[2],
654                                                      0, (1 << 10) - 1);
655                                 border.ui[3] = CLAMP(border.ui[3],
656                                                      0, 3);
657                                 break;
658 
659                         case V3D_SAMPLER_STATE_16U:
660                                 for (int i = 0; i < 4; i++)
661                                         border.ui[i] = CLAMP(border.ui[i],
662                                                              0, 0xffff);
663                                 break;
664 
665                         case V3D_SAMPLER_STATE_16I:
666                                 for (int i = 0; i < 4; i++)
667                                         border.i[i] = CLAMP(border.i[i],
668                                                             -32768, 32767);
669                                 break;
670 
671                         case V3D_SAMPLER_STATE_8U:
672                                 for (int i = 0; i < 4; i++)
673                                         border.ui[i] = CLAMP(border.ui[i],
674                                                              0, 0xff);
675                                 break;
676 
677                         case V3D_SAMPLER_STATE_8I:
678                                 for (int i = 0; i < 4; i++)
679                                         border.i[i] = CLAMP(border.i[i],
680                                                             -128, 127);
681                                 break;
682 
683                         default:
684                                 break;
685                         }
686 
687                         if (variant >= V3D_SAMPLER_STATE_32) {
688                                 sampler.border_color_word_0 = border.ui[0];
689                                 sampler.border_color_word_1 = border.ui[1];
690                                 sampler.border_color_word_2 = border.ui[2];
691                                 sampler.border_color_word_3 = border.ui[3];
692                         } else {
693                                 sampler.border_color_word_0 =
694                                         _mesa_float_to_half(border.f[0]);
695                                 sampler.border_color_word_1 =
696                                         _mesa_float_to_half(border.f[1]);
697                                 sampler.border_color_word_2 =
698                                         _mesa_float_to_half(border.f[2]);
699                                 sampler.border_color_word_3 =
700                                         _mesa_float_to_half(border.f[3]);
701                         }
702                 }
703         }
704 }
705 #endif
706 
707 static void *
v3d_create_sampler_state(struct pipe_context * pctx,const struct pipe_sampler_state * cso)708 v3d_create_sampler_state(struct pipe_context *pctx,
709                          const struct pipe_sampler_state *cso)
710 {
711         UNUSED struct v3d_context *v3d = v3d_context(pctx);
712         struct v3d_sampler_state *so = CALLOC_STRUCT(v3d_sampler_state);
713 
714         if (!so)
715                 return NULL;
716 
717         memcpy(so, cso, sizeof(*cso));
718 
719         bool either_nearest =
720                 (cso->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST ||
721                  cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST);
722 
723         enum V3DX(Wrap_Mode) wrap_s = translate_wrap(cso->wrap_s,
724                                                      either_nearest);
725         enum V3DX(Wrap_Mode) wrap_t = translate_wrap(cso->wrap_t,
726                                                      either_nearest);
727         enum V3DX(Wrap_Mode) wrap_r = translate_wrap(cso->wrap_r,
728                                                      either_nearest);
729 
730         bool uses_border_color = (wrap_s == V3D_WRAP_MODE_BORDER ||
731                                   wrap_t == V3D_WRAP_MODE_BORDER ||
732                                   wrap_r == V3D_WRAP_MODE_BORDER);
733         so->border_color_variants = (uses_border_color &&
734                                      (cso->border_color.ui[0] != 0 ||
735                                       cso->border_color.ui[1] != 0 ||
736                                       cso->border_color.ui[2] != 0 ||
737                                       cso->border_color.ui[3] != 0));
738 
739 #if V3D_VERSION >= 40
740         void *map;
741         int sampler_align = so->border_color_variants ? 32 : 8;
742         int sampler_size = align(cl_packet_length(SAMPLER_STATE), sampler_align);
743         int num_variants = (so->border_color_variants ? ARRAY_SIZE(so->sampler_state_offset) : 1);
744         u_upload_alloc(v3d->state_uploader, 0,
745                        sampler_size * num_variants,
746                        sampler_align,
747                        &so->sampler_state_offset[0],
748                        &so->sampler_state,
749                        &map);
750 
751         for (int i = 0; i < num_variants; i++) {
752                 so->sampler_state_offset[i] =
753                         so->sampler_state_offset[0] + i * sampler_size;
754                 v3d_upload_sampler_state_variant(map + i * sampler_size,
755                                                  cso, i, either_nearest);
756         }
757 
758 #else /* V3D_VERSION < 40 */
759         v3dx_pack(&so->p0, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1, p0) {
760                 p0.s_wrap_mode = wrap_s;
761                 p0.t_wrap_mode = wrap_t;
762                 p0.r_wrap_mode = wrap_r;
763         }
764 
765         v3dx_pack(&so->texture_shader_state, TEXTURE_SHADER_STATE, tex) {
766                 tex.depth_compare_function = cso->compare_func;
767                 tex.fixed_bias = cso->lod_bias;
768         }
769 #endif /* V3D_VERSION < 40 */
770         return so;
771 }
772 
773 static void
v3d_sampler_states_bind(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned nr,void ** hwcso)774 v3d_sampler_states_bind(struct pipe_context *pctx,
775                         enum pipe_shader_type shader, unsigned start,
776                         unsigned nr, void **hwcso)
777 {
778         struct v3d_context *v3d = v3d_context(pctx);
779         struct v3d_texture_stateobj *stage_tex = &v3d->tex[shader];
780 
781         assert(start == 0);
782         unsigned i;
783         unsigned new_nr = 0;
784 
785         for (i = 0; i < nr; i++) {
786                 if (hwcso[i])
787                         new_nr = i + 1;
788                 stage_tex->samplers[i] = hwcso[i];
789         }
790 
791         for (; i < stage_tex->num_samplers; i++) {
792                 stage_tex->samplers[i] = NULL;
793         }
794 
795         stage_tex->num_samplers = new_nr;
796 
797         v3d_flag_dirty_sampler_state(v3d, shader);
798 }
799 
800 static void
v3d_sampler_state_delete(struct pipe_context * pctx,void * hwcso)801 v3d_sampler_state_delete(struct pipe_context *pctx,
802                          void *hwcso)
803 {
804         struct pipe_sampler_state *psampler = hwcso;
805         struct v3d_sampler_state *sampler = v3d_sampler_state(psampler);
806 
807         pipe_resource_reference(&sampler->sampler_state, NULL);
808         free(psampler);
809 }
810 
811 #if V3D_VERSION >= 40
812 static uint32_t
translate_swizzle(unsigned char pipe_swizzle)813 translate_swizzle(unsigned char pipe_swizzle)
814 {
815         switch (pipe_swizzle) {
816         case PIPE_SWIZZLE_0:
817                 return 0;
818         case PIPE_SWIZZLE_1:
819                 return 1;
820         case PIPE_SWIZZLE_X:
821         case PIPE_SWIZZLE_Y:
822         case PIPE_SWIZZLE_Z:
823         case PIPE_SWIZZLE_W:
824                 return 2 + pipe_swizzle;
825         default:
826                 unreachable("unknown swizzle");
827         }
828 }
829 #endif
830 
831 static void
v3d_setup_texture_shader_state(struct V3DX (TEXTURE_SHADER_STATE)* tex,struct pipe_resource * prsc,int base_level,int last_level,int first_layer,int last_layer)832 v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex,
833                                struct pipe_resource *prsc,
834                                int base_level, int last_level,
835                                int first_layer, int last_layer)
836 {
837         struct v3d_resource *rsc = v3d_resource(prsc);
838         int msaa_scale = prsc->nr_samples > 1 ? 2 : 1;
839 
840         tex->image_width = prsc->width0 * msaa_scale;
841         tex->image_height = prsc->height0 * msaa_scale;
842 
843 #if V3D_VERSION >= 40
844         /* On 4.x, the height of a 1D texture is redefined to be the
845          * upper 14 bits of the width (which is only usable with txf).
846          */
847         if (prsc->target == PIPE_TEXTURE_1D ||
848             prsc->target == PIPE_TEXTURE_1D_ARRAY) {
849                 tex->image_height = tex->image_width >> 14;
850         }
851 
852         tex->image_width &= (1 << 14) - 1;
853         tex->image_height &= (1 << 14) - 1;
854 #endif
855 
856         if (prsc->target == PIPE_TEXTURE_3D) {
857                 tex->image_depth = prsc->depth0;
858         } else {
859                 tex->image_depth = (last_layer - first_layer) + 1;
860         }
861 
862         tex->base_level = base_level;
863 #if V3D_VERSION >= 40
864         tex->max_level = last_level;
865         /* Note that we don't have a job to reference the texture's sBO
866          * at state create time, so any time this sampler view is used
867          * we need to add the texture to the job.
868          */
869         tex->texture_base_pointer =
870                 cl_address(NULL,
871                            rsc->bo->offset +
872                            v3d_layer_offset(prsc, 0, first_layer));
873 #endif
874         tex->array_stride_64_byte_aligned = rsc->cube_map_stride / 64;
875 
876         /* Since other platform devices may produce UIF images even
877          * when they're not big enough for V3D to assume they're UIF,
878          * we force images with level 0 as UIF to be always treated
879          * that way.
880          */
881         tex->level_0_is_strictly_uif =
882                 (rsc->slices[0].tiling == VC5_TILING_UIF_XOR ||
883                  rsc->slices[0].tiling == VC5_TILING_UIF_NO_XOR);
884         tex->level_0_xor_enable = (rsc->slices[0].tiling == VC5_TILING_UIF_XOR);
885 
886         if (tex->level_0_is_strictly_uif)
887                 tex->level_0_ub_pad = rsc->slices[0].ub_pad;
888 
889 #if V3D_VERSION >= 40
890         if (tex->uif_xor_disable ||
891             tex->level_0_is_strictly_uif) {
892                 tex->extended = true;
893         }
894 #endif /* V3D_VERSION >= 40 */
895 }
896 
897 void
v3dX(create_texture_shader_state_bo)898 v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d,
899                                      struct v3d_sampler_view *so)
900 {
901         struct pipe_resource *prsc = so->texture;
902         const struct pipe_sampler_view *cso = &so->base;
903         struct v3d_screen *screen = v3d->screen;
904 
905         void *map;
906 
907 #if V3D_VERSION >= 40
908         v3d_bo_unreference(&so->bo);
909         so->bo = v3d_bo_alloc(v3d->screen,
910                               cl_packet_length(TEXTURE_SHADER_STATE), "sampler");
911         map = v3d_bo_map(so->bo);
912 #else /* V3D_VERSION < 40 */
913         STATIC_ASSERT(sizeof(so->texture_shader_state) >=
914                       cl_packet_length(TEXTURE_SHADER_STATE));
915         map = &so->texture_shader_state;
916 #endif
917 
918         v3dx_pack(map, TEXTURE_SHADER_STATE, tex) {
919                 v3d_setup_texture_shader_state(&tex, prsc,
920                                                cso->u.tex.first_level,
921                                                cso->u.tex.last_level,
922                                                cso->u.tex.first_layer,
923                                                cso->u.tex.last_layer);
924 
925                 tex.srgb = util_format_is_srgb(cso->format);
926 
927 #if V3D_VERSION >= 40
928                 tex.swizzle_r = translate_swizzle(so->swizzle[0]);
929                 tex.swizzle_g = translate_swizzle(so->swizzle[1]);
930                 tex.swizzle_b = translate_swizzle(so->swizzle[2]);
931                 tex.swizzle_a = translate_swizzle(so->swizzle[3]);
932 #endif
933 
934                 if (prsc->nr_samples > 1 && V3D_VERSION < 40) {
935                         /* Using texture views to reinterpret formats on our
936                          * MSAA textures won't work, because we don't lay out
937                          * the bits in memory as it's expected -- for example,
938                          * RGBA8 and RGB10_A2 are compatible in the
939                          * ARB_texture_view spec, but in HW we lay them out as
940                          * 32bpp RGBA8 and 64bpp RGBA16F.  Just assert for now
941                          * to catch failures.
942                          *
943                          * We explicitly allow remapping S8Z24 to RGBA8888 for
944                          * v3d_blit.c's stencil blits.
945                          */
946                         assert((util_format_linear(cso->format) ==
947                                 util_format_linear(prsc->format)) ||
948                                (prsc->format == PIPE_FORMAT_S8_UINT_Z24_UNORM &&
949                                 cso->format == PIPE_FORMAT_R8G8B8A8_UNORM));
950                         uint32_t output_image_format =
951                                 v3d_get_rt_format(&screen->devinfo, cso->format);
952                         uint32_t internal_type;
953                         uint32_t internal_bpp;
954                         v3d_get_internal_type_bpp_for_output_format(&screen->devinfo,
955                                                                     output_image_format,
956                                                                     &internal_type,
957                                                                     &internal_bpp);
958 
959                         switch (internal_type) {
960                         case V3D_INTERNAL_TYPE_8:
961                                 tex.texture_type = TEXTURE_DATA_FORMAT_RGBA8;
962                                 break;
963                         case V3D_INTERNAL_TYPE_16F:
964                                 tex.texture_type = TEXTURE_DATA_FORMAT_RGBA16F;
965                                 break;
966                         default:
967                                 unreachable("Bad MSAA texture type");
968                         }
969 
970                         /* sRGB was stored in the tile buffer as linear and
971                          * would have been encoded to sRGB on resolved tile
972                          * buffer store.  Note that this means we would need
973                          * shader code if we wanted to read an MSAA sRGB
974                          * texture without sRGB decode.
975                          */
976                         tex.srgb = false;
977                 } else {
978                         tex.texture_type = v3d_get_tex_format(&screen->devinfo,
979                                                               cso->format);
980                 }
981         };
982 }
983 
984 static struct pipe_sampler_view *
v3d_create_sampler_view(struct pipe_context * pctx,struct pipe_resource * prsc,const struct pipe_sampler_view * cso)985 v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
986                         const struct pipe_sampler_view *cso)
987 {
988         struct v3d_context *v3d = v3d_context(pctx);
989         struct v3d_screen *screen = v3d->screen;
990         struct v3d_sampler_view *so = CALLOC_STRUCT(v3d_sampler_view);
991         struct v3d_resource *rsc = v3d_resource(prsc);
992 
993         if (!so)
994                 return NULL;
995 
996         so->base = *cso;
997 
998         pipe_reference(NULL, &prsc->reference);
999 
1000         /* Compute the sampler view's swizzle up front. This will be plugged
1001          * into either the sampler (for 16-bit returns) or the shader's
1002          * texture key (for 32)
1003          */
1004         uint8_t view_swizzle[4] = {
1005                 cso->swizzle_r,
1006                 cso->swizzle_g,
1007                 cso->swizzle_b,
1008                 cso->swizzle_a
1009         };
1010         const uint8_t *fmt_swizzle =
1011                 v3d_get_format_swizzle(&screen->devinfo, so->base.format);
1012         util_format_compose_swizzles(fmt_swizzle, view_swizzle, so->swizzle);
1013 
1014         so->base.texture = prsc;
1015         so->base.reference.count = 1;
1016         so->base.context = pctx;
1017 
1018         if (rsc->separate_stencil &&
1019             cso->format == PIPE_FORMAT_X32_S8X24_UINT) {
1020                 rsc = rsc->separate_stencil;
1021                 prsc = &rsc->base;
1022         }
1023 
1024         /* If we're sampling depth from depth/stencil, demote the format to
1025          * just depth.  u_format will end up giving the answers for the
1026          * stencil channel, otherwise.
1027          */
1028         enum pipe_format sample_format = cso->format;
1029         if (sample_format == PIPE_FORMAT_S8_UINT_Z24_UNORM)
1030                 sample_format = PIPE_FORMAT_X8Z24_UNORM;
1031 
1032 #if V3D_VERSION >= 40
1033         const struct util_format_description *desc =
1034                 util_format_description(sample_format);
1035 
1036         if (util_format_is_pure_integer(sample_format) &&
1037             !util_format_has_depth(desc)) {
1038                 int chan = util_format_get_first_non_void_channel(sample_format);
1039                 if (util_format_is_pure_uint(sample_format)) {
1040                         switch (desc->channel[chan].size) {
1041                         case 32:
1042                                 so->sampler_variant = V3D_SAMPLER_STATE_32;
1043                                 break;
1044                         case 16:
1045                                 so->sampler_variant = V3D_SAMPLER_STATE_16U;
1046                                 break;
1047                         case 10:
1048                                 so->sampler_variant = V3D_SAMPLER_STATE_1010102U;
1049                                 break;
1050                         case 8:
1051                                 so->sampler_variant = V3D_SAMPLER_STATE_8U;
1052                                 break;
1053                         }
1054                 } else {
1055                         switch (desc->channel[chan].size) {
1056                         case 32:
1057                                 so->sampler_variant = V3D_SAMPLER_STATE_32;
1058                                 break;
1059                         case 16:
1060                                 so->sampler_variant = V3D_SAMPLER_STATE_16I;
1061                                 break;
1062                         case 8:
1063                                 so->sampler_variant = V3D_SAMPLER_STATE_8I;
1064                                 break;
1065                         }
1066                 }
1067         } else {
1068                 if (v3d_get_tex_return_size(&screen->devinfo, sample_format,
1069                                            PIPE_TEX_COMPARE_NONE) == 32) {
1070                         if (util_format_is_alpha(sample_format))
1071                                 so->sampler_variant = V3D_SAMPLER_STATE_32_A;
1072                         else
1073                                 so->sampler_variant = V3D_SAMPLER_STATE_32;
1074                 } else {
1075                         if (util_format_is_luminance_alpha(sample_format))
1076                                 so->sampler_variant = V3D_SAMPLER_STATE_F16_LA;
1077                         else if (util_format_is_alpha(sample_format))
1078                                 so->sampler_variant = V3D_SAMPLER_STATE_F16_A;
1079                         else if (fmt_swizzle[0] == PIPE_SWIZZLE_Z)
1080                                 so->sampler_variant = V3D_SAMPLER_STATE_F16_BGRA;
1081                         else
1082                                 so->sampler_variant = V3D_SAMPLER_STATE_F16;
1083 
1084                 }
1085 
1086                 if (util_format_is_unorm(sample_format)) {
1087                         so->sampler_variant += (V3D_SAMPLER_STATE_F16_UNORM -
1088                                                 V3D_SAMPLER_STATE_F16);
1089                 } else if (util_format_is_snorm(sample_format)){
1090                         so->sampler_variant += (V3D_SAMPLER_STATE_F16_SNORM -
1091                                                 V3D_SAMPLER_STATE_F16);
1092                 }
1093         }
1094 #endif
1095 
1096         /* V3D still doesn't support sampling from raster textures, so we will
1097          * have to copy to a temporary tiled texture.
1098          */
1099         if (!rsc->tiled && !(prsc->target == PIPE_TEXTURE_1D ||
1100                              prsc->target == PIPE_TEXTURE_1D_ARRAY)) {
1101                 struct v3d_resource *shadow_parent = rsc;
1102                 struct pipe_resource tmpl = {
1103                         .target = prsc->target,
1104                         .format = prsc->format,
1105                         .width0 = u_minify(prsc->width0,
1106                                            cso->u.tex.first_level),
1107                         .height0 = u_minify(prsc->height0,
1108                                             cso->u.tex.first_level),
1109                         .depth0 = 1,
1110                         .array_size = 1,
1111                         .bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
1112                         .last_level = cso->u.tex.last_level - cso->u.tex.first_level,
1113                         .nr_samples = prsc->nr_samples,
1114                 };
1115 
1116                 /* Create the shadow texture.  The rest of the sampler view
1117                  * setup will use the shadow.
1118                  */
1119                 prsc = v3d_resource_create(pctx->screen, &tmpl);
1120                 if (!prsc) {
1121                         free(so);
1122                         return NULL;
1123                 }
1124                 rsc = v3d_resource(prsc);
1125 
1126                 /* Flag it as needing update of the contents from the parent. */
1127                 rsc->writes = shadow_parent->writes - 1;
1128                 assert(rsc->tiled);
1129 
1130                 so->texture = prsc;
1131         } else {
1132                 pipe_resource_reference(&so->texture, prsc);
1133         }
1134 
1135         v3d_create_texture_shader_state_bo(v3d, so);
1136 
1137         return &so->base;
1138 }
1139 
1140 static void
v3d_sampler_view_destroy(struct pipe_context * pctx,struct pipe_sampler_view * psview)1141 v3d_sampler_view_destroy(struct pipe_context *pctx,
1142                          struct pipe_sampler_view *psview)
1143 {
1144         struct v3d_sampler_view *sview = v3d_sampler_view(psview);
1145 
1146         v3d_bo_unreference(&sview->bo);
1147         pipe_resource_reference(&psview->texture, NULL);
1148         pipe_resource_reference(&sview->texture, NULL);
1149         free(psview);
1150 }
1151 
1152 static void
v3d_set_sampler_views(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned nr,struct pipe_sampler_view ** views)1153 v3d_set_sampler_views(struct pipe_context *pctx,
1154                       enum pipe_shader_type shader,
1155                       unsigned start, unsigned nr,
1156                       struct pipe_sampler_view **views)
1157 {
1158         struct v3d_context *v3d = v3d_context(pctx);
1159         struct v3d_texture_stateobj *stage_tex = &v3d->tex[shader];
1160         unsigned i;
1161         unsigned new_nr = 0;
1162 
1163         assert(start == 0);
1164 
1165         for (i = 0; i < nr; i++) {
1166                 if (views[i])
1167                         new_nr = i + 1;
1168                 pipe_sampler_view_reference(&stage_tex->textures[i], views[i]);
1169         }
1170 
1171         for (; i < stage_tex->num_textures; i++) {
1172                 pipe_sampler_view_reference(&stage_tex->textures[i], NULL);
1173         }
1174 
1175         stage_tex->num_textures = new_nr;
1176 
1177         v3d_flag_dirty_sampler_state(v3d, shader);
1178 }
1179 
1180 static struct pipe_stream_output_target *
v3d_create_stream_output_target(struct pipe_context * pctx,struct pipe_resource * prsc,unsigned buffer_offset,unsigned buffer_size)1181 v3d_create_stream_output_target(struct pipe_context *pctx,
1182                                 struct pipe_resource *prsc,
1183                                 unsigned buffer_offset,
1184                                 unsigned buffer_size)
1185 {
1186         struct v3d_stream_output_target *target;
1187 
1188         target = CALLOC_STRUCT(v3d_stream_output_target);
1189         if (!target)
1190                 return NULL;
1191 
1192         pipe_reference_init(&target->base.reference, 1);
1193         pipe_resource_reference(&target->base.buffer, prsc);
1194 
1195         target->base.context = pctx;
1196         target->base.buffer_offset = buffer_offset;
1197         target->base.buffer_size = buffer_size;
1198 
1199         return &target->base;
1200 }
1201 
1202 static void
v3d_stream_output_target_destroy(struct pipe_context * pctx,struct pipe_stream_output_target * target)1203 v3d_stream_output_target_destroy(struct pipe_context *pctx,
1204                                  struct pipe_stream_output_target *target)
1205 {
1206         pipe_resource_reference(&target->buffer, NULL);
1207         free(target);
1208 }
1209 
1210 static void
v3d_set_stream_output_targets(struct pipe_context * pctx,unsigned num_targets,struct pipe_stream_output_target ** targets,const unsigned * offsets)1211 v3d_set_stream_output_targets(struct pipe_context *pctx,
1212                               unsigned num_targets,
1213                               struct pipe_stream_output_target **targets,
1214                               const unsigned *offsets)
1215 {
1216         struct v3d_context *ctx = v3d_context(pctx);
1217         struct v3d_streamout_stateobj *so = &ctx->streamout;
1218         unsigned i;
1219 
1220         assert(num_targets <= ARRAY_SIZE(so->targets));
1221 
1222         /* Update recorded vertex counts when we are ending the recording of
1223          * transform feedback. We do this when we switch primitive types
1224          * at draw time, but if we haven't switched primitives in our last
1225          * draw we need to do it here as well.
1226          */
1227         if (num_targets == 0 && so->num_targets > 0)
1228                 v3d_update_primitive_counters(ctx);
1229 
1230         for (i = 0; i < num_targets; i++) {
1231                 if (offsets[i] != -1)
1232                         so->offsets[i] = offsets[i];
1233 
1234                 pipe_so_target_reference(&so->targets[i], targets[i]);
1235         }
1236 
1237         for (; i < so->num_targets; i++)
1238                 pipe_so_target_reference(&so->targets[i], NULL);
1239 
1240         so->num_targets = num_targets;
1241 
1242         /* Create primitive counters BO if needed */
1243         if (num_targets > 0 && !ctx->prim_counts) {
1244                 /* Init all 7 counters and 1 padding to 0 */
1245                 uint32_t zeroes[8] = { 0 };
1246                 u_upload_data(ctx->uploader,
1247                               0, sizeof(zeroes), 32, zeroes,
1248                               &ctx->prim_counts_offset,
1249                               &ctx->prim_counts);
1250         }
1251 
1252         ctx->dirty |= VC5_DIRTY_STREAMOUT;
1253 }
1254 
1255 static void
v3d_set_shader_buffers(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned count,const struct pipe_shader_buffer * buffers,unsigned writable_bitmask)1256 v3d_set_shader_buffers(struct pipe_context *pctx,
1257                        enum pipe_shader_type shader,
1258                        unsigned start, unsigned count,
1259                        const struct pipe_shader_buffer *buffers,
1260                        unsigned writable_bitmask)
1261 {
1262         struct v3d_context *v3d = v3d_context(pctx);
1263         struct v3d_ssbo_stateobj *so = &v3d->ssbo[shader];
1264         unsigned mask = 0;
1265 
1266         if (buffers) {
1267                 for (unsigned i = 0; i < count; i++) {
1268                         unsigned n = i + start;
1269                         struct pipe_shader_buffer *buf = &so->sb[n];
1270 
1271                         if ((buf->buffer == buffers[i].buffer) &&
1272                             (buf->buffer_offset == buffers[i].buffer_offset) &&
1273                             (buf->buffer_size == buffers[i].buffer_size))
1274                                 continue;
1275 
1276                         mask |= 1 << n;
1277 
1278                         buf->buffer_offset = buffers[i].buffer_offset;
1279                         buf->buffer_size = buffers[i].buffer_size;
1280                         pipe_resource_reference(&buf->buffer, buffers[i].buffer);
1281 
1282                         if (buf->buffer)
1283                                 so->enabled_mask |= 1 << n;
1284                         else
1285                                 so->enabled_mask &= ~(1 << n);
1286                 }
1287         } else {
1288                 mask = ((1 << count) - 1) << start;
1289 
1290                 for (unsigned i = 0; i < count; i++) {
1291                         unsigned n = i + start;
1292                         struct pipe_shader_buffer *buf = &so->sb[n];
1293 
1294                         pipe_resource_reference(&buf->buffer, NULL);
1295                 }
1296 
1297                 so->enabled_mask &= ~mask;
1298         }
1299 
1300         v3d->dirty |= VC5_DIRTY_SSBO;
1301 }
1302 
1303 static void
v3d_create_image_view_texture_shader_state(struct v3d_context * v3d,struct v3d_shaderimg_stateobj * so,int img)1304 v3d_create_image_view_texture_shader_state(struct v3d_context *v3d,
1305                                            struct v3d_shaderimg_stateobj *so,
1306                                            int img)
1307 {
1308 #if V3D_VERSION >= 40
1309         struct v3d_image_view *iview = &so->si[img];
1310 
1311         void *map;
1312         u_upload_alloc(v3d->uploader, 0, cl_packet_length(TEXTURE_SHADER_STATE),
1313                        32,
1314                        &iview->tex_state_offset,
1315                        &iview->tex_state,
1316                        &map);
1317 
1318         struct pipe_resource *prsc = iview->base.resource;
1319 
1320         v3dx_pack(map, TEXTURE_SHADER_STATE, tex) {
1321                 v3d_setup_texture_shader_state(&tex, prsc,
1322                                                iview->base.u.tex.level,
1323                                                iview->base.u.tex.level,
1324                                                iview->base.u.tex.first_layer,
1325                                                iview->base.u.tex.last_layer);
1326 
1327                 tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);
1328                 tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);
1329                 tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z);
1330                 tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W);
1331 
1332                 tex.texture_type = v3d_get_tex_format(&v3d->screen->devinfo,
1333                                                       iview->base.format);
1334         };
1335 #else /* V3D_VERSION < 40 */
1336         /* V3D 3.x doesn't use support shader image load/store operations on
1337          * textures, so it would get lowered in the shader to general memory
1338          * acceses.
1339          */
1340 #endif
1341 }
1342 
1343 static void
v3d_set_shader_images(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned count,const struct pipe_image_view * images)1344 v3d_set_shader_images(struct pipe_context *pctx,
1345                       enum pipe_shader_type shader,
1346                       unsigned start, unsigned count,
1347                       const struct pipe_image_view *images)
1348 {
1349         struct v3d_context *v3d = v3d_context(pctx);
1350         struct v3d_shaderimg_stateobj *so = &v3d->shaderimg[shader];
1351 
1352         if (images) {
1353                 for (unsigned i = 0; i < count; i++) {
1354                         unsigned n = i + start;
1355                         struct v3d_image_view *iview = &so->si[n];
1356 
1357                         if ((iview->base.resource == images[i].resource) &&
1358                             (iview->base.format == images[i].format) &&
1359                             (iview->base.access == images[i].access) &&
1360                             !memcmp(&iview->base.u, &images[i].u,
1361                                     sizeof(iview->base.u)))
1362                                 continue;
1363 
1364                         util_copy_image_view(&iview->base, &images[i]);
1365 
1366                         if (iview->base.resource) {
1367                                 so->enabled_mask |= 1 << n;
1368                                 v3d_create_image_view_texture_shader_state(v3d,
1369                                                                            so,
1370                                                                            n);
1371                         } else {
1372                                 so->enabled_mask &= ~(1 << n);
1373                                 pipe_resource_reference(&iview->tex_state, NULL);
1374                         }
1375                 }
1376         } else {
1377                 for (unsigned i = 0; i < count; i++) {
1378                         unsigned n = i + start;
1379                         struct v3d_image_view *iview = &so->si[n];
1380 
1381                         pipe_resource_reference(&iview->base.resource, NULL);
1382                         pipe_resource_reference(&iview->tex_state, NULL);
1383                 }
1384 
1385                 if (count == 32)
1386                         so->enabled_mask = 0;
1387                 else
1388                         so->enabled_mask &= ~(((1 << count) - 1) << start);
1389         }
1390 
1391         v3d->dirty |= VC5_DIRTY_SHADER_IMAGE;
1392 }
1393 
1394 void
v3dX(state_init)1395 v3dX(state_init)(struct pipe_context *pctx)
1396 {
1397         pctx->set_blend_color = v3d_set_blend_color;
1398         pctx->set_stencil_ref = v3d_set_stencil_ref;
1399         pctx->set_clip_state = v3d_set_clip_state;
1400         pctx->set_sample_mask = v3d_set_sample_mask;
1401         pctx->set_constant_buffer = v3d_set_constant_buffer;
1402         pctx->set_framebuffer_state = v3d_set_framebuffer_state;
1403         pctx->set_polygon_stipple = v3d_set_polygon_stipple;
1404         pctx->set_scissor_states = v3d_set_scissor_states;
1405         pctx->set_viewport_states = v3d_set_viewport_states;
1406 
1407         pctx->set_vertex_buffers = v3d_set_vertex_buffers;
1408 
1409         pctx->create_blend_state = v3d_create_blend_state;
1410         pctx->bind_blend_state = v3d_blend_state_bind;
1411         pctx->delete_blend_state = v3d_generic_cso_state_delete;
1412 
1413         pctx->create_rasterizer_state = v3d_create_rasterizer_state;
1414         pctx->bind_rasterizer_state = v3d_rasterizer_state_bind;
1415         pctx->delete_rasterizer_state = v3d_generic_cso_state_delete;
1416 
1417         pctx->create_depth_stencil_alpha_state = v3d_create_depth_stencil_alpha_state;
1418         pctx->bind_depth_stencil_alpha_state = v3d_zsa_state_bind;
1419         pctx->delete_depth_stencil_alpha_state = v3d_generic_cso_state_delete;
1420 
1421         pctx->create_vertex_elements_state = v3d_vertex_state_create;
1422         pctx->delete_vertex_elements_state = v3d_vertex_state_delete;
1423         pctx->bind_vertex_elements_state = v3d_vertex_state_bind;
1424 
1425         pctx->create_sampler_state = v3d_create_sampler_state;
1426         pctx->delete_sampler_state = v3d_sampler_state_delete;
1427         pctx->bind_sampler_states = v3d_sampler_states_bind;
1428 
1429         pctx->create_sampler_view = v3d_create_sampler_view;
1430         pctx->sampler_view_destroy = v3d_sampler_view_destroy;
1431         pctx->set_sampler_views = v3d_set_sampler_views;
1432 
1433         pctx->set_shader_buffers = v3d_set_shader_buffers;
1434         pctx->set_shader_images = v3d_set_shader_images;
1435 
1436         pctx->create_stream_output_target = v3d_create_stream_output_target;
1437         pctx->stream_output_target_destroy = v3d_stream_output_target_destroy;
1438         pctx->set_stream_output_targets = v3d_set_stream_output_targets;
1439 }
1440