Path: blob/21.2-virgl/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
4573 views
/**********************************************************1* Copyright 2010 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**********************************************************/242526#include "wrapper_sw_winsys.h"2728#include "pipe/p_format.h"29#include "pipe/p_state.h"3031#include "frontend/sw_winsys.h"3233#include "util/u_memory.h"34#include "util/u_inlines.h"3536/*37* This code wraps a pipe_screen and exposes a sw_winsys interface for use38* with software resterizers. This code is used by the DRM based winsys to39* allow access to the drm driver.40*41* We must borrow the whole stack because only the pipe screen knows how42* to decode the content of a buffer. Or how to create a buffer that43* can still be used by drivers using real hardware (as the case is44* with software st/xorg but hw st/dri).45*46* We also need a pipe context for the transfers.47*/4849struct wrapper_sw_winsys50{51struct sw_winsys base;52struct pipe_screen *screen;53struct pipe_context *pipe;54enum pipe_texture_target target;55};5657struct wrapper_sw_displaytarget58{59struct wrapper_sw_winsys *winsys;60struct pipe_resource *tex;61struct pipe_transfer *transfer;6263unsigned map_count;64unsigned stride; /**< because we get stride at create */65void *ptr;66};6768static inline struct wrapper_sw_winsys *69wrapper_sw_winsys(struct sw_winsys *ws)70{71return (struct wrapper_sw_winsys *)ws;72}7374static inline struct wrapper_sw_displaytarget *75wrapper_sw_displaytarget(struct sw_displaytarget *dt)76{77return (struct wrapper_sw_displaytarget *)dt;78}798081/*82* Functions83*/848586static bool87wsw_is_dt_format_supported(struct sw_winsys *ws,88unsigned tex_usage,89enum pipe_format format)90{91struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);9293return wsw->screen->is_format_supported(wsw->screen, format,94PIPE_TEXTURE_2D, 0, 0,95PIPE_BIND_RENDER_TARGET |96PIPE_BIND_DISPLAY_TARGET);97}9899static bool100wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)101{102struct pipe_context *pipe = wdt->winsys->pipe;103struct pipe_resource *tex = wdt->tex;104struct pipe_transfer *tr;105void *map;106107map = pipe_texture_map(pipe, tex, 0, 0,108PIPE_MAP_READ_WRITE,1090, 0, wdt->tex->width0, wdt->tex->height0, &tr);110if (!map)111return false;112113*stride = tr->stride;114wdt->stride = tr->stride;115116pipe->texture_unmap(pipe, tr);117118return true;119}120121static struct sw_displaytarget *122wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw,123struct pipe_resource *tex, unsigned *stride)124{125struct wrapper_sw_displaytarget *wdt = CALLOC_STRUCT(wrapper_sw_displaytarget);126if (!wdt)127goto err_unref;128129wdt->tex = tex;130wdt->winsys = wsw;131132if (!wsw_dt_get_stride(wdt, stride))133goto err_free;134135return (struct sw_displaytarget *)wdt;136137err_free:138FREE(wdt);139err_unref:140pipe_resource_reference(&tex, NULL);141return NULL;142}143144static struct sw_displaytarget *145wsw_dt_create(struct sw_winsys *ws,146unsigned bind,147enum pipe_format format,148unsigned width, unsigned height,149unsigned alignment,150const void *front_private,151unsigned *stride)152{153struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);154struct pipe_resource templ;155struct pipe_resource *tex;156157/*158* XXX Why don't we just get the template.159*/160memset(&templ, 0, sizeof(templ));161templ.target = wsw->target;162templ.width0 = width;163templ.height0 = height;164templ.depth0 = 1;165templ.array_size = 1;166templ.format = format;167templ.bind = bind;168169/* XXX alignment: we can't do anything about this */170171tex = wsw->screen->resource_create(wsw->screen, &templ);172if (!tex)173return NULL;174175return wsw_dt_wrap_texture(wsw, tex, stride);176}177178static struct sw_displaytarget *179wsw_dt_from_handle(struct sw_winsys *ws,180const struct pipe_resource *templ,181struct winsys_handle *whandle,182unsigned *stride)183{184struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);185struct pipe_resource *tex;186187tex = wsw->screen->resource_from_handle(wsw->screen, templ, whandle,188PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);189if (!tex)190return NULL;191192return wsw_dt_wrap_texture(wsw, tex, stride);193}194195static bool196wsw_dt_get_handle(struct sw_winsys *ws,197struct sw_displaytarget *dt,198struct winsys_handle *whandle)199{200struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);201struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);202struct pipe_resource *tex = wdt->tex;203204return wsw->screen->resource_get_handle(wsw->screen, NULL, tex, whandle,205PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);206}207208static void *209wsw_dt_map(struct sw_winsys *ws,210struct sw_displaytarget *dt,211unsigned flags)212{213struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);214struct pipe_context *pipe = wdt->winsys->pipe;215struct pipe_resource *tex = wdt->tex;216struct pipe_transfer *tr;217void *ptr;218219if (!wdt->map_count) {220221assert(!wdt->transfer);222223ptr = pipe_texture_map(pipe, tex, 0, 0,224PIPE_MAP_READ_WRITE,2250, 0, wdt->tex->width0, wdt->tex->height0, &tr);226if (!ptr)227goto err;228229wdt->transfer = tr;230wdt->ptr = ptr;231232/* XXX Handle this case */233assert(tr->stride == wdt->stride);234}235236wdt->map_count++;237238return wdt->ptr;239240err:241pipe->texture_unmap(pipe, tr);242return NULL;243}244245static void246wsw_dt_unmap(struct sw_winsys *ws,247struct sw_displaytarget *dt)248{249struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);250struct pipe_context *pipe = wdt->winsys->pipe;251252assert(wdt->transfer);253254wdt->map_count--;255256if (wdt->map_count)257return;258259pipe->texture_unmap(pipe, wdt->transfer);260pipe->flush(pipe, NULL, 0);261wdt->transfer = NULL;262}263264static void265wsw_dt_destroy(struct sw_winsys *ws,266struct sw_displaytarget *dt)267{268struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);269270pipe_resource_reference(&wdt->tex, NULL);271272FREE(wdt);273}274275static void276wsw_destroy(struct sw_winsys *ws)277{278struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);279280wsw->pipe->destroy(wsw->pipe);281wsw->screen->destroy(wsw->screen);282283FREE(wsw);284}285286struct sw_winsys *287wrapper_sw_winsys_wrap_pipe_screen(struct pipe_screen *screen)288{289struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys);290291if (!wsw)292goto err;293294wsw->base.is_displaytarget_format_supported = wsw_is_dt_format_supported;295wsw->base.displaytarget_create = wsw_dt_create;296wsw->base.displaytarget_from_handle = wsw_dt_from_handle;297wsw->base.displaytarget_get_handle = wsw_dt_get_handle;298wsw->base.displaytarget_map = wsw_dt_map;299wsw->base.displaytarget_unmap = wsw_dt_unmap;300wsw->base.displaytarget_destroy = wsw_dt_destroy;301wsw->base.destroy = wsw_destroy;302303wsw->screen = screen;304wsw->pipe = screen->context_create(screen, NULL, 0);305if (!wsw->pipe)306goto err_free;307308if(screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES))309wsw->target = PIPE_TEXTURE_2D;310else311wsw->target = PIPE_TEXTURE_RECT;312313return &wsw->base;314315err_free:316FREE(wsw);317err:318return NULL;319}320321struct pipe_screen *322wrapper_sw_winsys_dewrap_pipe_screen(struct sw_winsys *ws)323{324struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);325struct pipe_screen *screen = wsw->screen;326327wsw->pipe->destroy(wsw->pipe);328/* don't destroy the screen its needed later on */329330FREE(wsw);331return screen;332}333334335