Path: blob/21.2-virgl/src/gallium/frontends/xa/xa_context.c
4561 views
/**********************************************************1* Copyright 2009-2011 VMware, Inc. All rights reserved.2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation5* files (the "Software"), to deal in the Software without6* restriction, including without limitation the rights to use, copy,7* modify, merge, publish, distribute, sublicense, and/or sell copies8* of the Software, and to permit persons to whom the Software is9* furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23*********************************************************24* Authors:25* Zack Rusin <zackr-at-vmware-dot-com>26* Thomas Hellstrom <thellstrom-at-vmware-dot-com>27*/28#include "xa_context.h"29#include "xa_priv.h"30#include "cso_cache/cso_context.h"31#include "util/u_inlines.h"32#include "util/u_rect.h"33#include "util/u_surface.h"34#include "pipe/p_context.h"3536XA_EXPORT void37xa_context_flush(struct xa_context *ctx)38{39if (ctx->last_fence) {40struct pipe_screen *screen = ctx->xa->screen;41screen->fence_reference(screen, &ctx->last_fence, NULL);42}43ctx->pipe->flush(ctx->pipe, &ctx->last_fence, 0);44}4546XA_EXPORT struct xa_context *47xa_context_default(struct xa_tracker *xa)48{49return xa->default_ctx;50}5152XA_EXPORT struct xa_context *53xa_context_create(struct xa_tracker *xa)54{55struct xa_context *ctx = calloc(1, sizeof(*ctx));5657ctx->xa = xa;58ctx->pipe = xa->screen->context_create(xa->screen, NULL, 0);59ctx->cso = cso_create_context(ctx->pipe, 0);60ctx->shaders = xa_shaders_create(ctx);61renderer_init_state(ctx);6263return ctx;64}6566XA_EXPORT void67xa_context_destroy(struct xa_context *r)68{69struct pipe_resource **vsbuf = &r->vs_const_buffer;70struct pipe_resource **fsbuf = &r->fs_const_buffer;7172if (*vsbuf)73pipe_resource_reference(vsbuf, NULL);7475if (*fsbuf)76pipe_resource_reference(fsbuf, NULL);7778if (r->shaders) {79xa_shaders_destroy(r->shaders);80r->shaders = NULL;81}8283xa_ctx_sampler_views_destroy(r);84if (r->srf)85pipe_surface_reference(&r->srf, NULL);8687if (r->cso) {88cso_destroy_context(r->cso);89r->cso = NULL;90}9192r->pipe->destroy(r->pipe);93free(r);94}9596XA_EXPORT int97xa_surface_dma(struct xa_context *ctx,98struct xa_surface *srf,99void *data,100unsigned int pitch,101int to_surface, struct xa_box *boxes, unsigned int num_boxes)102{103struct pipe_transfer *transfer;104void *map;105int w, h, i;106enum pipe_map_flags transfer_direction;107struct pipe_context *pipe = ctx->pipe;108109transfer_direction = (to_surface ? PIPE_MAP_WRITE :110PIPE_MAP_READ);111112for (i = 0; i < num_boxes; ++i, ++boxes) {113w = boxes->x2 - boxes->x1;114h = boxes->y2 - boxes->y1;115116map = pipe_texture_map(pipe, srf->tex, 0, 0,117transfer_direction, boxes->x1, boxes->y1,118w, h, &transfer);119if (!map)120return -XA_ERR_NORES;121122if (to_surface) {123util_copy_rect(map, srf->tex->format, transfer->stride,1240, 0, w, h, data, pitch, boxes->x1, boxes->y1);125} else {126util_copy_rect(data, srf->tex->format, pitch,127boxes->x1, boxes->y1, w, h, map, transfer->stride, 0,1280);129}130pipe->texture_unmap(pipe, transfer);131}132return XA_ERR_NONE;133}134135XA_EXPORT void *136xa_surface_map(struct xa_context *ctx,137struct xa_surface *srf, unsigned int usage)138{139void *map;140unsigned int gallium_usage = 0;141struct pipe_context *pipe = ctx->pipe;142143/*144* A surface may only have a single map.145*/146if (srf->transfer)147return NULL;148149if (usage & XA_MAP_READ)150gallium_usage |= PIPE_MAP_READ;151if (usage & XA_MAP_WRITE)152gallium_usage |= PIPE_MAP_WRITE;153if (usage & XA_MAP_MAP_DIRECTLY)154gallium_usage |= PIPE_MAP_DIRECTLY;155if (usage & XA_MAP_UNSYNCHRONIZED)156gallium_usage |= PIPE_MAP_UNSYNCHRONIZED;157if (usage & XA_MAP_DONTBLOCK)158gallium_usage |= PIPE_MAP_DONTBLOCK;159if (usage & XA_MAP_DISCARD_WHOLE_RESOURCE)160gallium_usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;161162if (!(gallium_usage & (PIPE_MAP_READ_WRITE)))163return NULL;164165map = pipe_texture_map(pipe, srf->tex, 0, 0,166gallium_usage, 0, 0,167srf->tex->width0, srf->tex->height0,168&srf->transfer);169if (!map)170return NULL;171172srf->mapping_pipe = pipe;173return map;174}175176XA_EXPORT void177xa_surface_unmap(struct xa_surface *srf)178{179if (srf->transfer) {180struct pipe_context *pipe = srf->mapping_pipe;181182pipe->texture_unmap(pipe, srf->transfer);183srf->transfer = NULL;184}185}186187int188xa_ctx_srf_create(struct xa_context *ctx, struct xa_surface *dst)189{190struct pipe_screen *screen = ctx->pipe->screen;191struct pipe_surface srf_templ;192193/*194* Cache surfaces unless we change render target195*/196if (ctx->srf) {197if (ctx->srf->texture == dst->tex)198return XA_ERR_NONE;199200pipe_surface_reference(&ctx->srf, NULL);201}202203if (!screen->is_format_supported(screen, dst->tex->format,204PIPE_TEXTURE_2D, 0, 0,205PIPE_BIND_RENDER_TARGET))206return -XA_ERR_INVAL;207208u_surface_default_template(&srf_templ, dst->tex);209ctx->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ);210if (!ctx->srf)211return -XA_ERR_NORES;212213return XA_ERR_NONE;214}215216void217xa_ctx_srf_destroy(struct xa_context *ctx)218{219/*220* Cache surfaces unless we change render target.221* Final destruction on context destroy.222*/223}224225XA_EXPORT int226xa_copy_prepare(struct xa_context *ctx,227struct xa_surface *dst, struct xa_surface *src)228{229if (src == dst)230return -XA_ERR_INVAL;231232if (src->tex->format != dst->tex->format) {233int ret = xa_ctx_srf_create(ctx, dst);234if (ret != XA_ERR_NONE)235return ret;236renderer_copy_prepare(ctx, ctx->srf, src->tex,237src->fdesc.xa_format,238dst->fdesc.xa_format);239ctx->simple_copy = 0;240} else241ctx->simple_copy = 1;242243ctx->src = src;244ctx->dst = dst;245xa_ctx_srf_destroy(ctx);246247return 0;248}249250XA_EXPORT void251xa_copy(struct xa_context *ctx,252int dx, int dy, int sx, int sy, int width, int height)253{254struct pipe_box src_box;255256xa_scissor_update(ctx, dx, dy, dx + width, dy + height);257258if (ctx->simple_copy) {259u_box_2d(sx, sy, width, height, &src_box);260ctx->pipe->resource_copy_region(ctx->pipe,261ctx->dst->tex, 0, dx, dy, 0,262ctx->src->tex,2630, &src_box);264} else265renderer_copy(ctx, dx, dy, sx, sy, width, height,266(float) ctx->src->tex->width0,267(float) ctx->src->tex->height0);268}269270XA_EXPORT void271xa_copy_done(struct xa_context *ctx)272{273if (!ctx->simple_copy) {274renderer_draw_flush(ctx);275}276}277278static void279bind_solid_blend_state(struct xa_context *ctx)280{281struct pipe_blend_state blend;282283memset(&blend, 0, sizeof(struct pipe_blend_state));284blend.rt[0].blend_enable = 0;285blend.rt[0].colormask = PIPE_MASK_RGBA;286287blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;288blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;289blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;290blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;291292cso_set_blend(ctx->cso, &blend);293}294295XA_EXPORT int296xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,297uint32_t fg)298{299unsigned vs_traits, fs_traits;300struct xa_shader shader;301int ret;302303ret = xa_ctx_srf_create(ctx, dst);304if (ret != XA_ERR_NONE)305return ret;306307if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)308xa_pixel_to_float4_a8(fg, ctx->solid_color);309else310xa_pixel_to_float4(fg, ctx->solid_color);311ctx->has_solid_src = 1;312313ctx->dst = dst;314315#if 0316debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",317(fg >> 24) & 0xff, (fg >> 16) & 0xff,318(fg >> 8) & 0xff, (fg >> 0) & 0xff,319exa->solid_color[0], exa->solid_color[1],320exa->solid_color[2], exa->solid_color[3]);321#endif322323vs_traits = VS_SRC_SRC | VS_COMPOSITE;324fs_traits = FS_SRC_SRC | VS_COMPOSITE;325326renderer_bind_destination(ctx, ctx->srf);327bind_solid_blend_state(ctx);328cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, 0, NULL);329ctx->pipe->set_sampler_views(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, 0, XA_MAX_SAMPLERS, NULL);330331shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);332cso_set_vertex_shader_handle(ctx->cso, shader.vs);333cso_set_fragment_shader_handle(ctx->cso, shader.fs);334335renderer_begin_solid(ctx);336337xa_ctx_srf_destroy(ctx);338return XA_ERR_NONE;339}340341XA_EXPORT void342xa_solid(struct xa_context *ctx, int x, int y, int width, int height)343{344xa_scissor_update(ctx, x, y, x + width, y + height);345renderer_solid(ctx, x, y, x + width, y + height);346}347348XA_EXPORT void349xa_solid_done(struct xa_context *ctx)350{351renderer_draw_flush(ctx);352ctx->comp = NULL;353ctx->has_solid_src = FALSE;354ctx->num_bound_samplers = 0;355}356357XA_EXPORT struct xa_fence *358xa_fence_get(struct xa_context *ctx)359{360struct xa_fence *fence = calloc(1, sizeof(*fence));361struct pipe_screen *screen = ctx->xa->screen;362363if (!fence)364return NULL;365366fence->xa = ctx->xa;367368if (ctx->last_fence == NULL)369fence->pipe_fence = NULL;370else371screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence);372373return fence;374}375376XA_EXPORT int377xa_fence_wait(struct xa_fence *fence, uint64_t timeout)378{379if (!fence)380return XA_ERR_NONE;381382if (fence->pipe_fence) {383struct pipe_screen *screen = fence->xa->screen;384boolean timed_out;385386timed_out = !screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);387if (timed_out)388return -XA_ERR_BUSY;389390screen->fence_reference(screen, &fence->pipe_fence, NULL);391}392return XA_ERR_NONE;393}394395XA_EXPORT void396xa_fence_destroy(struct xa_fence *fence)397{398if (!fence)399return;400401if (fence->pipe_fence) {402struct pipe_screen *screen = fence->xa->screen;403404screen->fence_reference(screen, &fence->pipe_fence, NULL);405}406407free(fence);408}409410void411xa_ctx_sampler_views_destroy(struct xa_context *ctx)412{413int i;414415for (i = 0; i < ctx->num_bound_samplers; ++i)416pipe_sampler_view_reference(&ctx->bound_sampler_views[i], NULL);417ctx->num_bound_samplers = 0;418}419420421