1bf215546Sopenharmony_ci/**********************************************************
2bf215546Sopenharmony_ci * Copyright 2009-2011 VMware, Inc. All rights reserved.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person
5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation
6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without
7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy,
8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies
9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is
10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be
13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22bf215546Sopenharmony_ci * SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci *********************************************************
25bf215546Sopenharmony_ci * Authors:
26bf215546Sopenharmony_ci * Zack Rusin <zackr-at-vmware-dot-com>
27bf215546Sopenharmony_ci * Thomas Hellstrom <thellstrom-at-vmware-dot-com>
28bf215546Sopenharmony_ci */
29bf215546Sopenharmony_ci#include "xa_context.h"
30bf215546Sopenharmony_ci#include "xa_priv.h"
31bf215546Sopenharmony_ci#include "cso_cache/cso_context.h"
32bf215546Sopenharmony_ci#include "util/u_inlines.h"
33bf215546Sopenharmony_ci#include "util/u_rect.h"
34bf215546Sopenharmony_ci#include "util/u_surface.h"
35bf215546Sopenharmony_ci#include "pipe/p_context.h"
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ciXA_EXPORT void
38bf215546Sopenharmony_cixa_context_flush(struct xa_context *ctx)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci    if (ctx->last_fence) {
41bf215546Sopenharmony_ci        struct pipe_screen *screen = ctx->xa->screen;
42bf215546Sopenharmony_ci        screen->fence_reference(screen, &ctx->last_fence, NULL);
43bf215546Sopenharmony_ci    }
44bf215546Sopenharmony_ci    ctx->pipe->flush(ctx->pipe, &ctx->last_fence, 0);
45bf215546Sopenharmony_ci}
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ciXA_EXPORT struct xa_context *
48bf215546Sopenharmony_cixa_context_default(struct xa_tracker *xa)
49bf215546Sopenharmony_ci{
50bf215546Sopenharmony_ci    return xa->default_ctx;
51bf215546Sopenharmony_ci}
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ciXA_EXPORT struct xa_context *
54bf215546Sopenharmony_cixa_context_create(struct xa_tracker *xa)
55bf215546Sopenharmony_ci{
56bf215546Sopenharmony_ci    struct xa_context *ctx = calloc(1, sizeof(*ctx));
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci    ctx->xa = xa;
59bf215546Sopenharmony_ci    ctx->pipe = xa->screen->context_create(xa->screen, NULL, 0);
60bf215546Sopenharmony_ci    ctx->cso = cso_create_context(ctx->pipe, 0);
61bf215546Sopenharmony_ci    ctx->shaders = xa_shaders_create(ctx);
62bf215546Sopenharmony_ci    renderer_init_state(ctx);
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci    return ctx;
65bf215546Sopenharmony_ci}
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ciXA_EXPORT void
68bf215546Sopenharmony_cixa_context_destroy(struct xa_context *r)
69bf215546Sopenharmony_ci{
70bf215546Sopenharmony_ci    struct pipe_resource **vsbuf = &r->vs_const_buffer;
71bf215546Sopenharmony_ci    struct pipe_resource **fsbuf = &r->fs_const_buffer;
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci    if (*vsbuf)
74bf215546Sopenharmony_ci	pipe_resource_reference(vsbuf, NULL);
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci    if (*fsbuf)
77bf215546Sopenharmony_ci	pipe_resource_reference(fsbuf, NULL);
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci    if (r->shaders) {
80bf215546Sopenharmony_ci	xa_shaders_destroy(r->shaders);
81bf215546Sopenharmony_ci	r->shaders = NULL;
82bf215546Sopenharmony_ci    }
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci    xa_ctx_sampler_views_destroy(r);
85bf215546Sopenharmony_ci    if (r->srf)
86bf215546Sopenharmony_ci        pipe_surface_reference(&r->srf, NULL);
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci    if (r->cso) {
89bf215546Sopenharmony_ci	cso_destroy_context(r->cso);
90bf215546Sopenharmony_ci	r->cso = NULL;
91bf215546Sopenharmony_ci    }
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci    r->pipe->destroy(r->pipe);
94bf215546Sopenharmony_ci    free(r);
95bf215546Sopenharmony_ci}
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ciXA_EXPORT int
98bf215546Sopenharmony_cixa_surface_dma(struct xa_context *ctx,
99bf215546Sopenharmony_ci	       struct xa_surface *srf,
100bf215546Sopenharmony_ci	       void *data,
101bf215546Sopenharmony_ci	       unsigned int pitch,
102bf215546Sopenharmony_ci	       int to_surface, struct xa_box *boxes, unsigned int num_boxes)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci    struct pipe_transfer *transfer;
105bf215546Sopenharmony_ci    void *map;
106bf215546Sopenharmony_ci    int w, h, i;
107bf215546Sopenharmony_ci    enum pipe_map_flags transfer_direction;
108bf215546Sopenharmony_ci    struct pipe_context *pipe = ctx->pipe;
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci    transfer_direction = (to_surface ? PIPE_MAP_WRITE :
111bf215546Sopenharmony_ci			  PIPE_MAP_READ);
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci    for (i = 0; i < num_boxes; ++i, ++boxes) {
114bf215546Sopenharmony_ci	w = boxes->x2 - boxes->x1;
115bf215546Sopenharmony_ci	h = boxes->y2 - boxes->y1;
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci	map = pipe_texture_map(pipe, srf->tex, 0, 0,
118bf215546Sopenharmony_ci                                transfer_direction, boxes->x1, boxes->y1,
119bf215546Sopenharmony_ci                                w, h, &transfer);
120bf215546Sopenharmony_ci	if (!map)
121bf215546Sopenharmony_ci	    return -XA_ERR_NORES;
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci	if (to_surface) {
124bf215546Sopenharmony_ci	    util_copy_rect(map, srf->tex->format, transfer->stride,
125bf215546Sopenharmony_ci			   0, 0, w, h, data, pitch, boxes->x1, boxes->y1);
126bf215546Sopenharmony_ci	} else {
127bf215546Sopenharmony_ci	    util_copy_rect(data, srf->tex->format, pitch,
128bf215546Sopenharmony_ci			   boxes->x1, boxes->y1, w, h, map, transfer->stride, 0,
129bf215546Sopenharmony_ci			   0);
130bf215546Sopenharmony_ci	}
131bf215546Sopenharmony_ci	pipe->texture_unmap(pipe, transfer);
132bf215546Sopenharmony_ci    }
133bf215546Sopenharmony_ci    return XA_ERR_NONE;
134bf215546Sopenharmony_ci}
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ciXA_EXPORT void *
137bf215546Sopenharmony_cixa_surface_map(struct xa_context *ctx,
138bf215546Sopenharmony_ci	       struct xa_surface *srf, unsigned int usage)
139bf215546Sopenharmony_ci{
140bf215546Sopenharmony_ci    void *map;
141bf215546Sopenharmony_ci    unsigned int gallium_usage = 0;
142bf215546Sopenharmony_ci    struct pipe_context *pipe = ctx->pipe;
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci    /*
145bf215546Sopenharmony_ci     * A surface may only have a single map.
146bf215546Sopenharmony_ci     */
147bf215546Sopenharmony_ci    if (srf->transfer)
148bf215546Sopenharmony_ci	return NULL;
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci    if (usage & XA_MAP_READ)
151bf215546Sopenharmony_ci	gallium_usage |= PIPE_MAP_READ;
152bf215546Sopenharmony_ci    if (usage & XA_MAP_WRITE)
153bf215546Sopenharmony_ci	gallium_usage |= PIPE_MAP_WRITE;
154bf215546Sopenharmony_ci    if (usage & XA_MAP_MAP_DIRECTLY)
155bf215546Sopenharmony_ci	gallium_usage |= PIPE_MAP_DIRECTLY;
156bf215546Sopenharmony_ci    if (usage & XA_MAP_UNSYNCHRONIZED)
157bf215546Sopenharmony_ci	gallium_usage |= PIPE_MAP_UNSYNCHRONIZED;
158bf215546Sopenharmony_ci    if (usage & XA_MAP_DONTBLOCK)
159bf215546Sopenharmony_ci	gallium_usage |= PIPE_MAP_DONTBLOCK;
160bf215546Sopenharmony_ci    if (usage & XA_MAP_DISCARD_WHOLE_RESOURCE)
161bf215546Sopenharmony_ci	gallium_usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci    if (!(gallium_usage & (PIPE_MAP_READ_WRITE)))
164bf215546Sopenharmony_ci	return NULL;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci    map = pipe_texture_map(pipe, srf->tex, 0, 0,
167bf215546Sopenharmony_ci                            gallium_usage, 0, 0,
168bf215546Sopenharmony_ci                            srf->tex->width0, srf->tex->height0,
169bf215546Sopenharmony_ci                            &srf->transfer);
170bf215546Sopenharmony_ci    if (!map)
171bf215546Sopenharmony_ci	return NULL;
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci    srf->mapping_pipe = pipe;
174bf215546Sopenharmony_ci    return map;
175bf215546Sopenharmony_ci}
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ciXA_EXPORT void
178bf215546Sopenharmony_cixa_surface_unmap(struct xa_surface *srf)
179bf215546Sopenharmony_ci{
180bf215546Sopenharmony_ci    if (srf->transfer) {
181bf215546Sopenharmony_ci	struct pipe_context *pipe = srf->mapping_pipe;
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci	pipe->texture_unmap(pipe, srf->transfer);
184bf215546Sopenharmony_ci	srf->transfer = NULL;
185bf215546Sopenharmony_ci    }
186bf215546Sopenharmony_ci}
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ciint
189bf215546Sopenharmony_cixa_ctx_srf_create(struct xa_context *ctx, struct xa_surface *dst)
190bf215546Sopenharmony_ci{
191bf215546Sopenharmony_ci    struct pipe_screen *screen = ctx->pipe->screen;
192bf215546Sopenharmony_ci    struct pipe_surface srf_templ;
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ci    /*
195bf215546Sopenharmony_ci     * Cache surfaces unless we change render target
196bf215546Sopenharmony_ci     */
197bf215546Sopenharmony_ci    if (ctx->srf) {
198bf215546Sopenharmony_ci        if (ctx->srf->texture == dst->tex)
199bf215546Sopenharmony_ci            return XA_ERR_NONE;
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci        pipe_surface_reference(&ctx->srf, NULL);
202bf215546Sopenharmony_ci    }
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci    if (!screen->is_format_supported(screen,  dst->tex->format,
205bf215546Sopenharmony_ci				     PIPE_TEXTURE_2D, 0, 0,
206bf215546Sopenharmony_ci				     PIPE_BIND_RENDER_TARGET))
207bf215546Sopenharmony_ci	return -XA_ERR_INVAL;
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci    u_surface_default_template(&srf_templ, dst->tex);
210bf215546Sopenharmony_ci    ctx->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ);
211bf215546Sopenharmony_ci    if (!ctx->srf)
212bf215546Sopenharmony_ci	return -XA_ERR_NORES;
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci    return XA_ERR_NONE;
215bf215546Sopenharmony_ci}
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_civoid
218bf215546Sopenharmony_cixa_ctx_srf_destroy(struct xa_context *ctx)
219bf215546Sopenharmony_ci{
220bf215546Sopenharmony_ci    /*
221bf215546Sopenharmony_ci     * Cache surfaces unless we change render target.
222bf215546Sopenharmony_ci     * Final destruction on context destroy.
223bf215546Sopenharmony_ci     */
224bf215546Sopenharmony_ci}
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ciXA_EXPORT int
227bf215546Sopenharmony_cixa_copy_prepare(struct xa_context *ctx,
228bf215546Sopenharmony_ci		struct xa_surface *dst, struct xa_surface *src)
229bf215546Sopenharmony_ci{
230bf215546Sopenharmony_ci    if (src == dst)
231bf215546Sopenharmony_ci	return -XA_ERR_INVAL;
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci    if (src->tex->format != dst->tex->format) {
234bf215546Sopenharmony_ci	int ret = xa_ctx_srf_create(ctx, dst);
235bf215546Sopenharmony_ci	if (ret != XA_ERR_NONE)
236bf215546Sopenharmony_ci	    return ret;
237bf215546Sopenharmony_ci	renderer_copy_prepare(ctx, ctx->srf, src->tex,
238bf215546Sopenharmony_ci			      src->fdesc.xa_format,
239bf215546Sopenharmony_ci			      dst->fdesc.xa_format);
240bf215546Sopenharmony_ci	ctx->simple_copy = 0;
241bf215546Sopenharmony_ci    } else
242bf215546Sopenharmony_ci	ctx->simple_copy = 1;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci    ctx->src = src;
245bf215546Sopenharmony_ci    ctx->dst = dst;
246bf215546Sopenharmony_ci    xa_ctx_srf_destroy(ctx);
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci    return 0;
249bf215546Sopenharmony_ci}
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ciXA_EXPORT void
252bf215546Sopenharmony_cixa_copy(struct xa_context *ctx,
253bf215546Sopenharmony_ci	int dx, int dy, int sx, int sy, int width, int height)
254bf215546Sopenharmony_ci{
255bf215546Sopenharmony_ci    struct pipe_box src_box;
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci    xa_scissor_update(ctx, dx, dy, dx + width, dy + height);
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_ci    if (ctx->simple_copy) {
260bf215546Sopenharmony_ci	u_box_2d(sx, sy, width, height, &src_box);
261bf215546Sopenharmony_ci	ctx->pipe->resource_copy_region(ctx->pipe,
262bf215546Sopenharmony_ci					ctx->dst->tex, 0, dx, dy, 0,
263bf215546Sopenharmony_ci					ctx->src->tex,
264bf215546Sopenharmony_ci					0, &src_box);
265bf215546Sopenharmony_ci    } else
266bf215546Sopenharmony_ci	renderer_copy(ctx, dx, dy, sx, sy, width, height,
267bf215546Sopenharmony_ci		      (float) ctx->src->tex->width0,
268bf215546Sopenharmony_ci		      (float) ctx->src->tex->height0);
269bf215546Sopenharmony_ci}
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ciXA_EXPORT void
272bf215546Sopenharmony_cixa_copy_done(struct xa_context *ctx)
273bf215546Sopenharmony_ci{
274bf215546Sopenharmony_ci    if (!ctx->simple_copy) {
275bf215546Sopenharmony_ci	renderer_draw_flush(ctx);
276bf215546Sopenharmony_ci    }
277bf215546Sopenharmony_ci}
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_cistatic void
280bf215546Sopenharmony_cibind_solid_blend_state(struct xa_context *ctx)
281bf215546Sopenharmony_ci{
282bf215546Sopenharmony_ci    struct pipe_blend_state blend;
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci    memset(&blend, 0, sizeof(struct pipe_blend_state));
285bf215546Sopenharmony_ci    blend.rt[0].blend_enable = 0;
286bf215546Sopenharmony_ci    blend.rt[0].colormask = PIPE_MASK_RGBA;
287bf215546Sopenharmony_ci
288bf215546Sopenharmony_ci    blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
289bf215546Sopenharmony_ci    blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
290bf215546Sopenharmony_ci    blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
291bf215546Sopenharmony_ci    blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci    cso_set_blend(ctx->cso, &blend);
294bf215546Sopenharmony_ci}
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ciXA_EXPORT int
297bf215546Sopenharmony_cixa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
298bf215546Sopenharmony_ci		 uint32_t fg)
299bf215546Sopenharmony_ci{
300bf215546Sopenharmony_ci    unsigned vs_traits, fs_traits;
301bf215546Sopenharmony_ci    struct xa_shader shader;
302bf215546Sopenharmony_ci    int ret;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci    ret = xa_ctx_srf_create(ctx, dst);
305bf215546Sopenharmony_ci    if (ret != XA_ERR_NONE)
306bf215546Sopenharmony_ci	return ret;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
309bf215546Sopenharmony_ci	xa_pixel_to_float4_a8(fg, ctx->solid_color);
310bf215546Sopenharmony_ci    else
311bf215546Sopenharmony_ci	xa_pixel_to_float4(fg, ctx->solid_color);
312bf215546Sopenharmony_ci    ctx->has_solid_src = 1;
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci    ctx->dst = dst;
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ci#if 0
317bf215546Sopenharmony_ci    debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
318bf215546Sopenharmony_ci		 (fg >> 24) & 0xff, (fg >> 16) & 0xff,
319bf215546Sopenharmony_ci		 (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
320bf215546Sopenharmony_ci		 exa->solid_color[0], exa->solid_color[1],
321bf215546Sopenharmony_ci		 exa->solid_color[2], exa->solid_color[3]);
322bf215546Sopenharmony_ci#endif
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci    vs_traits = VS_SRC_SRC | VS_COMPOSITE;
325bf215546Sopenharmony_ci    fs_traits = FS_SRC_SRC | VS_COMPOSITE;
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci    renderer_bind_destination(ctx, ctx->srf);
328bf215546Sopenharmony_ci    bind_solid_blend_state(ctx);
329bf215546Sopenharmony_ci    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
330bf215546Sopenharmony_ci    ctx->pipe->set_sampler_views(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, 0,
331bf215546Sopenharmony_ci                                 XA_MAX_SAMPLERS, false, NULL);
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci    shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
334bf215546Sopenharmony_ci    cso_set_vertex_shader_handle(ctx->cso, shader.vs);
335bf215546Sopenharmony_ci    cso_set_fragment_shader_handle(ctx->cso, shader.fs);
336bf215546Sopenharmony_ci
337bf215546Sopenharmony_ci    renderer_begin_solid(ctx);
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci    xa_ctx_srf_destroy(ctx);
340bf215546Sopenharmony_ci    return XA_ERR_NONE;
341bf215546Sopenharmony_ci}
342bf215546Sopenharmony_ci
343bf215546Sopenharmony_ciXA_EXPORT void
344bf215546Sopenharmony_cixa_solid(struct xa_context *ctx, int x, int y, int width, int height)
345bf215546Sopenharmony_ci{
346bf215546Sopenharmony_ci    xa_scissor_update(ctx, x, y, x + width, y + height);
347bf215546Sopenharmony_ci    renderer_solid(ctx, x, y, x + width, y + height);
348bf215546Sopenharmony_ci}
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_ciXA_EXPORT void
351bf215546Sopenharmony_cixa_solid_done(struct xa_context *ctx)
352bf215546Sopenharmony_ci{
353bf215546Sopenharmony_ci    renderer_draw_flush(ctx);
354bf215546Sopenharmony_ci    ctx->comp = NULL;
355bf215546Sopenharmony_ci    ctx->has_solid_src = FALSE;
356bf215546Sopenharmony_ci    ctx->num_bound_samplers = 0;
357bf215546Sopenharmony_ci}
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ciXA_EXPORT struct xa_fence *
360bf215546Sopenharmony_cixa_fence_get(struct xa_context *ctx)
361bf215546Sopenharmony_ci{
362bf215546Sopenharmony_ci    struct xa_fence *fence = calloc(1, sizeof(*fence));
363bf215546Sopenharmony_ci    struct pipe_screen *screen = ctx->xa->screen;
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci    if (!fence)
366bf215546Sopenharmony_ci	return NULL;
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci    fence->xa = ctx->xa;
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci    if (ctx->last_fence == NULL)
371bf215546Sopenharmony_ci	fence->pipe_fence = NULL;
372bf215546Sopenharmony_ci    else
373bf215546Sopenharmony_ci	screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence);
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci    return fence;
376bf215546Sopenharmony_ci}
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ciXA_EXPORT int
379bf215546Sopenharmony_cixa_fence_wait(struct xa_fence *fence, uint64_t timeout)
380bf215546Sopenharmony_ci{
381bf215546Sopenharmony_ci    if (!fence)
382bf215546Sopenharmony_ci	return XA_ERR_NONE;
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci    if (fence->pipe_fence) {
385bf215546Sopenharmony_ci	struct pipe_screen *screen = fence->xa->screen;
386bf215546Sopenharmony_ci	boolean timed_out;
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci	timed_out = !screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
389bf215546Sopenharmony_ci	if (timed_out)
390bf215546Sopenharmony_ci	    return -XA_ERR_BUSY;
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci	screen->fence_reference(screen, &fence->pipe_fence, NULL);
393bf215546Sopenharmony_ci    }
394bf215546Sopenharmony_ci    return XA_ERR_NONE;
395bf215546Sopenharmony_ci}
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ciXA_EXPORT void
398bf215546Sopenharmony_cixa_fence_destroy(struct xa_fence *fence)
399bf215546Sopenharmony_ci{
400bf215546Sopenharmony_ci    if (!fence)
401bf215546Sopenharmony_ci	return;
402bf215546Sopenharmony_ci
403bf215546Sopenharmony_ci    if (fence->pipe_fence) {
404bf215546Sopenharmony_ci	struct pipe_screen *screen = fence->xa->screen;
405bf215546Sopenharmony_ci
406bf215546Sopenharmony_ci	screen->fence_reference(screen, &fence->pipe_fence, NULL);
407bf215546Sopenharmony_ci    }
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci    free(fence);
410bf215546Sopenharmony_ci}
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_civoid
413bf215546Sopenharmony_cixa_ctx_sampler_views_destroy(struct xa_context *ctx)
414bf215546Sopenharmony_ci{
415bf215546Sopenharmony_ci    int i;
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci    for (i = 0; i < ctx->num_bound_samplers; ++i)
418bf215546Sopenharmony_ci	pipe_sampler_view_reference(&ctx->bound_sampler_views[i], NULL);
419bf215546Sopenharmony_ci    ctx->num_bound_samplers = 0;
420bf215546Sopenharmony_ci}
421