1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2009, VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * Copyright 2010 George Sapountzis <gsapountzis@gmail.com> 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the 9848b8605Smrg * "Software"), to deal in the Software without restriction, including 10848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 11848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 12848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 13848b8605Smrg * the following conditions: 14848b8605Smrg * 15848b8605Smrg * The above copyright notice and this permission notice (including the 16848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 17848b8605Smrg * of the Software. 18848b8605Smrg * 19848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26848b8605Smrg * 27848b8605Smrg **************************************************************************/ 28848b8605Smrg 29848b8605Smrg#include "util/u_format.h" 30848b8605Smrg#include "util/u_memory.h" 31848b8605Smrg#include "util/u_inlines.h" 32848b8605Smrg#include "util/u_box.h" 33848b8605Smrg#include "pipe/p_context.h" 34b8e80941Smrg#include "pipe-loader/pipe_loader.h" 35848b8605Smrg#include "state_tracker/drisw_api.h" 36848b8605Smrg#include "state_tracker/st_context.h" 37848b8605Smrg 38848b8605Smrg#include "dri_screen.h" 39848b8605Smrg#include "dri_context.h" 40848b8605Smrg#include "dri_drawable.h" 41b8e80941Smrg#include "dri_helpers.h" 42848b8605Smrg#include "dri_query_renderer.h" 43848b8605Smrg 44848b8605SmrgDEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT", FALSE); 45848b8605Smrg 46b8e80941Smrgstatic inline void 47848b8605Smrgget_drawable_info(__DRIdrawable *dPriv, int *x, int *y, int *w, int *h) 48848b8605Smrg{ 49848b8605Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 50848b8605Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 51848b8605Smrg 52848b8605Smrg loader->getDrawableInfo(dPriv, 53848b8605Smrg x, y, w, h, 54848b8605Smrg dPriv->loaderPrivate); 55848b8605Smrg} 56848b8605Smrg 57b8e80941Smrgstatic inline void 58848b8605Smrgput_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height) 59848b8605Smrg{ 60848b8605Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 61848b8605Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 62848b8605Smrg 63848b8605Smrg loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, 64848b8605Smrg 0, 0, width, height, 65848b8605Smrg data, dPriv->loaderPrivate); 66848b8605Smrg} 67848b8605Smrg 68b8e80941Smrgstatic inline void 69848b8605Smrgput_image2(__DRIdrawable *dPriv, void *data, int x, int y, 70848b8605Smrg unsigned width, unsigned height, unsigned stride) 71848b8605Smrg{ 72848b8605Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 73848b8605Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 74848b8605Smrg 75848b8605Smrg loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, 76848b8605Smrg x, y, width, height, stride, 77848b8605Smrg data, dPriv->loaderPrivate); 78848b8605Smrg} 79848b8605Smrg 80b8e80941Smrgstatic inline void 81b8e80941Smrgput_image_shm(__DRIdrawable *dPriv, int shmid, char *shmaddr, 82b8e80941Smrg unsigned offset, unsigned offset_x, int x, int y, 83b8e80941Smrg unsigned width, unsigned height, unsigned stride) 84b8e80941Smrg{ 85b8e80941Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 86b8e80941Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 87b8e80941Smrg 88b8e80941Smrg /* if we have the newer interface, don't have to add the offset_x here. */ 89b8e80941Smrg if (loader->base.version > 4 && loader->putImageShm2) 90b8e80941Smrg loader->putImageShm2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, 91b8e80941Smrg x, y, width, height, stride, 92b8e80941Smrg shmid, shmaddr, offset, dPriv->loaderPrivate); 93b8e80941Smrg else 94b8e80941Smrg loader->putImageShm(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, 95b8e80941Smrg x, y, width, height, stride, 96b8e80941Smrg shmid, shmaddr, offset + offset_x, dPriv->loaderPrivate); 97b8e80941Smrg} 98b8e80941Smrg 99b8e80941Smrgstatic inline void 100848b8605Smrgget_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data) 101848b8605Smrg{ 102848b8605Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 103848b8605Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 104848b8605Smrg 105848b8605Smrg loader->getImage(dPriv, 106848b8605Smrg x, y, width, height, 107848b8605Smrg data, dPriv->loaderPrivate); 108848b8605Smrg} 109848b8605Smrg 110b8e80941Smrgstatic inline void 111b8e80941Smrgget_image2(__DRIdrawable *dPriv, int x, int y, int width, int height, int stride, void *data) 112b8e80941Smrg{ 113b8e80941Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 114b8e80941Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 115b8e80941Smrg 116b8e80941Smrg /* getImage2 support is only in version 3 or newer */ 117b8e80941Smrg if (loader->base.version < 3) 118b8e80941Smrg return; 119b8e80941Smrg 120b8e80941Smrg loader->getImage2(dPriv, 121b8e80941Smrg x, y, width, height, stride, 122b8e80941Smrg data, dPriv->loaderPrivate); 123b8e80941Smrg} 124b8e80941Smrg 125b8e80941Smrgstatic inline bool 126b8e80941Smrgget_image_shm(__DRIdrawable *dPriv, int x, int y, int width, int height, 127b8e80941Smrg struct pipe_resource *res) 128b8e80941Smrg{ 129b8e80941Smrg __DRIscreen *sPriv = dPriv->driScreenPriv; 130b8e80941Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 131b8e80941Smrg struct winsys_handle whandle; 132b8e80941Smrg 133b8e80941Smrg whandle.type = WINSYS_HANDLE_TYPE_SHMID; 134b8e80941Smrg 135b8e80941Smrg if (loader->base.version < 4 || !loader->getImageShm) 136b8e80941Smrg return FALSE; 137b8e80941Smrg 138b8e80941Smrg if (!res->screen->resource_get_handle(res->screen, NULL, res, &whandle, PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)) 139b8e80941Smrg return FALSE; 140b8e80941Smrg 141b8e80941Smrg loader->getImageShm(dPriv, x, y, width, height, whandle.handle, dPriv->loaderPrivate); 142b8e80941Smrg return TRUE; 143b8e80941Smrg} 144b8e80941Smrg 145848b8605Smrgstatic void 146848b8605Smrgdrisw_update_drawable_info(struct dri_drawable *drawable) 147848b8605Smrg{ 148848b8605Smrg __DRIdrawable *dPriv = drawable->dPriv; 149848b8605Smrg int x, y; 150848b8605Smrg 151848b8605Smrg get_drawable_info(dPriv, &x, &y, &dPriv->w, &dPriv->h); 152848b8605Smrg} 153848b8605Smrg 154b8e80941Smrgstatic void 155b8e80941Smrgdrisw_get_image(struct dri_drawable *drawable, 156b8e80941Smrg int x, int y, unsigned width, unsigned height, unsigned stride, 157b8e80941Smrg void *data) 158b8e80941Smrg{ 159b8e80941Smrg __DRIdrawable *dPriv = drawable->dPriv; 160b8e80941Smrg int draw_x, draw_y, draw_w, draw_h; 161b8e80941Smrg 162b8e80941Smrg get_drawable_info(dPriv, &draw_x, &draw_y, &draw_w, &draw_h); 163b8e80941Smrg get_image2(dPriv, x, y, draw_w, draw_h, stride, data); 164b8e80941Smrg} 165b8e80941Smrg 166848b8605Smrgstatic void 167848b8605Smrgdrisw_put_image(struct dri_drawable *drawable, 168848b8605Smrg void *data, unsigned width, unsigned height) 169848b8605Smrg{ 170848b8605Smrg __DRIdrawable *dPriv = drawable->dPriv; 171848b8605Smrg 172848b8605Smrg put_image(dPriv, data, width, height); 173848b8605Smrg} 174848b8605Smrg 175848b8605Smrgstatic void 176848b8605Smrgdrisw_put_image2(struct dri_drawable *drawable, 177848b8605Smrg void *data, int x, int y, unsigned width, unsigned height, 178848b8605Smrg unsigned stride) 179848b8605Smrg{ 180848b8605Smrg __DRIdrawable *dPriv = drawable->dPriv; 181848b8605Smrg 182848b8605Smrg put_image2(dPriv, data, x, y, width, height, stride); 183848b8605Smrg} 184848b8605Smrg 185b8e80941Smrgstatic inline void 186b8e80941Smrgdrisw_put_image_shm(struct dri_drawable *drawable, 187b8e80941Smrg int shmid, char *shmaddr, unsigned offset, 188b8e80941Smrg unsigned offset_x, 189b8e80941Smrg int x, int y, unsigned width, unsigned height, 190b8e80941Smrg unsigned stride) 191b8e80941Smrg{ 192b8e80941Smrg __DRIdrawable *dPriv = drawable->dPriv; 193b8e80941Smrg 194b8e80941Smrg put_image_shm(dPriv, shmid, shmaddr, offset, offset_x, x, y, width, height, stride); 195b8e80941Smrg} 196b8e80941Smrg 197b8e80941Smrgstatic inline void 198848b8605Smrgdrisw_present_texture(__DRIdrawable *dPriv, 199848b8605Smrg struct pipe_resource *ptex, struct pipe_box *sub_box) 200848b8605Smrg{ 201848b8605Smrg struct dri_drawable *drawable = dri_drawable(dPriv); 202848b8605Smrg struct dri_screen *screen = dri_screen(drawable->sPriv); 203848b8605Smrg 204b8e80941Smrg if (screen->swrast_no_present) 205848b8605Smrg return; 206848b8605Smrg 207848b8605Smrg screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable, sub_box); 208848b8605Smrg} 209848b8605Smrg 210b8e80941Smrgstatic inline void 211848b8605Smrgdrisw_invalidate_drawable(__DRIdrawable *dPriv) 212848b8605Smrg{ 213848b8605Smrg struct dri_drawable *drawable = dri_drawable(dPriv); 214848b8605Smrg 215848b8605Smrg drawable->texture_stamp = dPriv->lastStamp - 1; 216848b8605Smrg 217848b8605Smrg p_atomic_inc(&drawable->base.stamp); 218848b8605Smrg} 219848b8605Smrg 220b8e80941Smrgstatic inline void 221848b8605Smrgdrisw_copy_to_front(__DRIdrawable * dPriv, 222848b8605Smrg struct pipe_resource *ptex) 223848b8605Smrg{ 224848b8605Smrg drisw_present_texture(dPriv, ptex, NULL); 225848b8605Smrg 226848b8605Smrg drisw_invalidate_drawable(dPriv); 227848b8605Smrg} 228848b8605Smrg 229848b8605Smrg/* 230848b8605Smrg * Backend functions for st_framebuffer interface and swap_buffers. 231848b8605Smrg */ 232848b8605Smrg 233848b8605Smrgstatic void 234848b8605Smrgdrisw_swap_buffers(__DRIdrawable *dPriv) 235848b8605Smrg{ 236848b8605Smrg struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); 237848b8605Smrg struct dri_drawable *drawable = dri_drawable(dPriv); 238848b8605Smrg struct pipe_resource *ptex; 239848b8605Smrg 240848b8605Smrg if (!ctx) 241848b8605Smrg return; 242848b8605Smrg 243848b8605Smrg ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 244848b8605Smrg 245848b8605Smrg if (ptex) { 246b8e80941Smrg if (ctx->pp) 247848b8605Smrg pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]); 248848b8605Smrg 249848b8605Smrg ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); 250848b8605Smrg 251848b8605Smrg drisw_copy_to_front(dPriv, ptex); 252848b8605Smrg } 253848b8605Smrg} 254848b8605Smrg 255848b8605Smrgstatic void 256848b8605Smrgdrisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y, 257848b8605Smrg int w, int h) 258848b8605Smrg{ 259848b8605Smrg struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); 260848b8605Smrg struct dri_drawable *drawable = dri_drawable(dPriv); 261848b8605Smrg struct pipe_resource *ptex; 262848b8605Smrg struct pipe_box box; 263848b8605Smrg if (!ctx) 264848b8605Smrg return; 265848b8605Smrg 266848b8605Smrg ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; 267848b8605Smrg 268848b8605Smrg if (ptex) { 269848b8605Smrg if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]) 270848b8605Smrg pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]); 271848b8605Smrg 272848b8605Smrg ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); 273848b8605Smrg 274848b8605Smrg u_box_2d(x, dPriv->h - y - h, w, h, &box); 275848b8605Smrg drisw_present_texture(dPriv, ptex, &box); 276848b8605Smrg } 277848b8605Smrg} 278848b8605Smrg 279848b8605Smrgstatic void 280848b8605Smrgdrisw_flush_frontbuffer(struct dri_context *ctx, 281848b8605Smrg struct dri_drawable *drawable, 282848b8605Smrg enum st_attachment_type statt) 283848b8605Smrg{ 284848b8605Smrg struct pipe_resource *ptex; 285848b8605Smrg 286848b8605Smrg if (!ctx) 287848b8605Smrg return; 288848b8605Smrg 289848b8605Smrg ptex = drawable->textures[statt]; 290848b8605Smrg 291848b8605Smrg if (ptex) { 292848b8605Smrg drisw_copy_to_front(ctx->dPriv, ptex); 293848b8605Smrg } 294848b8605Smrg} 295848b8605Smrg 296848b8605Smrg/** 297848b8605Smrg * Allocate framebuffer attachments. 298848b8605Smrg * 299848b8605Smrg * During fixed-size operation, the function keeps allocating new attachments 300848b8605Smrg * as they are requested. Unused attachments are not removed, not until the 301848b8605Smrg * framebuffer is resized or destroyed. 302848b8605Smrg */ 303848b8605Smrgstatic void 304848b8605Smrgdrisw_allocate_textures(struct dri_context *stctx, 305848b8605Smrg struct dri_drawable *drawable, 306848b8605Smrg const enum st_attachment_type *statts, 307848b8605Smrg unsigned count) 308848b8605Smrg{ 309848b8605Smrg struct dri_screen *screen = dri_screen(drawable->sPriv); 310b8e80941Smrg const __DRIswrastLoaderExtension *loader = drawable->dPriv->driScreenPriv->swrast_loader; 311848b8605Smrg struct pipe_resource templ; 312848b8605Smrg unsigned width, height; 313848b8605Smrg boolean resized; 314848b8605Smrg unsigned i; 315848b8605Smrg 316848b8605Smrg width = drawable->dPriv->w; 317848b8605Smrg height = drawable->dPriv->h; 318848b8605Smrg 319848b8605Smrg resized = (drawable->old_w != width || 320848b8605Smrg drawable->old_h != height); 321848b8605Smrg 322848b8605Smrg /* remove outdated textures */ 323848b8605Smrg if (resized) { 324848b8605Smrg for (i = 0; i < ST_ATTACHMENT_COUNT; i++) 325848b8605Smrg pipe_resource_reference(&drawable->textures[i], NULL); 326848b8605Smrg } 327848b8605Smrg 328848b8605Smrg memset(&templ, 0, sizeof(templ)); 329848b8605Smrg templ.target = screen->target; 330848b8605Smrg templ.width0 = width; 331848b8605Smrg templ.height0 = height; 332848b8605Smrg templ.depth0 = 1; 333848b8605Smrg templ.array_size = 1; 334848b8605Smrg templ.last_level = 0; 335848b8605Smrg 336848b8605Smrg for (i = 0; i < count; i++) { 337848b8605Smrg enum pipe_format format; 338848b8605Smrg unsigned bind; 339848b8605Smrg 340848b8605Smrg /* the texture already exists or not requested */ 341848b8605Smrg if (drawable->textures[statts[i]]) 342848b8605Smrg continue; 343848b8605Smrg 344848b8605Smrg dri_drawable_get_format(drawable, statts[i], &format, &bind); 345848b8605Smrg 346848b8605Smrg /* if we don't do any present, no need for display targets */ 347b8e80941Smrg if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL && !screen->swrast_no_present) 348848b8605Smrg bind |= PIPE_BIND_DISPLAY_TARGET; 349848b8605Smrg 350848b8605Smrg if (format == PIPE_FORMAT_NONE) 351848b8605Smrg continue; 352848b8605Smrg 353848b8605Smrg templ.format = format; 354848b8605Smrg templ.bind = bind; 355848b8605Smrg 356b8e80941Smrg if (statts[i] == ST_ATTACHMENT_FRONT_LEFT && 357b8e80941Smrg screen->base.screen->resource_create_front && 358b8e80941Smrg loader->base.version >= 3) { 359b8e80941Smrg drawable->textures[statts[i]] = 360b8e80941Smrg screen->base.screen->resource_create_front(screen->base.screen, &templ, (const void *)drawable); 361b8e80941Smrg } else 362b8e80941Smrg drawable->textures[statts[i]] = 363b8e80941Smrg screen->base.screen->resource_create(screen->base.screen, &templ); 364848b8605Smrg } 365848b8605Smrg 366848b8605Smrg drawable->old_w = width; 367848b8605Smrg drawable->old_h = height; 368848b8605Smrg} 369848b8605Smrg 370848b8605Smrgstatic void 371848b8605Smrgdrisw_update_tex_buffer(struct dri_drawable *drawable, 372848b8605Smrg struct dri_context *ctx, 373848b8605Smrg struct pipe_resource *res) 374848b8605Smrg{ 375848b8605Smrg __DRIdrawable *dPriv = drawable->dPriv; 376848b8605Smrg 377848b8605Smrg struct st_context *st_ctx = (struct st_context *)ctx->st; 378848b8605Smrg struct pipe_context *pipe = st_ctx->pipe; 379848b8605Smrg struct pipe_transfer *transfer; 380848b8605Smrg char *map; 381848b8605Smrg int x, y, w, h; 382848b8605Smrg int ximage_stride, line; 383848b8605Smrg int cpp = util_format_get_blocksize(res->format); 384848b8605Smrg 385848b8605Smrg get_drawable_info(dPriv, &x, &y, &w, &h); 386848b8605Smrg 387848b8605Smrg map = pipe_transfer_map(pipe, res, 388848b8605Smrg 0, 0, // level, layer, 389848b8605Smrg PIPE_TRANSFER_WRITE, 390848b8605Smrg x, y, w, h, &transfer); 391848b8605Smrg 392848b8605Smrg /* Copy the Drawable content to the mapped texture buffer */ 393b8e80941Smrg if (!get_image_shm(dPriv, x, y, w, h, res)) 394b8e80941Smrg get_image(dPriv, x, y, w, h, map); 395848b8605Smrg 396848b8605Smrg /* The pipe transfer has a pitch rounded up to the nearest 64 pixels. 397848b8605Smrg get_image() has a pitch rounded up to 4 bytes. */ 398848b8605Smrg ximage_stride = ((w * cpp) + 3) & -4; 399848b8605Smrg for (line = h-1; line; --line) { 400848b8605Smrg memmove(&map[line * transfer->stride], 401848b8605Smrg &map[line * ximage_stride], 402848b8605Smrg ximage_stride); 403848b8605Smrg } 404848b8605Smrg 405848b8605Smrg pipe_transfer_unmap(pipe, transfer); 406848b8605Smrg} 407848b8605Smrg 408b8e80941Smrgstatic __DRIimageExtension driSWImageExtension = { 409b8e80941Smrg .base = { __DRI_IMAGE, 6 }, 410b8e80941Smrg 411b8e80941Smrg .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, 412b8e80941Smrg .createImageFromTexture = dri2_create_from_texture, 413b8e80941Smrg .destroyImage = dri2_destroy_image, 414b8e80941Smrg}; 415b8e80941Smrg 416848b8605Smrg/* 417848b8605Smrg * Backend function for init_screen. 418848b8605Smrg */ 419848b8605Smrg 420848b8605Smrgstatic const __DRIextension *drisw_screen_extensions[] = { 421848b8605Smrg &driTexBufferExtension.base, 422848b8605Smrg &dri2RendererQueryExtension.base, 423b8e80941Smrg &dri2ConfigQueryExtension.base, 424b8e80941Smrg &dri2FenceExtension.base, 425b8e80941Smrg &dri2NoErrorExtension.base, 426b8e80941Smrg &driSWImageExtension.base, 427b8e80941Smrg &dri2FlushControlExtension.base, 428848b8605Smrg NULL 429848b8605Smrg}; 430848b8605Smrg 431b8e80941Smrgstatic const struct drisw_loader_funcs drisw_lf = { 432b8e80941Smrg .get_image = drisw_get_image, 433848b8605Smrg .put_image = drisw_put_image, 434848b8605Smrg .put_image2 = drisw_put_image2 435848b8605Smrg}; 436848b8605Smrg 437b8e80941Smrgstatic const struct drisw_loader_funcs drisw_shm_lf = { 438b8e80941Smrg .get_image = drisw_get_image, 439b8e80941Smrg .put_image = drisw_put_image, 440b8e80941Smrg .put_image2 = drisw_put_image2, 441b8e80941Smrg .put_image_shm = drisw_put_image_shm 442b8e80941Smrg}; 443b8e80941Smrg 444848b8605Smrgstatic const __DRIconfig ** 445848b8605Smrgdrisw_init_screen(__DRIscreen * sPriv) 446848b8605Smrg{ 447b8e80941Smrg const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; 448848b8605Smrg const __DRIconfig **configs; 449848b8605Smrg struct dri_screen *screen; 450b8e80941Smrg struct pipe_screen *pscreen = NULL; 451b8e80941Smrg const struct drisw_loader_funcs *lf = &drisw_lf; 452848b8605Smrg 453848b8605Smrg screen = CALLOC_STRUCT(dri_screen); 454848b8605Smrg if (!screen) 455848b8605Smrg return NULL; 456848b8605Smrg 457848b8605Smrg screen->sPriv = sPriv; 458848b8605Smrg screen->fd = -1; 459848b8605Smrg 460b8e80941Smrg screen->swrast_no_present = debug_get_option_swrast_no_present(); 461848b8605Smrg 462848b8605Smrg sPriv->driverPrivate = (void *)screen; 463848b8605Smrg sPriv->extensions = drisw_screen_extensions; 464b8e80941Smrg if (loader->base.version >= 4) { 465b8e80941Smrg if (loader->putImageShm) 466b8e80941Smrg lf = &drisw_shm_lf; 467b8e80941Smrg } 468848b8605Smrg 469b8e80941Smrg if (pipe_loader_sw_probe_dri(&screen->dev, lf)) { 470b8e80941Smrg dri_init_options(screen); 471b8e80941Smrg 472b8e80941Smrg pscreen = pipe_loader_create_screen(screen->dev); 473b8e80941Smrg } 474848b8605Smrg 475b8e80941Smrg if (!pscreen) 476b8e80941Smrg goto fail; 477b8e80941Smrg 478b8e80941Smrg configs = dri_init_screen_helper(screen, pscreen); 479848b8605Smrg if (!configs) 480848b8605Smrg goto fail; 481848b8605Smrg 482b8e80941Smrg screen->lookup_egl_image = dri2_lookup_egl_image; 483b8e80941Smrg 484848b8605Smrg return configs; 485848b8605Smrgfail: 486848b8605Smrg dri_destroy_screen_helper(screen); 487b8e80941Smrg if (screen->dev) 488b8e80941Smrg pipe_loader_release(&screen->dev, 1); 489848b8605Smrg FREE(screen); 490848b8605Smrg return NULL; 491848b8605Smrg} 492848b8605Smrg 493848b8605Smrgstatic boolean 494848b8605Smrgdrisw_create_buffer(__DRIscreen * sPriv, 495848b8605Smrg __DRIdrawable * dPriv, 496848b8605Smrg const struct gl_config * visual, boolean isPixmap) 497848b8605Smrg{ 498848b8605Smrg struct dri_drawable *drawable = NULL; 499848b8605Smrg 500848b8605Smrg if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) 501848b8605Smrg return FALSE; 502848b8605Smrg 503848b8605Smrg drawable = dPriv->driverPrivate; 504848b8605Smrg 505848b8605Smrg drawable->allocate_textures = drisw_allocate_textures; 506848b8605Smrg drawable->update_drawable_info = drisw_update_drawable_info; 507848b8605Smrg drawable->flush_frontbuffer = drisw_flush_frontbuffer; 508848b8605Smrg drawable->update_tex_buffer = drisw_update_tex_buffer; 509848b8605Smrg 510848b8605Smrg return TRUE; 511848b8605Smrg} 512848b8605Smrg 513848b8605Smrg/** 514848b8605Smrg * DRI driver virtual function table. 515848b8605Smrg * 516848b8605Smrg * DRI versions differ in their implementation of init_screen and swap_buffers. 517848b8605Smrg */ 518848b8605Smrgconst struct __DriverAPIRec galliumsw_driver_api = { 519848b8605Smrg .InitScreen = drisw_init_screen, 520848b8605Smrg .DestroyScreen = dri_destroy_screen, 521848b8605Smrg .CreateContext = dri_create_context, 522848b8605Smrg .DestroyContext = dri_destroy_context, 523848b8605Smrg .CreateBuffer = drisw_create_buffer, 524848b8605Smrg .DestroyBuffer = dri_destroy_buffer, 525848b8605Smrg .SwapBuffers = drisw_swap_buffers, 526848b8605Smrg .MakeCurrent = dri_make_current, 527848b8605Smrg .UnbindContext = dri_unbind_context, 528848b8605Smrg .CopySubBuffer = drisw_copy_sub_buffer, 529848b8605Smrg}; 530848b8605Smrg 531848b8605Smrg/* This is the table of extensions that the loader will dlsym() for. */ 532848b8605Smrgconst __DRIextension *galliumsw_driver_extensions[] = { 533848b8605Smrg &driCoreExtension.base, 534848b8605Smrg &driSWRastExtension.base, 535848b8605Smrg &driCopySubBufferExtension.base, 536848b8605Smrg &gallium_config_options.base, 537848b8605Smrg NULL 538848b8605Smrg}; 539848b8605Smrg 540848b8605Smrg/* vim: set sw=3 ts=8 sts=3 expandtab: */ 541