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