1/*
2 * Copyright (c) 2012-2015 Etnaviv Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 *    Wladimir J. van der Laan <laanwj@gmail.com>
25 *    Christian Gmeiner <christian.gmeiner@gmail.com>
26 */
27
28#include "etnaviv_state.h"
29
30#include "hw/common.xml.h"
31
32#include "etnaviv_blend.h"
33#include "etnaviv_clear_blit.h"
34#include "etnaviv_context.h"
35#include "etnaviv_format.h"
36#include "etnaviv_rasterizer.h"
37#include "etnaviv_screen.h"
38#include "etnaviv_shader.h"
39#include "etnaviv_surface.h"
40#include "etnaviv_translate.h"
41#include "etnaviv_util.h"
42#include "etnaviv_zsa.h"
43#include "util/u_framebuffer.h"
44#include "util/u_helpers.h"
45#include "util/u_inlines.h"
46#include "util/u_math.h"
47#include "util/u_memory.h"
48#include "util/u_upload_mgr.h"
49
50static void
51etna_set_stencil_ref(struct pipe_context *pctx, const struct pipe_stencil_ref sr)
52{
53   struct etna_context *ctx = etna_context(pctx);
54   struct compiled_stencil_ref *cs = &ctx->stencil_ref;
55
56   ctx->stencil_ref_s = sr;
57
58   for (unsigned i = 0; i < 2; i++) {
59      cs->PE_STENCIL_CONFIG[i] =
60         VIVS_PE_STENCIL_CONFIG_REF_FRONT(sr.ref_value[i]);
61      cs->PE_STENCIL_CONFIG_EXT[i] =
62         VIVS_PE_STENCIL_CONFIG_EXT_REF_BACK(sr.ref_value[!i]);
63   }
64   ctx->dirty |= ETNA_DIRTY_STENCIL_REF;
65}
66
67static void
68etna_set_clip_state(struct pipe_context *pctx, const struct pipe_clip_state *pcs)
69{
70   /* NOOP */
71}
72
73static void
74etna_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
75{
76   struct etna_context *ctx = etna_context(pctx);
77
78   ctx->sample_mask = sample_mask;
79   ctx->dirty |= ETNA_DIRTY_SAMPLE_MASK;
80}
81
82static void
83etna_set_constant_buffer(struct pipe_context *pctx,
84      enum pipe_shader_type shader, uint index, bool take_ownership,
85      const struct pipe_constant_buffer *cb)
86{
87   struct etna_context *ctx = etna_context(pctx);
88   struct etna_constbuf_state *so = &ctx->constant_buffer[shader];
89
90   assert(index < ETNA_MAX_CONST_BUF);
91
92   util_copy_constant_buffer(&so->cb[index], cb, take_ownership);
93
94   /* Note that the gallium frontends can unbind constant buffers by
95    * passing NULL here. */
96   if (unlikely(!cb || (!cb->buffer && !cb->user_buffer))) {
97      so->enabled_mask &= ~(1 << index);
98      return;
99   }
100
101   assert(index != 0 || cb->user_buffer != NULL);
102
103   if (!cb->buffer) {
104      struct pipe_constant_buffer *cb = &so->cb[index];
105      u_upload_data(pctx->const_uploader, 0, cb->buffer_size, 16, cb->user_buffer, &cb->buffer_offset, &cb->buffer);
106   }
107
108   so->enabled_mask |= 1 << index;
109   ctx->dirty |= ETNA_DIRTY_CONSTBUF;
110}
111
112static void
113etna_update_render_resource(struct pipe_context *pctx, struct etna_resource *base)
114{
115   struct etna_resource *to = base, *from = base;
116
117   if (base->texture && etna_resource_newer(etna_resource(base->texture), base))
118      from = etna_resource(base->texture);
119
120   if (base->render)
121      to = etna_resource(base->render);
122
123   if ((to != from) && etna_resource_older(to, from)) {
124      etna_copy_resource(pctx, &to->base, &from->base, 0, base->base.last_level);
125      to->seqno = from->seqno;
126   }
127}
128
129static void
130etna_set_framebuffer_state(struct pipe_context *pctx,
131      const struct pipe_framebuffer_state *fb)
132{
133   struct etna_context *ctx = etna_context(pctx);
134   struct etna_screen *screen = ctx->screen;
135   struct compiled_framebuffer_state *cs = &ctx->framebuffer;
136   int nr_samples_color = -1;
137   int nr_samples_depth = -1;
138   bool target_16bpp = false;
139   bool target_linear = false;
140
141   /* Set up TS as well. Warning: this state is used by both the RS and PE */
142   uint32_t ts_mem_config = 0;
143   uint32_t pe_mem_config = 0;
144   uint32_t pe_logic_op = 0;
145
146   if (fb->nr_cbufs > 0) { /* at least one color buffer? */
147      struct etna_surface *cbuf = etna_surface(fb->cbufs[0]);
148      struct etna_resource *res = etna_resource(cbuf->base.texture);
149      bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
150      uint32_t fmt = translate_pe_format(cbuf->base.format);
151
152      assert((res->layout & ETNA_LAYOUT_BIT_TILE) ||
153             VIV_FEATURE(screen, chipMinorFeatures2, LINEAR_PE));
154      etna_update_render_resource(pctx, etna_resource(cbuf->prsc));
155
156      if (res->layout == ETNA_LAYOUT_LINEAR)
157         target_linear = true;
158
159      if (fmt >= PE_FORMAT_R16F)
160          cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_FORMAT_EXT(fmt) |
161                                VIVS_PE_COLOR_FORMAT_FORMAT_MASK;
162      else
163          cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_FORMAT(fmt);
164
165      if (util_format_get_blocksize(cbuf->base.format) <= 2)
166         target_16bpp = true;
167
168      cs->PE_COLOR_FORMAT |=
169         VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK |
170         VIVS_PE_COLOR_FORMAT_OVERWRITE |
171         COND(color_supertiled, VIVS_PE_COLOR_FORMAT_SUPER_TILED);
172      if (VIV_FEATURE(screen, chipMinorFeatures6, CACHE128B256BPERLINE))
173         cs->PE_COLOR_FORMAT |= COND(color_supertiled, VIVS_PE_COLOR_FORMAT_SUPER_TILED_NEW);
174      /* VIVS_PE_COLOR_FORMAT_COMPONENTS() and
175       * VIVS_PE_COLOR_FORMAT_OVERWRITE comes from blend_state
176       * but only if we set the bits above. */
177      /* merged with depth_stencil_alpha */
178      if ((cbuf->surf.offset & 63) ||
179          (((cbuf->surf.stride * 4) & 63) && cbuf->surf.height > 4)) {
180         /* XXX Must make temporary surface here.
181          * Need the same mechanism on gc2000 when we want to do mipmap
182          * generation by
183          * rendering to levels > 1 due to multitiled / tiled conversion. */
184         BUG("Alignment error, trying to render to offset %08x with tile "
185             "stride %i",
186             cbuf->surf.offset, cbuf->surf.stride * 4);
187      }
188
189      if (screen->specs.halti >= 0 && screen->model != 0x880) {
190         /* Rendertargets on GPUs with more than a single pixel pipe must always
191          * be multi-tiled, or single-buffer mode must be supported */
192         assert(screen->specs.pixel_pipes == 1 ||
193                (res->layout & ETNA_LAYOUT_BIT_MULTI) || screen->specs.single_buffer);
194         for (int i = 0; i < screen->specs.pixel_pipes; i++) {
195            cs->PE_PIPE_COLOR_ADDR[i] = cbuf->reloc[i];
196            cs->PE_PIPE_COLOR_ADDR[i].flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
197         }
198      } else {
199         cs->PE_COLOR_ADDR = cbuf->reloc[0];
200         cs->PE_COLOR_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
201      }
202
203      cs->PE_COLOR_STRIDE = cbuf->surf.stride;
204
205      if (cbuf->surf.ts_size) {
206         cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value;
207         cs->TS_COLOR_CLEAR_VALUE_EXT = cbuf->level->clear_value >> 32;
208
209         cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc;
210         cs->TS_COLOR_STATUS_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
211
212         cs->TS_COLOR_SURFACE_BASE = cbuf->reloc[0];
213         cs->TS_COLOR_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
214
215         pe_mem_config |= VIVS_PE_MEM_CONFIG_COLOR_TS_MODE(cbuf->level->ts_mode);
216
217         if (cbuf->level->ts_compress_fmt >= 0) {
218            /* overwrite bit breaks v1/v2 compression */
219            if (!screen->specs.v4_compression)
220               cs->PE_COLOR_FORMAT &= ~VIVS_PE_COLOR_FORMAT_OVERWRITE;
221
222            ts_mem_config |=
223               VIVS_TS_MEM_CONFIG_COLOR_COMPRESSION |
224               VIVS_TS_MEM_CONFIG_COLOR_COMPRESSION_FORMAT(cbuf->level->ts_compress_fmt);
225         }
226      }
227
228      nr_samples_color = cbuf->base.texture->nr_samples;
229
230      if (util_format_is_srgb(cbuf->base.format))
231         pe_logic_op |= VIVS_PE_LOGIC_OP_SRGB;
232
233      cs->PS_CONTROL = COND(util_format_is_unorm(cbuf->base.format), VIVS_PS_CONTROL_SATURATE_RT0);
234      cs->PS_CONTROL_EXT =
235         VIVS_PS_CONTROL_EXT_OUTPUT_MODE0(translate_output_mode(cbuf->base.format, screen->specs.halti >= 5));
236   } else {
237      /* Clearing VIVS_PE_COLOR_FORMAT_COMPONENTS__MASK and
238       * VIVS_PE_COLOR_FORMAT_OVERWRITE prevents us from overwriting the
239       * color target */
240      cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_OVERWRITE;
241      cs->PE_COLOR_STRIDE = 0;
242      cs->TS_COLOR_STATUS_BASE.bo = NULL;
243      cs->TS_COLOR_SURFACE_BASE.bo = NULL;
244
245      cs->PE_COLOR_ADDR = screen->dummy_rt_reloc;
246      for (int i = 0; i < screen->specs.pixel_pipes; i++)
247         cs->PE_PIPE_COLOR_ADDR[i] = screen->dummy_rt_reloc;
248   }
249
250   if (fb->zsbuf != NULL) {
251      struct etna_surface *zsbuf = etna_surface(fb->zsbuf);
252      struct etna_resource *res = etna_resource(zsbuf->base.texture);
253
254      etna_update_render_resource(pctx, etna_resource(zsbuf->prsc));
255
256      assert(res->layout &ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */
257
258      uint32_t depth_format = translate_depth_format(zsbuf->base.format);
259      unsigned depth_bits =
260         depth_format == VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16 ? 16 : 24;
261      bool depth_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
262
263      if (depth_bits == 16)
264         target_16bpp = true;
265
266      cs->PE_DEPTH_CONFIG =
267         depth_format |
268         COND(depth_supertiled, VIVS_PE_DEPTH_CONFIG_SUPER_TILED) |
269         VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_Z |
270         VIVS_PE_DEPTH_CONFIG_UNK18; /* something to do with clipping? */
271      /* VIVS_PE_DEPTH_CONFIG_ONLY_DEPTH */
272      /* merged with depth_stencil_alpha */
273
274      if (screen->specs.halti >= 0 && screen->model != 0x880) {
275         for (int i = 0; i < screen->specs.pixel_pipes; i++) {
276            cs->PE_PIPE_DEPTH_ADDR[i] = zsbuf->reloc[i];
277            cs->PE_PIPE_DEPTH_ADDR[i].flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
278         }
279      } else {
280         cs->PE_DEPTH_ADDR = zsbuf->reloc[0];
281         cs->PE_DEPTH_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
282      }
283
284      cs->PE_DEPTH_STRIDE = zsbuf->surf.stride;
285      cs->PE_HDEPTH_CONTROL = VIVS_PE_HDEPTH_CONTROL_FORMAT_DISABLED;
286      cs->PE_DEPTH_NORMALIZE = fui(exp2f(depth_bits) - 1.0f);
287
288      if (zsbuf->surf.ts_size) {
289         cs->TS_DEPTH_CLEAR_VALUE = zsbuf->level->clear_value;
290
291         cs->TS_DEPTH_STATUS_BASE = zsbuf->ts_reloc;
292         cs->TS_DEPTH_STATUS_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
293
294         cs->TS_DEPTH_SURFACE_BASE = zsbuf->reloc[0];
295         cs->TS_DEPTH_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
296
297         pe_mem_config |= VIVS_PE_MEM_CONFIG_DEPTH_TS_MODE(zsbuf->level->ts_mode);
298
299         if (zsbuf->level->ts_compress_fmt >= 0) {
300            ts_mem_config |=
301               VIVS_TS_MEM_CONFIG_DEPTH_COMPRESSION |
302               COND(zsbuf->level->ts_compress_fmt == COMPRESSION_FORMAT_D24S8,
303                    VIVS_TS_MEM_CONFIG_STENCIL_ENABLE);
304         }
305      }
306
307      ts_mem_config |= COND(depth_bits == 16, VIVS_TS_MEM_CONFIG_DEPTH_16BPP);
308
309      nr_samples_depth = zsbuf->base.texture->nr_samples;
310   } else {
311      cs->PE_DEPTH_CONFIG = VIVS_PE_DEPTH_CONFIG_DEPTH_MODE_NONE;
312      cs->PE_DEPTH_ADDR.bo = NULL;
313      cs->PE_DEPTH_STRIDE = 0;
314      cs->TS_DEPTH_STATUS_BASE.bo = NULL;
315      cs->TS_DEPTH_SURFACE_BASE.bo = NULL;
316
317      for (int i = 0; i < ETNA_MAX_PIXELPIPES; i++)
318         cs->PE_PIPE_DEPTH_ADDR[i].bo = NULL;
319   }
320
321   /* MSAA setup */
322   if (nr_samples_depth != -1 && nr_samples_color != -1 &&
323       nr_samples_depth != nr_samples_color) {
324      BUG("Number of samples in color and depth texture must match (%i and %i respectively)",
325          nr_samples_color, nr_samples_depth);
326   }
327
328   switch (MAX2(nr_samples_depth, nr_samples_color)) {
329   case 0:
330   case 1: /* Are 0 and 1 samples allowed? */
331      cs->GL_MULTI_SAMPLE_CONFIG =
332         VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_NONE;
333      cs->msaa_mode = false;
334      break;
335   case 2:
336      cs->GL_MULTI_SAMPLE_CONFIG = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_2X;
337      cs->msaa_mode = true; /* Add input to PS */
338      cs->RA_MULTISAMPLE_UNK00E04 = 0x0;
339      cs->RA_MULTISAMPLE_UNK00E10[0] = 0x0000aa22;
340      cs->RA_CENTROID_TABLE[0] = 0x66aa2288;
341      cs->RA_CENTROID_TABLE[1] = 0x88558800;
342      cs->RA_CENTROID_TABLE[2] = 0x88881100;
343      cs->RA_CENTROID_TABLE[3] = 0x33888800;
344      break;
345   case 4:
346      cs->GL_MULTI_SAMPLE_CONFIG = VIVS_GL_MULTI_SAMPLE_CONFIG_MSAA_SAMPLES_4X;
347      cs->msaa_mode = true; /* Add input to PS */
348      cs->RA_MULTISAMPLE_UNK00E04 = 0x0;
349      cs->RA_MULTISAMPLE_UNK00E10[0] = 0xeaa26e26;
350      cs->RA_MULTISAMPLE_UNK00E10[1] = 0xe6ae622a;
351      cs->RA_MULTISAMPLE_UNK00E10[2] = 0xaaa22a22;
352      cs->RA_CENTROID_TABLE[0] = 0x4a6e2688;
353      cs->RA_CENTROID_TABLE[1] = 0x888888a2;
354      cs->RA_CENTROID_TABLE[2] = 0x888888ea;
355      cs->RA_CENTROID_TABLE[3] = 0x888888c6;
356      cs->RA_CENTROID_TABLE[4] = 0x46622a88;
357      cs->RA_CENTROID_TABLE[5] = 0x888888ae;
358      cs->RA_CENTROID_TABLE[6] = 0x888888e6;
359      cs->RA_CENTROID_TABLE[7] = 0x888888ca;
360      cs->RA_CENTROID_TABLE[8] = 0x262a2288;
361      cs->RA_CENTROID_TABLE[9] = 0x886688a2;
362      cs->RA_CENTROID_TABLE[10] = 0x888866aa;
363      cs->RA_CENTROID_TABLE[11] = 0x668888a6;
364      break;
365   }
366
367   cs->TS_MEM_CONFIG = ts_mem_config;
368   cs->PE_MEM_CONFIG = pe_mem_config;
369
370   /* Single buffer setup. There is only one switch for this, not a separate
371    * one per color buffer / depth buffer. To keep the logic simple always use
372    * single buffer when this feature is available.
373    */
374   if (unlikely(target_linear))
375      pe_logic_op |= VIVS_PE_LOGIC_OP_SINGLE_BUFFER(1);
376   else if (screen->specs.single_buffer)
377      pe_logic_op |= VIVS_PE_LOGIC_OP_SINGLE_BUFFER(target_16bpp ? 3 : 2);
378   cs->PE_LOGIC_OP = pe_logic_op;
379
380   /* keep copy of original structure */
381   util_copy_framebuffer_state(&ctx->framebuffer_s, fb);
382   ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_DERIVE_TS;
383}
384
385static void
386etna_set_polygon_stipple(struct pipe_context *pctx,
387      const struct pipe_poly_stipple *stipple)
388{
389   /* NOP */
390}
391
392static void
393etna_set_scissor_states(struct pipe_context *pctx, unsigned start_slot,
394      unsigned num_scissors, const struct pipe_scissor_state *ss)
395{
396   struct etna_context *ctx = etna_context(pctx);
397   assert(ss->minx <= ss->maxx);
398   assert(ss->miny <= ss->maxy);
399
400   ctx->scissor = *ss;
401   ctx->dirty |= ETNA_DIRTY_SCISSOR;
402}
403
404static void
405etna_set_viewport_states(struct pipe_context *pctx, unsigned start_slot,
406      unsigned num_scissors, const struct pipe_viewport_state *vs)
407{
408   struct etna_context *ctx = etna_context(pctx);
409   struct compiled_viewport_state *cs = &ctx->viewport;
410
411   ctx->viewport_s = *vs;
412   /**
413    * For Vivante GPU, viewport z transformation is 0..1 to 0..1 instead of
414    * -1..1 to 0..1.
415    * scaling and translation to 0..1 already happened, so remove that
416    *
417    * z' = (z * 2 - 1) * scale + translate
418    *    = z * (2 * scale) + (translate - scale)
419    *
420    * scale' = 2 * scale
421    * translate' = translate - scale
422    */
423
424   /* must be fixp as v4 state deltas assume it is */
425   cs->PA_VIEWPORT_SCALE_X = etna_f32_to_fixp16(vs->scale[0]);
426   cs->PA_VIEWPORT_SCALE_Y = etna_f32_to_fixp16(vs->scale[1]);
427   cs->PA_VIEWPORT_SCALE_Z = fui(vs->scale[2] * 2.0f);
428   cs->PA_VIEWPORT_OFFSET_X = etna_f32_to_fixp16(vs->translate[0]);
429   cs->PA_VIEWPORT_OFFSET_Y = etna_f32_to_fixp16(vs->translate[1]);
430   cs->PA_VIEWPORT_OFFSET_Z = fui(vs->translate[2] - vs->scale[2]);
431
432   /* Compute scissor rectangle (fixp) from viewport.
433    * Make sure left is always < right and top always < bottom.
434    */
435   cs->SE_SCISSOR_LEFT = MAX2(vs->translate[0] - fabsf(vs->scale[0]), 0.0f);
436   cs->SE_SCISSOR_TOP = MAX2(vs->translate[1] - fabsf(vs->scale[1]), 0.0f);
437   cs->SE_SCISSOR_RIGHT = ceilf(MAX2(vs->translate[0] + fabsf(vs->scale[0]), 0.0f));
438   cs->SE_SCISSOR_BOTTOM = ceilf(MAX2(vs->translate[1] + fabsf(vs->scale[1]), 0.0f));
439
440   cs->PE_DEPTH_NEAR = fui(0.0); /* not affected if depth mode is Z (as in GL) */
441   cs->PE_DEPTH_FAR = fui(1.0);
442   ctx->dirty |= ETNA_DIRTY_VIEWPORT;
443}
444
445static void
446etna_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot,
447      unsigned num_buffers, unsigned unbind_num_trailing_slots, bool take_ownership,
448      const struct pipe_vertex_buffer *vb)
449{
450   struct etna_context *ctx = etna_context(pctx);
451   struct etna_vertexbuf_state *so = &ctx->vertex_buffer;
452
453   util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot,
454                                num_buffers, unbind_num_trailing_slots,
455                                take_ownership);
456   so->count = util_last_bit(so->enabled_mask);
457
458   for (unsigned idx = start_slot; idx < start_slot + num_buffers; ++idx) {
459      struct compiled_set_vertex_buffer *cs = &so->cvb[idx];
460      struct pipe_vertex_buffer *vbi = &so->vb[idx];
461
462      assert(!vbi->is_user_buffer); /* XXX support user_buffer using
463                                       etna_usermem_map */
464
465      if (vbi->buffer.resource) { /* GPU buffer */
466         cs->FE_VERTEX_STREAM_BASE_ADDR.bo = etna_resource(vbi->buffer.resource)->bo;
467         cs->FE_VERTEX_STREAM_BASE_ADDR.offset = vbi->buffer_offset;
468         cs->FE_VERTEX_STREAM_BASE_ADDR.flags = ETNA_RELOC_READ;
469         cs->FE_VERTEX_STREAM_CONTROL =
470            FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE(vbi->stride);
471      } else {
472         cs->FE_VERTEX_STREAM_BASE_ADDR.bo = NULL;
473         cs->FE_VERTEX_STREAM_CONTROL = 0;
474      }
475   }
476
477   ctx->dirty |= ETNA_DIRTY_VERTEX_BUFFERS;
478}
479
480static void
481etna_blend_state_bind(struct pipe_context *pctx, void *bs)
482{
483   struct etna_context *ctx = etna_context(pctx);
484
485   ctx->blend = bs;
486   ctx->dirty |= ETNA_DIRTY_BLEND;
487}
488
489static void
490etna_blend_state_delete(struct pipe_context *pctx, void *bs)
491{
492   FREE(bs);
493}
494
495static void
496etna_rasterizer_state_bind(struct pipe_context *pctx, void *rs)
497{
498   struct etna_context *ctx = etna_context(pctx);
499
500   ctx->rasterizer = rs;
501   ctx->dirty |= ETNA_DIRTY_RASTERIZER;
502}
503
504static void
505etna_rasterizer_state_delete(struct pipe_context *pctx, void *rs)
506{
507   FREE(rs);
508}
509
510static void
511etna_zsa_state_bind(struct pipe_context *pctx, void *zs)
512{
513   struct etna_context *ctx = etna_context(pctx);
514
515   ctx->zsa = zs;
516   ctx->dirty |= ETNA_DIRTY_ZSA;
517}
518
519static void
520etna_zsa_state_delete(struct pipe_context *pctx, void *zs)
521{
522   FREE(zs);
523}
524
525/** Create vertex element states, which define a layout for fetching
526 * vertices for rendering.
527 */
528static void *
529etna_vertex_elements_state_create(struct pipe_context *pctx,
530      unsigned num_elements, const struct pipe_vertex_element *elements)
531{
532   struct etna_context *ctx = etna_context(pctx);
533   struct etna_screen *screen = ctx->screen;
534   struct compiled_vertex_elements_state *cs = CALLOC_STRUCT(compiled_vertex_elements_state);
535
536   if (!cs)
537      return NULL;
538
539   if (num_elements > screen->specs.vertex_max_elements) {
540      BUG("number of elements (%u) exceeds chip maximum (%u)", num_elements,
541          screen->specs.vertex_max_elements);
542      FREE(cs);
543      return NULL;
544   }
545
546   /* XXX could minimize number of consecutive stretches here by sorting, and
547    * permuting the inputs in shader or does Mesa do this already? */
548
549   cs->num_elements = num_elements;
550
551   unsigned start_offset = 0; /* start of current consecutive stretch */
552   bool nonconsecutive = true; /* previous value of nonconsecutive */
553   uint32_t buffer_mask = 0; /* mask of buffer_idx already seen */
554
555   for (unsigned idx = 0; idx < num_elements; ++idx) {
556      unsigned buffer_idx = elements[idx].vertex_buffer_index;
557      unsigned element_size = util_format_get_blocksize(elements[idx].src_format);
558      unsigned end_offset = elements[idx].src_offset + element_size;
559      uint32_t format_type, normalize;
560
561      if (nonconsecutive)
562         start_offset = elements[idx].src_offset;
563
564      /* guaranteed by PIPE_CAP_MAX_VERTEX_BUFFERS */
565      assert(buffer_idx < screen->specs.stream_count);
566
567      /* maximum vertex size is 256 bytes */
568      assert(element_size != 0 && (end_offset - start_offset) < 256);
569
570      /* check whether next element is consecutive to this one */
571      nonconsecutive = (idx == (num_elements - 1)) ||
572                       elements[idx + 1].vertex_buffer_index != buffer_idx ||
573                       end_offset != elements[idx + 1].src_offset;
574
575      format_type = translate_vertex_format_type(elements[idx].src_format);
576      normalize = translate_vertex_format_normalize(elements[idx].src_format);
577
578      assert(format_type != ETNA_NO_MATCH);
579      assert(normalize != ETNA_NO_MATCH);
580
581      if (screen->specs.halti < 5) {
582         cs->FE_VERTEX_ELEMENT_CONFIG[idx] =
583            COND(nonconsecutive, VIVS_FE_VERTEX_ELEMENT_CONFIG_NONCONSECUTIVE) |
584            format_type |
585            VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(util_format_get_nr_components(elements[idx].src_format)) |
586            normalize | VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(ENDIAN_MODE_NO_SWAP) |
587            VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(buffer_idx) |
588            VIVS_FE_VERTEX_ELEMENT_CONFIG_START(elements[idx].src_offset) |
589            VIVS_FE_VERTEX_ELEMENT_CONFIG_END(end_offset - start_offset);
590      } else { /* HALTI5 spread vertex attrib config over two registers */
591         cs->NFE_GENERIC_ATTRIB_CONFIG0[idx] =
592            format_type |
593            VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM(util_format_get_nr_components(elements[idx].src_format)) |
594            normalize | VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN(ENDIAN_MODE_NO_SWAP) |
595            VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(buffer_idx) |
596            VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START(elements[idx].src_offset);
597         cs->NFE_GENERIC_ATTRIB_CONFIG1[idx] =
598            COND(nonconsecutive, VIVS_NFE_GENERIC_ATTRIB_CONFIG1_NONCONSECUTIVE) |
599            VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END(end_offset - start_offset);
600      }
601
602      if (util_format_is_pure_integer(elements[idx].src_format))
603         cs->NFE_GENERIC_ATTRIB_SCALE[idx] = 1;
604      else
605         cs->NFE_GENERIC_ATTRIB_SCALE[idx] = fui(1.0f);
606
607      /* instance_divisor is part of elements state but should be the same for all buffers */
608      if (buffer_mask & 1 << buffer_idx)
609         assert(cs->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[buffer_idx] == elements[idx].instance_divisor);
610      else
611         cs->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[buffer_idx] = elements[idx].instance_divisor;
612
613      buffer_mask |= 1 << buffer_idx;
614      cs->num_buffers = MAX2(cs->num_buffers, buffer_idx + 1);
615   }
616
617   return cs;
618}
619
620static void
621etna_vertex_elements_state_delete(struct pipe_context *pctx, void *ve)
622{
623   FREE(ve);
624}
625
626static void
627etna_vertex_elements_state_bind(struct pipe_context *pctx, void *ve)
628{
629   struct etna_context *ctx = etna_context(pctx);
630
631   ctx->vertex_elements = ve;
632   ctx->dirty |= ETNA_DIRTY_VERTEX_ELEMENTS;
633}
634
635static void
636etna_set_stream_output_targets(struct pipe_context *pctx,
637      unsigned num_targets, struct pipe_stream_output_target **targets,
638      const unsigned *offsets)
639{
640   /* stub */
641}
642
643static bool
644etna_update_ts_config(struct etna_context *ctx)
645{
646   uint32_t new_ts_config = ctx->framebuffer.TS_MEM_CONFIG;
647
648   if (ctx->framebuffer_s.nr_cbufs > 0) {
649      struct etna_surface *c_surf = etna_surface(ctx->framebuffer_s.cbufs[0]);
650
651      if(c_surf->level->ts_size && c_surf->level->ts_valid) {
652         new_ts_config |= VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
653      } else {
654         new_ts_config &= ~VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR;
655      }
656   }
657
658   if (ctx->framebuffer_s.zsbuf) {
659      struct etna_surface *zs_surf = etna_surface(ctx->framebuffer_s.zsbuf);
660
661      if(zs_surf->level->ts_size && zs_surf->level->ts_valid) {
662         new_ts_config |= VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
663      } else {
664         new_ts_config &= ~VIVS_TS_MEM_CONFIG_DEPTH_FAST_CLEAR;
665      }
666   }
667
668   if (new_ts_config != ctx->framebuffer.TS_MEM_CONFIG ||
669       (ctx->dirty & ETNA_DIRTY_FRAMEBUFFER)) {
670      ctx->framebuffer.TS_MEM_CONFIG = new_ts_config;
671      ctx->dirty |= ETNA_DIRTY_TS;
672   }
673
674   ctx->dirty &= ~ETNA_DIRTY_DERIVE_TS;
675
676   return true;
677}
678
679static bool
680etna_update_clipping(struct etna_context *ctx)
681{
682   const struct etna_rasterizer_state *rasterizer = etna_rasterizer_state(ctx->rasterizer);
683   const struct pipe_framebuffer_state *fb = &ctx->framebuffer_s;
684
685   /* clip framebuffer against viewport */
686   uint32_t scissor_left = ctx->viewport.SE_SCISSOR_LEFT;
687   uint32_t scissor_top = ctx->viewport.SE_SCISSOR_TOP;
688   uint32_t scissor_right = MIN2(fb->width, ctx->viewport.SE_SCISSOR_RIGHT);
689   uint32_t scissor_bottom = MIN2(fb->height, ctx->viewport.SE_SCISSOR_BOTTOM);
690
691   /* clip against scissor */
692   if (rasterizer->scissor) {
693      scissor_left = MAX2(ctx->scissor.minx, scissor_left);
694      scissor_top = MAX2(ctx->scissor.miny, scissor_top);
695      scissor_right = MIN2(ctx->scissor.maxx, scissor_right);
696      scissor_bottom = MIN2(ctx->scissor.maxy, scissor_bottom);
697   }
698
699   ctx->clipping.minx = scissor_left;
700   ctx->clipping.miny = scissor_top;
701   ctx->clipping.maxx = scissor_right;
702   ctx->clipping.maxy = scissor_bottom;
703
704   ctx->dirty |= ETNA_DIRTY_SCISSOR_CLIP;
705
706   return true;
707}
708
709static bool
710etna_update_zsa(struct etna_context *ctx)
711{
712   struct compiled_shader_state *shader_state = &ctx->shader_state;
713   struct pipe_depth_stencil_alpha_state *zsa_state = ctx->zsa;
714   struct etna_zsa_state *zsa = etna_zsa_state(zsa_state);
715   struct etna_screen *screen = ctx->screen;
716   uint32_t new_pe_depth, new_ra_depth;
717   bool early_z_allowed = !VIV_FEATURE(screen, chipFeatures, NO_EARLY_Z);
718   bool late_z_write = false, early_z_write = false,
719        late_z_test = false, early_z_test = false;
720
721   /* Linear PE breaks the combination of early test with late write, as it
722    * seems RA and PE disagree about the buffer layout in this mode. Fall back
723    * to late Z always even though early Z write might be possible, as we don't
724    * know if any other draws to the same surface require late Z write.
725    */
726   if (ctx->framebuffer_s.nr_cbufs > 0) {
727      struct etna_surface *cbuf = etna_surface(ctx->framebuffer_s.cbufs[0]);
728      struct etna_resource *res = etna_resource(cbuf->base.texture);
729
730      if (res->layout == ETNA_LAYOUT_LINEAR)
731         early_z_allowed = false;
732   }
733
734   if (zsa->z_write_enabled) {
735      if (VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH) &&
736          early_z_allowed &&
737          !zsa->stencil_enabled &&
738          !zsa_state->alpha_enabled &&
739          !shader_state->writes_z &&
740          !shader_state->uses_discard)
741         early_z_write = true;
742      else
743         late_z_write = true;
744   }
745
746   if (zsa->z_test_enabled) {
747      if (early_z_allowed &&
748          !zsa->stencil_modified &&
749          !shader_state->writes_z)
750         early_z_test = true;
751      else
752         late_z_test = true;
753   }
754
755   new_pe_depth = VIVS_PE_DEPTH_CONFIG_DEPTH_FUNC(zsa->z_test_enabled ?
756                     /* compare funcs have 1 to 1 mapping */
757                     zsa_state->depth_func : PIPE_FUNC_ALWAYS) |
758                  COND(zsa->z_write_enabled, VIVS_PE_DEPTH_CONFIG_WRITE_ENABLE) |
759                  COND(early_z_test, VIVS_PE_DEPTH_CONFIG_EARLY_Z) |
760                  COND(!late_z_write && !late_z_test && !zsa->stencil_enabled,
761                       VIVS_PE_DEPTH_CONFIG_DISABLE_ZS);
762
763   /* blob sets this to 0x40000031 on GC7000, seems to make no difference,
764    * but keep it in mind if depth behaves strangely. */
765   new_ra_depth = 0x0000030 |
766                  COND(early_z_test, VIVS_RA_EARLY_DEPTH_TEST_ENABLE);
767
768   if (VIV_FEATURE(screen, chipMinorFeatures5, RA_WRITE_DEPTH)) {
769      if (!early_z_write)
770         new_ra_depth |= VIVS_RA_EARLY_DEPTH_WRITE_DISABLE;
771      /* The new early hierarchical test seems to only work properly if depth
772       * is also written from the early stage.
773       */
774      if (late_z_test || (early_z_test && late_z_write))
775         new_ra_depth |= VIVS_RA_EARLY_DEPTH_HDEPTH_DISABLE;
776   }
777
778   if (new_pe_depth != zsa->PE_DEPTH_CONFIG ||
779       new_ra_depth != zsa->RA_DEPTH_CONFIG)
780      ctx->dirty |= ETNA_DIRTY_ZSA;
781
782   zsa->PE_DEPTH_CONFIG = new_pe_depth;
783   zsa->RA_DEPTH_CONFIG = new_ra_depth;
784
785   return true;
786}
787
788static bool
789etna_record_flush_resources(struct etna_context *ctx)
790{
791   struct pipe_framebuffer_state *fb = &ctx->framebuffer_s;
792
793   if (fb->nr_cbufs > 0) {
794      struct etna_surface *surf = etna_surface(fb->cbufs[0]);
795
796      if (!etna_resource(surf->prsc)->explicit_flush) {
797         bool found;
798
799         _mesa_set_search_or_add(ctx->flush_resources, surf->prsc, &found);
800
801         if (!found)
802            pipe_reference(NULL, &surf->prsc->reference);
803      }
804   }
805
806   return true;
807}
808
809struct etna_state_updater {
810   bool (*update)(struct etna_context *ctx);
811   uint32_t dirty;
812};
813
814static const struct etna_state_updater etna_state_updates[] = {
815   {
816      etna_shader_update_vertex, ETNA_DIRTY_SHADER | ETNA_DIRTY_VERTEX_ELEMENTS,
817   },
818   {
819      etna_shader_link, ETNA_DIRTY_SHADER,
820   },
821   {
822      etna_update_blend, ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER
823   },
824   {
825      etna_update_blend_color, ETNA_DIRTY_BLEND_COLOR | ETNA_DIRTY_FRAMEBUFFER,
826   },
827   {
828      etna_update_ts_config, ETNA_DIRTY_DERIVE_TS,
829   },
830   {
831      etna_update_clipping, ETNA_DIRTY_SCISSOR | ETNA_DIRTY_FRAMEBUFFER |
832                            ETNA_DIRTY_RASTERIZER | ETNA_DIRTY_VIEWPORT,
833   },
834   {
835      etna_update_zsa, ETNA_DIRTY_ZSA | ETNA_DIRTY_SHADER |
836                       ETNA_DIRTY_FRAMEBUFFER,
837   },
838   {
839      etna_record_flush_resources, ETNA_DIRTY_FRAMEBUFFER,
840   }
841};
842
843bool
844etna_state_update(struct etna_context *ctx)
845{
846   for (unsigned int i = 0; i < ARRAY_SIZE(etna_state_updates); i++)
847      if (ctx->dirty & etna_state_updates[i].dirty)
848         if (!etna_state_updates[i].update(ctx))
849            return false;
850
851   return true;
852}
853
854void
855etna_state_init(struct pipe_context *pctx)
856{
857   pctx->set_blend_color = etna_set_blend_color;
858   pctx->set_stencil_ref = etna_set_stencil_ref;
859   pctx->set_clip_state = etna_set_clip_state;
860   pctx->set_sample_mask = etna_set_sample_mask;
861   pctx->set_constant_buffer = etna_set_constant_buffer;
862   pctx->set_framebuffer_state = etna_set_framebuffer_state;
863   pctx->set_polygon_stipple = etna_set_polygon_stipple;
864   pctx->set_scissor_states = etna_set_scissor_states;
865   pctx->set_viewport_states = etna_set_viewport_states;
866
867   pctx->set_vertex_buffers = etna_set_vertex_buffers;
868
869   pctx->bind_blend_state = etna_blend_state_bind;
870   pctx->delete_blend_state = etna_blend_state_delete;
871
872   pctx->bind_rasterizer_state = etna_rasterizer_state_bind;
873   pctx->delete_rasterizer_state = etna_rasterizer_state_delete;
874
875   pctx->bind_depth_stencil_alpha_state = etna_zsa_state_bind;
876   pctx->delete_depth_stencil_alpha_state = etna_zsa_state_delete;
877
878   pctx->create_vertex_elements_state = etna_vertex_elements_state_create;
879   pctx->delete_vertex_elements_state = etna_vertex_elements_state_delete;
880   pctx->bind_vertex_elements_state = etna_vertex_elements_state_bind;
881
882   pctx->set_stream_output_targets = etna_set_stream_output_targets;
883}
884