17ec681f3Smrg/**********************************************************
27ec681f3Smrg * Copyright 2009-2011 VMware, Inc. All rights reserved.
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person
57ec681f3Smrg * obtaining a copy of this software and associated documentation
67ec681f3Smrg * files (the "Software"), to deal in the Software without
77ec681f3Smrg * restriction, including without limitation the rights to use, copy,
87ec681f3Smrg * modify, merge, publish, distribute, sublicense, and/or sell copies
97ec681f3Smrg * of the Software, and to permit persons to whom the Software is
107ec681f3Smrg * furnished to do so, subject to the following conditions:
117ec681f3Smrg *
127ec681f3Smrg * The above copyright notice and this permission notice shall be
137ec681f3Smrg * included in all copies or substantial portions of the Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
167ec681f3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
177ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
187ec681f3Smrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
197ec681f3Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
207ec681f3Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
217ec681f3Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
227ec681f3Smrg * SOFTWARE.
237ec681f3Smrg *
247ec681f3Smrg *********************************************************
257ec681f3Smrg * Authors:
267ec681f3Smrg * Zack Rusin <zackr-at-vmware-dot-com>
277ec681f3Smrg * Thomas Hellstrom <thellstrom-at-vmware-dot-com>
287ec681f3Smrg */
297ec681f3Smrg#include "xa_context.h"
307ec681f3Smrg#include "xa_priv.h"
317ec681f3Smrg#include "cso_cache/cso_context.h"
327ec681f3Smrg#include "util/u_inlines.h"
337ec681f3Smrg#include "util/u_rect.h"
347ec681f3Smrg#include "util/u_surface.h"
357ec681f3Smrg#include "pipe/p_context.h"
367ec681f3Smrg
377ec681f3SmrgXA_EXPORT void
387ec681f3Smrgxa_context_flush(struct xa_context *ctx)
397ec681f3Smrg{
407ec681f3Smrg    if (ctx->last_fence) {
417ec681f3Smrg        struct pipe_screen *screen = ctx->xa->screen;
427ec681f3Smrg        screen->fence_reference(screen, &ctx->last_fence, NULL);
437ec681f3Smrg    }
447ec681f3Smrg    ctx->pipe->flush(ctx->pipe, &ctx->last_fence, 0);
457ec681f3Smrg}
467ec681f3Smrg
477ec681f3SmrgXA_EXPORT struct xa_context *
487ec681f3Smrgxa_context_default(struct xa_tracker *xa)
497ec681f3Smrg{
507ec681f3Smrg    return xa->default_ctx;
517ec681f3Smrg}
527ec681f3Smrg
537ec681f3SmrgXA_EXPORT struct xa_context *
547ec681f3Smrgxa_context_create(struct xa_tracker *xa)
557ec681f3Smrg{
567ec681f3Smrg    struct xa_context *ctx = calloc(1, sizeof(*ctx));
577ec681f3Smrg
587ec681f3Smrg    ctx->xa = xa;
597ec681f3Smrg    ctx->pipe = xa->screen->context_create(xa->screen, NULL, 0);
607ec681f3Smrg    ctx->cso = cso_create_context(ctx->pipe, 0);
617ec681f3Smrg    ctx->shaders = xa_shaders_create(ctx);
627ec681f3Smrg    renderer_init_state(ctx);
637ec681f3Smrg
647ec681f3Smrg    return ctx;
657ec681f3Smrg}
667ec681f3Smrg
677ec681f3SmrgXA_EXPORT void
687ec681f3Smrgxa_context_destroy(struct xa_context *r)
697ec681f3Smrg{
707ec681f3Smrg    struct pipe_resource **vsbuf = &r->vs_const_buffer;
717ec681f3Smrg    struct pipe_resource **fsbuf = &r->fs_const_buffer;
727ec681f3Smrg
737ec681f3Smrg    if (*vsbuf)
747ec681f3Smrg	pipe_resource_reference(vsbuf, NULL);
757ec681f3Smrg
767ec681f3Smrg    if (*fsbuf)
777ec681f3Smrg	pipe_resource_reference(fsbuf, NULL);
787ec681f3Smrg
797ec681f3Smrg    if (r->shaders) {
807ec681f3Smrg	xa_shaders_destroy(r->shaders);
817ec681f3Smrg	r->shaders = NULL;
827ec681f3Smrg    }
837ec681f3Smrg
847ec681f3Smrg    xa_ctx_sampler_views_destroy(r);
857ec681f3Smrg    if (r->srf)
867ec681f3Smrg        pipe_surface_reference(&r->srf, NULL);
877ec681f3Smrg
887ec681f3Smrg    if (r->cso) {
897ec681f3Smrg	cso_destroy_context(r->cso);
907ec681f3Smrg	r->cso = NULL;
917ec681f3Smrg    }
927ec681f3Smrg
937ec681f3Smrg    r->pipe->destroy(r->pipe);
947ec681f3Smrg    free(r);
957ec681f3Smrg}
967ec681f3Smrg
977ec681f3SmrgXA_EXPORT int
987ec681f3Smrgxa_surface_dma(struct xa_context *ctx,
997ec681f3Smrg	       struct xa_surface *srf,
1007ec681f3Smrg	       void *data,
1017ec681f3Smrg	       unsigned int pitch,
1027ec681f3Smrg	       int to_surface, struct xa_box *boxes, unsigned int num_boxes)
1037ec681f3Smrg{
1047ec681f3Smrg    struct pipe_transfer *transfer;
1057ec681f3Smrg    void *map;
1067ec681f3Smrg    int w, h, i;
1077ec681f3Smrg    enum pipe_map_flags transfer_direction;
1087ec681f3Smrg    struct pipe_context *pipe = ctx->pipe;
1097ec681f3Smrg
1107ec681f3Smrg    transfer_direction = (to_surface ? PIPE_MAP_WRITE :
1117ec681f3Smrg			  PIPE_MAP_READ);
1127ec681f3Smrg
1137ec681f3Smrg    for (i = 0; i < num_boxes; ++i, ++boxes) {
1147ec681f3Smrg	w = boxes->x2 - boxes->x1;
1157ec681f3Smrg	h = boxes->y2 - boxes->y1;
1167ec681f3Smrg
1177ec681f3Smrg	map = pipe_texture_map(pipe, srf->tex, 0, 0,
1187ec681f3Smrg                                transfer_direction, boxes->x1, boxes->y1,
1197ec681f3Smrg                                w, h, &transfer);
1207ec681f3Smrg	if (!map)
1217ec681f3Smrg	    return -XA_ERR_NORES;
1227ec681f3Smrg
1237ec681f3Smrg	if (to_surface) {
1247ec681f3Smrg	    util_copy_rect(map, srf->tex->format, transfer->stride,
1257ec681f3Smrg			   0, 0, w, h, data, pitch, boxes->x1, boxes->y1);
1267ec681f3Smrg	} else {
1277ec681f3Smrg	    util_copy_rect(data, srf->tex->format, pitch,
1287ec681f3Smrg			   boxes->x1, boxes->y1, w, h, map, transfer->stride, 0,
1297ec681f3Smrg			   0);
1307ec681f3Smrg	}
1317ec681f3Smrg	pipe->texture_unmap(pipe, transfer);
1327ec681f3Smrg    }
1337ec681f3Smrg    return XA_ERR_NONE;
1347ec681f3Smrg}
1357ec681f3Smrg
1367ec681f3SmrgXA_EXPORT void *
1377ec681f3Smrgxa_surface_map(struct xa_context *ctx,
1387ec681f3Smrg	       struct xa_surface *srf, unsigned int usage)
1397ec681f3Smrg{
1407ec681f3Smrg    void *map;
1417ec681f3Smrg    unsigned int gallium_usage = 0;
1427ec681f3Smrg    struct pipe_context *pipe = ctx->pipe;
1437ec681f3Smrg
1447ec681f3Smrg    /*
1457ec681f3Smrg     * A surface may only have a single map.
1467ec681f3Smrg     */
1477ec681f3Smrg    if (srf->transfer)
1487ec681f3Smrg	return NULL;
1497ec681f3Smrg
1507ec681f3Smrg    if (usage & XA_MAP_READ)
1517ec681f3Smrg	gallium_usage |= PIPE_MAP_READ;
1527ec681f3Smrg    if (usage & XA_MAP_WRITE)
1537ec681f3Smrg	gallium_usage |= PIPE_MAP_WRITE;
1547ec681f3Smrg    if (usage & XA_MAP_MAP_DIRECTLY)
1557ec681f3Smrg	gallium_usage |= PIPE_MAP_DIRECTLY;
1567ec681f3Smrg    if (usage & XA_MAP_UNSYNCHRONIZED)
1577ec681f3Smrg	gallium_usage |= PIPE_MAP_UNSYNCHRONIZED;
1587ec681f3Smrg    if (usage & XA_MAP_DONTBLOCK)
1597ec681f3Smrg	gallium_usage |= PIPE_MAP_DONTBLOCK;
1607ec681f3Smrg    if (usage & XA_MAP_DISCARD_WHOLE_RESOURCE)
1617ec681f3Smrg	gallium_usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
1627ec681f3Smrg
1637ec681f3Smrg    if (!(gallium_usage & (PIPE_MAP_READ_WRITE)))
1647ec681f3Smrg	return NULL;
1657ec681f3Smrg
1667ec681f3Smrg    map = pipe_texture_map(pipe, srf->tex, 0, 0,
1677ec681f3Smrg                            gallium_usage, 0, 0,
1687ec681f3Smrg                            srf->tex->width0, srf->tex->height0,
1697ec681f3Smrg                            &srf->transfer);
1707ec681f3Smrg    if (!map)
1717ec681f3Smrg	return NULL;
1727ec681f3Smrg
1737ec681f3Smrg    srf->mapping_pipe = pipe;
1747ec681f3Smrg    return map;
1757ec681f3Smrg}
1767ec681f3Smrg
1777ec681f3SmrgXA_EXPORT void
1787ec681f3Smrgxa_surface_unmap(struct xa_surface *srf)
1797ec681f3Smrg{
1807ec681f3Smrg    if (srf->transfer) {
1817ec681f3Smrg	struct pipe_context *pipe = srf->mapping_pipe;
1827ec681f3Smrg
1837ec681f3Smrg	pipe->texture_unmap(pipe, srf->transfer);
1847ec681f3Smrg	srf->transfer = NULL;
1857ec681f3Smrg    }
1867ec681f3Smrg}
1877ec681f3Smrg
1887ec681f3Smrgint
1897ec681f3Smrgxa_ctx_srf_create(struct xa_context *ctx, struct xa_surface *dst)
1907ec681f3Smrg{
1917ec681f3Smrg    struct pipe_screen *screen = ctx->pipe->screen;
1927ec681f3Smrg    struct pipe_surface srf_templ;
1937ec681f3Smrg
1947ec681f3Smrg    /*
1957ec681f3Smrg     * Cache surfaces unless we change render target
1967ec681f3Smrg     */
1977ec681f3Smrg    if (ctx->srf) {
1987ec681f3Smrg        if (ctx->srf->texture == dst->tex)
1997ec681f3Smrg            return XA_ERR_NONE;
2007ec681f3Smrg
2017ec681f3Smrg        pipe_surface_reference(&ctx->srf, NULL);
2027ec681f3Smrg    }
2037ec681f3Smrg
2047ec681f3Smrg    if (!screen->is_format_supported(screen,  dst->tex->format,
2057ec681f3Smrg				     PIPE_TEXTURE_2D, 0, 0,
2067ec681f3Smrg				     PIPE_BIND_RENDER_TARGET))
2077ec681f3Smrg	return -XA_ERR_INVAL;
2087ec681f3Smrg
2097ec681f3Smrg    u_surface_default_template(&srf_templ, dst->tex);
2107ec681f3Smrg    ctx->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ);
2117ec681f3Smrg    if (!ctx->srf)
2127ec681f3Smrg	return -XA_ERR_NORES;
2137ec681f3Smrg
2147ec681f3Smrg    return XA_ERR_NONE;
2157ec681f3Smrg}
2167ec681f3Smrg
2177ec681f3Smrgvoid
2187ec681f3Smrgxa_ctx_srf_destroy(struct xa_context *ctx)
2197ec681f3Smrg{
2207ec681f3Smrg    /*
2217ec681f3Smrg     * Cache surfaces unless we change render target.
2227ec681f3Smrg     * Final destruction on context destroy.
2237ec681f3Smrg     */
2247ec681f3Smrg}
2257ec681f3Smrg
2267ec681f3SmrgXA_EXPORT int
2277ec681f3Smrgxa_copy_prepare(struct xa_context *ctx,
2287ec681f3Smrg		struct xa_surface *dst, struct xa_surface *src)
2297ec681f3Smrg{
2307ec681f3Smrg    if (src == dst)
2317ec681f3Smrg	return -XA_ERR_INVAL;
2327ec681f3Smrg
2337ec681f3Smrg    if (src->tex->format != dst->tex->format) {
2347ec681f3Smrg	int ret = xa_ctx_srf_create(ctx, dst);
2357ec681f3Smrg	if (ret != XA_ERR_NONE)
2367ec681f3Smrg	    return ret;
2377ec681f3Smrg	renderer_copy_prepare(ctx, ctx->srf, src->tex,
2387ec681f3Smrg			      src->fdesc.xa_format,
2397ec681f3Smrg			      dst->fdesc.xa_format);
2407ec681f3Smrg	ctx->simple_copy = 0;
2417ec681f3Smrg    } else
2427ec681f3Smrg	ctx->simple_copy = 1;
2437ec681f3Smrg
2447ec681f3Smrg    ctx->src = src;
2457ec681f3Smrg    ctx->dst = dst;
2467ec681f3Smrg    xa_ctx_srf_destroy(ctx);
2477ec681f3Smrg
2487ec681f3Smrg    return 0;
2497ec681f3Smrg}
2507ec681f3Smrg
2517ec681f3SmrgXA_EXPORT void
2527ec681f3Smrgxa_copy(struct xa_context *ctx,
2537ec681f3Smrg	int dx, int dy, int sx, int sy, int width, int height)
2547ec681f3Smrg{
2557ec681f3Smrg    struct pipe_box src_box;
2567ec681f3Smrg
2577ec681f3Smrg    xa_scissor_update(ctx, dx, dy, dx + width, dy + height);
2587ec681f3Smrg
2597ec681f3Smrg    if (ctx->simple_copy) {
2607ec681f3Smrg	u_box_2d(sx, sy, width, height, &src_box);
2617ec681f3Smrg	ctx->pipe->resource_copy_region(ctx->pipe,
2627ec681f3Smrg					ctx->dst->tex, 0, dx, dy, 0,
2637ec681f3Smrg					ctx->src->tex,
2647ec681f3Smrg					0, &src_box);
2657ec681f3Smrg    } else
2667ec681f3Smrg	renderer_copy(ctx, dx, dy, sx, sy, width, height,
2677ec681f3Smrg		      (float) ctx->src->tex->width0,
2687ec681f3Smrg		      (float) ctx->src->tex->height0);
2697ec681f3Smrg}
2707ec681f3Smrg
2717ec681f3SmrgXA_EXPORT void
2727ec681f3Smrgxa_copy_done(struct xa_context *ctx)
2737ec681f3Smrg{
2747ec681f3Smrg    if (!ctx->simple_copy) {
2757ec681f3Smrg	renderer_draw_flush(ctx);
2767ec681f3Smrg    }
2777ec681f3Smrg}
2787ec681f3Smrg
2797ec681f3Smrgstatic void
2807ec681f3Smrgbind_solid_blend_state(struct xa_context *ctx)
2817ec681f3Smrg{
2827ec681f3Smrg    struct pipe_blend_state blend;
2837ec681f3Smrg
2847ec681f3Smrg    memset(&blend, 0, sizeof(struct pipe_blend_state));
2857ec681f3Smrg    blend.rt[0].blend_enable = 0;
2867ec681f3Smrg    blend.rt[0].colormask = PIPE_MASK_RGBA;
2877ec681f3Smrg
2887ec681f3Smrg    blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
2897ec681f3Smrg    blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
2907ec681f3Smrg    blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
2917ec681f3Smrg    blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
2927ec681f3Smrg
2937ec681f3Smrg    cso_set_blend(ctx->cso, &blend);
2947ec681f3Smrg}
2957ec681f3Smrg
2967ec681f3SmrgXA_EXPORT int
2977ec681f3Smrgxa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
2987ec681f3Smrg		 uint32_t fg)
2997ec681f3Smrg{
3007ec681f3Smrg    unsigned vs_traits, fs_traits;
3017ec681f3Smrg    struct xa_shader shader;
3027ec681f3Smrg    int ret;
3037ec681f3Smrg
3047ec681f3Smrg    ret = xa_ctx_srf_create(ctx, dst);
3057ec681f3Smrg    if (ret != XA_ERR_NONE)
3067ec681f3Smrg	return ret;
3077ec681f3Smrg
3087ec681f3Smrg    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
3097ec681f3Smrg	xa_pixel_to_float4_a8(fg, ctx->solid_color);
3107ec681f3Smrg    else
3117ec681f3Smrg	xa_pixel_to_float4(fg, ctx->solid_color);
3127ec681f3Smrg    ctx->has_solid_src = 1;
3137ec681f3Smrg
3147ec681f3Smrg    ctx->dst = dst;
3157ec681f3Smrg
3167ec681f3Smrg#if 0
3177ec681f3Smrg    debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
3187ec681f3Smrg		 (fg >> 24) & 0xff, (fg >> 16) & 0xff,
3197ec681f3Smrg		 (fg >> 8) & 0xff,  (fg >> 0) & 0xff,
3207ec681f3Smrg		 exa->solid_color[0], exa->solid_color[1],
3217ec681f3Smrg		 exa->solid_color[2], exa->solid_color[3]);
3227ec681f3Smrg#endif
3237ec681f3Smrg
3247ec681f3Smrg    vs_traits = VS_SRC_SRC | VS_COMPOSITE;
3257ec681f3Smrg    fs_traits = FS_SRC_SRC | VS_COMPOSITE;
3267ec681f3Smrg
3277ec681f3Smrg    renderer_bind_destination(ctx, ctx->srf);
3287ec681f3Smrg    bind_solid_blend_state(ctx);
3297ec681f3Smrg    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
3307ec681f3Smrg    ctx->pipe->set_sampler_views(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, 0,
3317ec681f3Smrg                                 XA_MAX_SAMPLERS, false, NULL);
3327ec681f3Smrg
3337ec681f3Smrg    shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
3347ec681f3Smrg    cso_set_vertex_shader_handle(ctx->cso, shader.vs);
3357ec681f3Smrg    cso_set_fragment_shader_handle(ctx->cso, shader.fs);
3367ec681f3Smrg
3377ec681f3Smrg    renderer_begin_solid(ctx);
3387ec681f3Smrg
3397ec681f3Smrg    xa_ctx_srf_destroy(ctx);
3407ec681f3Smrg    return XA_ERR_NONE;
3417ec681f3Smrg}
3427ec681f3Smrg
3437ec681f3SmrgXA_EXPORT void
3447ec681f3Smrgxa_solid(struct xa_context *ctx, int x, int y, int width, int height)
3457ec681f3Smrg{
3467ec681f3Smrg    xa_scissor_update(ctx, x, y, x + width, y + height);
3477ec681f3Smrg    renderer_solid(ctx, x, y, x + width, y + height);
3487ec681f3Smrg}
3497ec681f3Smrg
3507ec681f3SmrgXA_EXPORT void
3517ec681f3Smrgxa_solid_done(struct xa_context *ctx)
3527ec681f3Smrg{
3537ec681f3Smrg    renderer_draw_flush(ctx);
3547ec681f3Smrg    ctx->comp = NULL;
3557ec681f3Smrg    ctx->has_solid_src = FALSE;
3567ec681f3Smrg    ctx->num_bound_samplers = 0;
3577ec681f3Smrg}
3587ec681f3Smrg
3597ec681f3SmrgXA_EXPORT struct xa_fence *
3607ec681f3Smrgxa_fence_get(struct xa_context *ctx)
3617ec681f3Smrg{
3627ec681f3Smrg    struct xa_fence *fence = calloc(1, sizeof(*fence));
3637ec681f3Smrg    struct pipe_screen *screen = ctx->xa->screen;
3647ec681f3Smrg
3657ec681f3Smrg    if (!fence)
3667ec681f3Smrg	return NULL;
3677ec681f3Smrg
3687ec681f3Smrg    fence->xa = ctx->xa;
3697ec681f3Smrg
3707ec681f3Smrg    if (ctx->last_fence == NULL)
3717ec681f3Smrg	fence->pipe_fence = NULL;
3727ec681f3Smrg    else
3737ec681f3Smrg	screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence);
3747ec681f3Smrg
3757ec681f3Smrg    return fence;
3767ec681f3Smrg}
3777ec681f3Smrg
3787ec681f3SmrgXA_EXPORT int
3797ec681f3Smrgxa_fence_wait(struct xa_fence *fence, uint64_t timeout)
3807ec681f3Smrg{
3817ec681f3Smrg    if (!fence)
3827ec681f3Smrg	return XA_ERR_NONE;
3837ec681f3Smrg
3847ec681f3Smrg    if (fence->pipe_fence) {
3857ec681f3Smrg	struct pipe_screen *screen = fence->xa->screen;
3867ec681f3Smrg	boolean timed_out;
3877ec681f3Smrg
3887ec681f3Smrg	timed_out = !screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
3897ec681f3Smrg	if (timed_out)
3907ec681f3Smrg	    return -XA_ERR_BUSY;
3917ec681f3Smrg
3927ec681f3Smrg	screen->fence_reference(screen, &fence->pipe_fence, NULL);
3937ec681f3Smrg    }
3947ec681f3Smrg    return XA_ERR_NONE;
3957ec681f3Smrg}
3967ec681f3Smrg
3977ec681f3SmrgXA_EXPORT void
3987ec681f3Smrgxa_fence_destroy(struct xa_fence *fence)
3997ec681f3Smrg{
4007ec681f3Smrg    if (!fence)
4017ec681f3Smrg	return;
4027ec681f3Smrg
4037ec681f3Smrg    if (fence->pipe_fence) {
4047ec681f3Smrg	struct pipe_screen *screen = fence->xa->screen;
4057ec681f3Smrg
4067ec681f3Smrg	screen->fence_reference(screen, &fence->pipe_fence, NULL);
4077ec681f3Smrg    }
4087ec681f3Smrg
4097ec681f3Smrg    free(fence);
4107ec681f3Smrg}
4117ec681f3Smrg
4127ec681f3Smrgvoid
4137ec681f3Smrgxa_ctx_sampler_views_destroy(struct xa_context *ctx)
4147ec681f3Smrg{
4157ec681f3Smrg    int i;
4167ec681f3Smrg
4177ec681f3Smrg    for (i = 0; i < ctx->num_bound_samplers; ++i)
4187ec681f3Smrg	pipe_sampler_view_reference(&ctx->bound_sampler_views[i], NULL);
4197ec681f3Smrg    ctx->num_bound_samplers = 0;
4207ec681f3Smrg}
421