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_context.h"
29
30#include "etnaviv_blend.h"
31#include "etnaviv_clear_blit.h"
32#include "etnaviv_compiler.h"
33#include "etnaviv_debug.h"
34#include "etnaviv_emit.h"
35#include "etnaviv_fence.h"
36#include "etnaviv_query.h"
37#include "etnaviv_query_acc.h"
38#include "etnaviv_rasterizer.h"
39#include "etnaviv_resource.h"
40#include "etnaviv_screen.h"
41#include "etnaviv_shader.h"
42#include "etnaviv_state.h"
43#include "etnaviv_surface.h"
44#include "etnaviv_texture.h"
45#include "etnaviv_transfer.h"
46#include "etnaviv_translate.h"
47#include "etnaviv_zsa.h"
48
49#include "pipe/p_context.h"
50#include "pipe/p_state.h"
51#include "util/hash_table.h"
52#include "util/u_blitter.h"
53#include "util/u_draw.h"
54#include "util/u_helpers.h"
55#include "util/u_memory.h"
56#include "util/u_prim.h"
57#include "util/u_upload_mgr.h"
58
59#include "hw/common.xml.h"
60
61static inline void
62etna_emit_nop_with_data(struct etna_cmd_stream *stream, uint32_t value)
63{
64   etna_cmd_stream_emit(stream, VIV_FE_NOP_HEADER_OP_NOP);
65   etna_cmd_stream_emit(stream, value);
66}
67
68static void
69etna_emit_string_marker(struct pipe_context *pctx, const char *string, int len)
70{
71   struct etna_context *ctx = etna_context(pctx);
72   struct etna_cmd_stream *stream = ctx->stream;
73   const uint32_t *buf = (const void *)string;
74
75   etna_cmd_stream_reserve(stream, len * 2);
76
77   while (len >= 4) {
78      etna_emit_nop_with_data(stream, *buf);
79      buf++;
80      len -= 4;
81   }
82
83   /* copy remainder bytes without reading past end of input string */
84   if (len > 0) {
85      uint32_t w = 0;
86      memcpy(&w, buf, len);
87      etna_emit_nop_with_data(stream, w);
88   }
89}
90
91static void
92etna_context_destroy(struct pipe_context *pctx)
93{
94   struct etna_context *ctx = etna_context(pctx);
95
96   mtx_lock(&ctx->lock);
97
98   if (ctx->used_resources_read) {
99
100      /*
101       * There should be no resources tracked in the context when it's being
102       * destroyed. Be sure there are none to avoid memory leaks on buggy
103       * programs.
104       */
105      set_foreach(ctx->used_resources_read, entry) {
106         struct etna_resource *rsc = (struct etna_resource *)entry->key;
107
108         mtx_lock(&rsc->lock);
109         _mesa_set_remove_key(rsc->pending_ctx, ctx);
110         mtx_unlock(&rsc->lock);
111      }
112      _mesa_set_destroy(ctx->used_resources_read, NULL);
113
114   }
115   if (ctx->used_resources_write) {
116
117      /*
118       * There should be no resources tracked in the context when it's being
119       * destroyed. Be sure there are none to avoid memory leaks on buggy
120       * programs.
121       */
122      set_foreach(ctx->used_resources_write, entry) {
123         struct etna_resource *rsc = (struct etna_resource *)entry->key;
124
125         mtx_lock(&rsc->lock);
126         _mesa_set_remove_key(rsc->pending_ctx, ctx);
127         mtx_unlock(&rsc->lock);
128      }
129      _mesa_set_destroy(ctx->used_resources_write, NULL);
130
131   }
132   if (ctx->flush_resources)
133      _mesa_set_destroy(ctx->flush_resources, NULL);
134
135   mtx_unlock(&ctx->lock);
136
137   if (ctx->dummy_desc_bo)
138      etna_bo_del(ctx->dummy_desc_bo);
139
140   if (ctx->dummy_rt)
141      etna_bo_del(ctx->dummy_rt);
142
143   util_copy_framebuffer_state(&ctx->framebuffer_s, NULL);
144
145   if (ctx->blitter)
146      util_blitter_destroy(ctx->blitter);
147
148   if (pctx->stream_uploader)
149      u_upload_destroy(pctx->stream_uploader);
150
151   if (ctx->stream)
152      etna_cmd_stream_del(ctx->stream);
153
154   slab_destroy_child(&ctx->transfer_pool);
155
156   if (ctx->in_fence_fd != -1)
157      close(ctx->in_fence_fd);
158
159   mtx_destroy(&ctx->lock);
160
161   FREE(pctx);
162}
163
164/* Update render state where needed based on draw operation */
165static void
166etna_update_state_for_draw(struct etna_context *ctx, const struct pipe_draw_info *info)
167{
168   /* Handle primitive restart:
169    * - If not an indexed draw, we don't care about the state of the primitive restart bit.
170    * - Otherwise, set the bit in INDEX_STREAM_CONTROL in the index buffer state
171    *   accordingly
172    * - If the value of the INDEX_STREAM_CONTROL register changed due to this, or
173    *   primitive restart is enabled and the restart index changed, mark the index
174    *   buffer state as dirty
175    */
176
177   if (info->index_size) {
178      uint32_t new_control = ctx->index_buffer.FE_INDEX_STREAM_CONTROL;
179
180      if (info->primitive_restart)
181         new_control |= VIVS_FE_INDEX_STREAM_CONTROL_PRIMITIVE_RESTART;
182      else
183         new_control &= ~VIVS_FE_INDEX_STREAM_CONTROL_PRIMITIVE_RESTART;
184
185      if (ctx->index_buffer.FE_INDEX_STREAM_CONTROL != new_control ||
186          (info->primitive_restart && ctx->index_buffer.FE_PRIMITIVE_RESTART_INDEX != info->restart_index)) {
187         ctx->index_buffer.FE_INDEX_STREAM_CONTROL = new_control;
188         ctx->index_buffer.FE_PRIMITIVE_RESTART_INDEX = info->restart_index;
189         ctx->dirty |= ETNA_DIRTY_INDEX_BUFFER;
190      }
191   }
192}
193
194static bool
195etna_get_vs(struct etna_context *ctx, struct etna_shader_key key)
196{
197   const struct etna_shader_variant *old = ctx->shader.vs;
198
199   ctx->shader.vs = etna_shader_variant(ctx->shader.bind_vs, key, &ctx->debug);
200
201   if (!ctx->shader.vs)
202      return false;
203
204   if (old != ctx->shader.vs)
205      ctx->dirty |= ETNA_DIRTY_SHADER;
206
207   return true;
208}
209
210static bool
211etna_get_fs(struct etna_context *ctx, struct etna_shader_key key)
212{
213   const struct etna_shader_variant *old = ctx->shader.fs;
214
215   ctx->shader.fs = etna_shader_variant(ctx->shader.bind_fs, key, &ctx->debug);
216
217   if (!ctx->shader.fs)
218      return false;
219
220   if (old != ctx->shader.fs)
221      ctx->dirty |= ETNA_DIRTY_SHADER;
222
223   return true;
224}
225
226static void
227etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
228              unsigned drawid_offset,
229              const struct pipe_draw_indirect_info *indirect,
230              const struct pipe_draw_start_count_bias *draws,
231              unsigned num_draws)
232{
233   if (num_draws > 1) {
234      util_draw_multi(pctx, info, drawid_offset, indirect, draws, num_draws);
235      return;
236   }
237
238   if (!indirect && (!draws[0].count || !info->instance_count))
239      return;
240
241   struct etna_context *ctx = etna_context(pctx);
242   struct etna_screen *screen = ctx->screen;
243   struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s;
244   uint32_t draw_mode;
245   unsigned i;
246
247   if (!indirect &&
248       !info->primitive_restart &&
249       !u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
250      return;
251
252   if (ctx->vertex_elements == NULL || ctx->vertex_elements->num_elements == 0)
253      return; /* Nothing to do */
254
255   int prims = u_decomposed_prims_for_vertices(info->mode, draws[0].count);
256   if (unlikely(prims <= 0)) {
257      DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode);
258      return;
259   }
260
261   draw_mode = translate_draw_mode(info->mode);
262   if (draw_mode == ETNA_NO_MATCH) {
263      BUG("Unsupported draw mode");
264      return;
265   }
266
267   /* Upload a user index buffer. */
268   unsigned index_offset = 0;
269   struct pipe_resource *indexbuf = NULL;
270
271   if (info->index_size) {
272      indexbuf = info->has_user_indices ? NULL : info->index.resource;
273      if (info->has_user_indices &&
274          !util_upload_index_buffer(pctx, info, &draws[0], &indexbuf, &index_offset, 4)) {
275         BUG("Index buffer upload failed.");
276         return;
277      }
278      /* Add start to index offset, when rendering indexed */
279      index_offset += draws[0].start * info->index_size;
280
281      ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo = etna_resource(indexbuf)->bo;
282      ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.offset = index_offset;
283      ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.flags = ETNA_RELOC_READ;
284      ctx->index_buffer.FE_INDEX_STREAM_CONTROL = translate_index_size(info->index_size);
285
286      if (!ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo) {
287         BUG("Unsupported or no index buffer");
288         return;
289      }
290   } else {
291      ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo = 0;
292      ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.offset = 0;
293      ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.flags = 0;
294      ctx->index_buffer.FE_INDEX_STREAM_CONTROL = 0;
295   }
296   ctx->dirty |= ETNA_DIRTY_INDEX_BUFFER;
297
298   struct etna_shader_key key = {
299      .front_ccw = ctx->rasterizer->front_ccw,
300      .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable,
301      .sprite_coord_yinvert = !!ctx->rasterizer->sprite_coord_mode,
302   };
303
304   if (pfb->cbufs[0])
305      key.frag_rb_swap = !!translate_pe_format_rb_swap(pfb->cbufs[0]->format);
306
307   if (!etna_get_vs(ctx, key) || !etna_get_fs(ctx, key)) {
308      BUG("compiled shaders are not okay");
309      return;
310   }
311
312   /* Update any derived state */
313   if (!etna_state_update(ctx))
314      return;
315
316   mtx_lock(&ctx->lock);
317
318   /*
319    * Figure out the buffers/features we need:
320    */
321   if (etna_depth_enabled(ctx))
322      resource_written(ctx, pfb->zsbuf->texture);
323
324   if (etna_stencil_enabled(ctx))
325      resource_written(ctx, pfb->zsbuf->texture);
326
327   for (i = 0; i < pfb->nr_cbufs; i++) {
328      struct pipe_resource *surf;
329
330      if (!pfb->cbufs[i])
331         continue;
332
333      surf = pfb->cbufs[i]->texture;
334      resource_written(ctx, surf);
335   }
336
337   /* Mark constant buffers as being read */
338   u_foreach_bit(i, ctx->constant_buffer[PIPE_SHADER_VERTEX].enabled_mask)
339      resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb[i].buffer);
340
341   u_foreach_bit(i, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].enabled_mask)
342      resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb[i].buffer);
343
344   /* Mark VBOs as being read */
345   u_foreach_bit(i, ctx->vertex_buffer.enabled_mask) {
346      assert(!ctx->vertex_buffer.vb[i].is_user_buffer);
347      resource_read(ctx, ctx->vertex_buffer.vb[i].buffer.resource);
348   }
349
350   /* Mark index buffer as being read */
351   resource_read(ctx, indexbuf);
352
353   /* Mark textures as being read */
354   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
355      if (ctx->sampler_view[i]) {
356          resource_read(ctx, ctx->sampler_view[i]->texture);
357
358         /* if texture was modified since the last update,
359          * we need to clear the texture cache and possibly
360          * resolve/update ts
361          */
362         etna_update_sampler_source(ctx->sampler_view[i], i);
363      }
364   }
365
366   ctx->stats.prims_generated += u_reduced_prims_for_vertices(info->mode, draws[0].count);
367   ctx->stats.draw_calls++;
368
369   /* Update state for this draw operation */
370   etna_update_state_for_draw(ctx, info);
371
372   /* First, sync state, then emit DRAW_PRIMITIVES or DRAW_INDEXED_PRIMITIVES */
373   etna_emit_state(ctx);
374
375   if (screen->specs.halti >= 2) {
376      /* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */
377      etna_draw_instanced(ctx->stream, info->index_size, draw_mode, info->instance_count,
378         draws[0].count, info->index_size ? draws->index_bias : draws[0].start);
379   } else {
380      if (info->index_size)
381         etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, draws->index_bias);
382      else
383         etna_draw_primitives(ctx->stream, draw_mode, draws[0].start, prims);
384   }
385
386   if (DBG_ENABLED(ETNA_DBG_DRAW_STALL)) {
387      /* Stall the FE after every draw operation.  This allows better
388       * debug of GPU hang conditions, as the FE will indicate which
389       * draw op has caused the hang. */
390      etna_stall(ctx->stream, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
391   }
392   mtx_unlock(&ctx->lock);
393
394   if (DBG_ENABLED(ETNA_DBG_FLUSH_ALL))
395      pctx->flush(pctx, NULL, 0);
396
397   if (ctx->framebuffer_s.cbufs[0])
398      etna_resource(ctx->framebuffer_s.cbufs[0]->texture)->seqno++;
399   if (ctx->framebuffer_s.zsbuf)
400      etna_resource(ctx->framebuffer_s.zsbuf->texture)->seqno++;
401   if (info->index_size && indexbuf != info->index.resource)
402      pipe_resource_reference(&indexbuf, NULL);
403}
404
405static void
406etna_reset_gpu_state(struct etna_context *ctx)
407{
408   struct etna_cmd_stream *stream = ctx->stream;
409   struct etna_screen *screen = ctx->screen;
410   uint32_t dummy_attribs[VIVS_NFE_GENERIC_ATTRIB__LEN] = { 0 };
411
412   etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL);
413   etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x00000001);
414   etna_set_state(stream, VIVS_PA_W_CLIP_LIMIT, 0x34000001);
415   etna_set_state(stream, VIVS_PA_FLAGS, 0x00000000); /* blob sets ZCONVERT_BYPASS on GC3000+, this messes up z for us */
416   etna_set_state(stream, VIVS_PA_VIEWPORT_UNK00A80, 0x38a01404);
417   etna_set_state(stream, VIVS_PA_VIEWPORT_UNK00A84, fui(8192.0));
418   etna_set_state(stream, VIVS_PA_ZFARCLIPPING, 0x00000000);
419   etna_set_state(stream, VIVS_RA_HDEPTH_CONTROL, 0x00007000);
420   etna_set_state(stream, VIVS_PS_CONTROL_EXT, 0x00000000);
421
422   /* There is no HALTI0 specific state */
423   if (screen->specs.halti >= 1) { /* Only on HALTI1+ */
424      etna_set_state(stream, VIVS_VS_HALTI1_UNK00884, 0x00000808);
425   }
426   if (screen->specs.halti >= 2) { /* Only on HALTI2+ */
427      etna_set_state(stream, VIVS_RA_UNK00E0C, 0x00000000);
428   }
429   if (screen->specs.halti >= 3) { /* Only on HALTI3+ */
430      etna_set_state(stream, VIVS_PS_HALTI3_UNK0103C, 0x76543210);
431   }
432   if (screen->specs.halti >= 4) { /* Only on HALTI4+ */
433      etna_set_state(stream, VIVS_PS_MSAA_CONFIG, 0x6fffffff & 0xf70fffff & 0xfff6ffff &
434                                                  0xffff6fff & 0xfffff6ff & 0xffffff7f);
435      etna_set_state(stream, VIVS_PE_HALTI4_UNK014C0, 0x00000000);
436   }
437   if (screen->specs.halti >= 5) { /* Only on HALTI5+ */
438      etna_set_state(stream, VIVS_NTE_DESCRIPTOR_UNK14C40, 0x00000001);
439      etna_set_state(stream, VIVS_FE_HALTI5_UNK007D8, 0x00000002);
440      etna_set_state(stream, VIVS_PS_SAMPLER_BASE, 0x00000000);
441      etna_set_state(stream, VIVS_VS_SAMPLER_BASE, 0x00000020);
442      etna_set_state(stream, VIVS_SH_CONFIG, VIVS_SH_CONFIG_RTNE_ROUNDING);
443   } else { /* Only on pre-HALTI5 */
444      etna_set_state(stream, VIVS_GL_UNK03838, 0x00000000);
445      etna_set_state(stream, VIVS_GL_UNK03854, 0x00000000);
446   }
447
448   if (!screen->specs.use_blt) {
449      /* Enable SINGLE_BUFFER for resolve, if supported */
450      etna_set_state(stream, VIVS_RS_SINGLE_BUFFER, COND(screen->specs.single_buffer, VIVS_RS_SINGLE_BUFFER_ENABLE));
451   }
452
453   if (screen->specs.halti >= 5) {
454      /* TXDESC cache flush - do this once at the beginning, as texture
455       * descriptors are only written by the CPU once, then patched by the kernel
456       * before command stream submission. It does not need flushing if the
457       * referenced image data changes.
458       */
459      etna_set_state(stream, VIVS_NTE_DESCRIPTOR_FLUSH, 0);
460      etna_set_state(stream, VIVS_GL_FLUSH_CACHE,
461            VIVS_GL_FLUSH_CACHE_DESCRIPTOR_UNK12 |
462            VIVS_GL_FLUSH_CACHE_DESCRIPTOR_UNK13);
463
464      /* Icache invalidate (should do this on shader change?) */
465      etna_set_state(stream, VIVS_VS_ICACHE_INVALIDATE,
466            VIVS_VS_ICACHE_INVALIDATE_UNK0 | VIVS_VS_ICACHE_INVALIDATE_UNK1 |
467            VIVS_VS_ICACHE_INVALIDATE_UNK2 | VIVS_VS_ICACHE_INVALIDATE_UNK3 |
468            VIVS_VS_ICACHE_INVALIDATE_UNK4);
469   }
470
471   /* It seems that some GPUs (at least some GC400 have shown this behavior)
472    * come out of reset with random vertex attributes enabled and also don't
473    * disable them on the write to the first config register as normal. Enabling
474    * all attributes seems to provide the GPU with the required edge to actually
475    * disable the unused attributes on the next draw.
476    */
477   if (screen->specs.halti >= 5) {
478      etna_set_state_multi(stream, VIVS_NFE_GENERIC_ATTRIB_CONFIG0(0),
479                           VIVS_NFE_GENERIC_ATTRIB__LEN, dummy_attribs);
480   } else {
481      etna_set_state_multi(stream, VIVS_FE_VERTEX_ELEMENT_CONFIG(0),
482                           screen->specs.halti >= 0 ? 16 : 12, dummy_attribs);
483   }
484
485   ctx->dirty = ~0L;
486   ctx->dirty_sampler_views = ~0L;
487}
488
489static void
490etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
491           enum pipe_flush_flags flags)
492{
493   struct etna_context *ctx = etna_context(pctx);
494   int out_fence_fd = -1;
495
496   mtx_lock(&ctx->lock);
497
498   list_for_each_entry(struct etna_acc_query, aq, &ctx->active_acc_queries, node)
499      etna_acc_query_suspend(aq, ctx);
500
501   /* flush all resources that need an implicit flush */
502   set_foreach(ctx->flush_resources, entry) {
503      struct pipe_resource *prsc = (struct pipe_resource *)entry->key;
504
505      pctx->flush_resource(pctx, prsc);
506   }
507   _mesa_set_clear(ctx->flush_resources, NULL);
508
509   etna_cmd_stream_flush(ctx->stream, ctx->in_fence_fd,
510                          (flags & PIPE_FLUSH_FENCE_FD) ? &out_fence_fd : NULL);
511
512   list_for_each_entry(struct etna_acc_query, aq, &ctx->active_acc_queries, node)
513      etna_acc_query_resume(aq, ctx);
514
515   if (fence)
516      *fence = etna_fence_create(pctx, out_fence_fd);
517
518   /*
519   * Go through all _resources_ pending in this _context_ and mark them as
520   * not pending in this _context_ anymore, since they were just flushed.
521   */
522   set_foreach(ctx->used_resources_read, entry) {
523      struct etna_resource *rsc = (struct etna_resource *)entry->key;
524      struct pipe_resource *referenced = &rsc->base;
525
526      mtx_lock(&rsc->lock);
527
528      _mesa_set_remove_key(rsc->pending_ctx, ctx);
529
530      /* if resource has no pending ctx's reset its status */
531      if (_mesa_set_next_entry(rsc->pending_ctx, NULL) == NULL)
532         rsc->status &= ~ETNA_PENDING_READ;
533
534      mtx_unlock(&rsc->lock);
535
536      pipe_resource_reference(&referenced, NULL);
537   }
538   _mesa_set_clear(ctx->used_resources_read, NULL);
539
540   set_foreach(ctx->used_resources_write, entry) {
541      struct etna_resource *rsc = (struct etna_resource *)entry->key;
542      struct pipe_resource *referenced = &rsc->base;
543
544      mtx_lock(&rsc->lock);
545      _mesa_set_remove_key(rsc->pending_ctx, ctx);
546
547      /* if resource has no pending ctx's reset its status */
548      if (_mesa_set_next_entry(rsc->pending_ctx, NULL) == NULL)
549         rsc->status &= ~ETNA_PENDING_WRITE;
550      mtx_unlock(&rsc->lock);
551
552      pipe_resource_reference(&referenced, NULL);
553   }
554   _mesa_set_clear(ctx->used_resources_write, NULL);
555
556   etna_reset_gpu_state(ctx);
557   mtx_unlock(&ctx->lock);
558}
559
560static void
561etna_context_force_flush(struct etna_cmd_stream *stream, void *priv)
562{
563   struct pipe_context *pctx = priv;
564
565   pctx->flush(pctx, NULL, 0);
566
567}
568
569static void
570etna_set_debug_callback(struct pipe_context *pctx,
571                        const struct pipe_debug_callback *cb)
572{
573   struct etna_context *ctx = etna_context(pctx);
574
575   if (cb)
576      ctx->debug = *cb;
577   else
578      memset(&ctx->debug, 0, sizeof(ctx->debug));
579}
580
581struct pipe_context *
582etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
583{
584   struct etna_context *ctx = CALLOC_STRUCT(etna_context);
585   struct etna_screen *screen;
586   struct pipe_context *pctx;
587
588   if (ctx == NULL)
589      return NULL;
590
591   pctx = &ctx->base;
592   pctx->priv = ctx;
593   pctx->screen = pscreen;
594   pctx->stream_uploader = u_upload_create_default(pctx);
595   if (!pctx->stream_uploader)
596      goto fail;
597   pctx->const_uploader = pctx->stream_uploader;
598
599   screen = etna_screen(pscreen);
600   ctx->stream = etna_cmd_stream_new(screen->pipe, 0x2000,
601                                     &etna_context_force_flush, pctx);
602   if (ctx->stream == NULL)
603      goto fail;
604
605   ctx->used_resources_read = _mesa_set_create(NULL, _mesa_hash_pointer,
606                                          _mesa_key_pointer_equal);
607   if (!ctx->used_resources_read)
608      goto fail;
609
610   ctx->used_resources_write = _mesa_set_create(NULL, _mesa_hash_pointer,
611                                          _mesa_key_pointer_equal);
612   if (!ctx->used_resources_write)
613      goto fail;
614
615   ctx->flush_resources = _mesa_set_create(NULL, _mesa_hash_pointer,
616                                           _mesa_key_pointer_equal);
617   if (!ctx->flush_resources)
618      goto fail;
619
620   mtx_init(&ctx->lock, mtx_recursive);
621
622   /* context ctxate setup */
623   ctx->screen = screen;
624   /* need some sane default in case gallium frontends don't set some state: */
625   ctx->sample_mask = 0xffff;
626
627   /*  Set sensible defaults for state */
628   etna_reset_gpu_state(ctx);
629
630   ctx->in_fence_fd = -1;
631
632   pctx->destroy = etna_context_destroy;
633   pctx->draw_vbo = etna_draw_vbo;
634   pctx->flush = etna_flush;
635   pctx->set_debug_callback = etna_set_debug_callback;
636   pctx->create_fence_fd = etna_create_fence_fd;
637   pctx->fence_server_sync = etna_fence_server_sync;
638   pctx->emit_string_marker = etna_emit_string_marker;
639
640   /* creation of compile states */
641   pctx->create_blend_state = etna_blend_state_create;
642   pctx->create_rasterizer_state = etna_rasterizer_state_create;
643   pctx->create_depth_stencil_alpha_state = etna_zsa_state_create;
644
645   etna_clear_blit_init(pctx);
646   etna_query_context_init(pctx);
647   etna_state_init(pctx);
648   etna_surface_init(pctx);
649   etna_shader_init(pctx);
650   etna_texture_init(pctx);
651   etna_transfer_init(pctx);
652
653   ctx->blitter = util_blitter_create(pctx);
654   if (!ctx->blitter)
655      goto fail;
656
657   slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
658   list_inithead(&ctx->active_acc_queries);
659
660   /* create dummy RT buffer, used when rendering with no color buffer */
661   ctx->dummy_rt = etna_bo_new(ctx->screen->dev, 64 * 64 * 4,
662                               DRM_ETNA_GEM_CACHE_WC);
663   if (!ctx->dummy_rt)
664      goto fail;
665
666   ctx->dummy_rt_reloc.bo = ctx->dummy_rt;
667   ctx->dummy_rt_reloc.offset = 0;
668   ctx->dummy_rt_reloc.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
669
670   if (screen->specs.halti >= 5) {
671      /* Create an empty dummy texture descriptor */
672      ctx->dummy_desc_bo = etna_bo_new(ctx->screen->dev, 0x100, DRM_ETNA_GEM_CACHE_WC);
673      if (!ctx->dummy_desc_bo)
674         goto fail;
675      uint32_t *buf = etna_bo_map(ctx->dummy_desc_bo);
676      etna_bo_cpu_prep(ctx->dummy_desc_bo, DRM_ETNA_PREP_WRITE);
677      memset(buf, 0, 0x100);
678      etna_bo_cpu_fini(ctx->dummy_desc_bo);
679      ctx->DUMMY_DESC_ADDR.bo = ctx->dummy_desc_bo;
680      ctx->DUMMY_DESC_ADDR.offset = 0;
681      ctx->DUMMY_DESC_ADDR.flags = ETNA_RELOC_READ;
682   }
683
684   return pctx;
685
686fail:
687   pctx->destroy(pctx);
688
689   return NULL;
690}
691