xorg_dri2.c revision 3905119b4743eb5d284236cc237ee2c19ae3c5c8
1/* 2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * 26 * Author: Alan Hourihane <alanh@tungstengraphics.com> 27 * Author: Jakob Bornecrantz <wallbraker@gmail.com> 28 * 29 */ 30 31#include "xorg-server.h" 32#include "xf86.h" 33#include "xf86_OSproc.h" 34 35#include "xorg_tracker.h" 36 37#include "dri2.h" 38 39#include "pipe/p_state.h" 40#include "pipe/p_inlines.h" 41 42#include "util/u_rect.h" 43 44typedef struct { 45 PixmapPtr pPixmap; 46 struct pipe_texture *tex; 47 struct pipe_buffer *buf; 48} *BufferPrivatePtr; 49 50static DRI2BufferPtr 51driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) 52{ 53 struct pipe_texture *depth, *tex; 54 struct pipe_buffer *buf; 55 ScreenPtr pScreen = pDraw->pScreen; 56 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 57 modesettingPtr ms = modesettingPTR(pScrn); 58 BufferPrivatePtr privates; 59 DRI2BufferPtr buffers; 60 PixmapPtr pPixmap; 61 unsigned stride, handle; 62 int i; 63 64 buffers = xcalloc(count, sizeof *buffers); 65 if (!buffers) 66 goto fail_buffers; 67 68 privates = xcalloc(count, sizeof *privates); 69 if (!privates) 70 goto fail_privates; 71 72 depth = NULL; 73 for (i = 0; i < count; i++) { 74 pPixmap = NULL; 75 tex = NULL; 76 buf = NULL; 77 if (attachments[i] == DRI2BufferFrontLeft) { 78 if (pDraw->type == DRAWABLE_PIXMAP) 79 pPixmap = (PixmapPtr) pDraw; 80 else 81 pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); 82 pPixmap->refcnt++; 83 tex = xorg_exa_get_texture(pPixmap); 84 } else if (attachments[i] == DRI2BufferStencil) { 85 pipe_texture_reference(&tex, depth); 86 } else if (attachments[i] == DRI2BufferDepth) { 87 struct pipe_texture template; 88 memset(&template, 0, sizeof(template)); 89 template.target = PIPE_TEXTURE_2D; 90 template.format = PIPE_FORMAT_S8Z24_UNORM; 91 pf_get_block(template.format, &template.block); 92 template.width[0] = pDraw->width; 93 template.height[0] = pDraw->height; 94 template.depth[0] = 1; 95 template.last_level = 0; 96 template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; 97 tex = ms->screen->texture_create(ms->screen, &template); 98 depth = tex; 99 } else { 100 struct pipe_texture template; 101 memset(&template, 0, sizeof(template)); 102 template.target = PIPE_TEXTURE_2D; 103 template.format = PIPE_FORMAT_A8R8G8B8_UNORM; 104 pf_get_block(template.format, &template.block); 105 template.width[0] = pDraw->width; 106 template.height[0] = pDraw->height; 107 template.depth[0] = 1; 108 template.last_level = 0; 109 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; 110 tex = ms->screen->texture_create(ms->screen, &template); 111 } 112 113 if (!tex) 114 FatalError("NO TEXTURE IN DRI2\n"); 115 116 ms->api->buffer_from_texture(ms->api, tex, &buf, &stride); 117 ms->api->global_handle_from_buffer(ms->api, ms->screen, buf, &handle); 118 119 buffers[i].name = handle; 120 buffers[i].attachment = attachments[i]; 121 buffers[i].pitch = stride; 122 buffers[i].cpp = 4; 123 buffers[i].driverPrivate = &privates[i]; 124 buffers[i].flags = 0; /* not tiled */ 125 privates[i].pPixmap = pPixmap; 126 privates[i].buf = buf; 127 privates[i].tex = tex; 128 } 129 130 return buffers; 131 132fail_privates: 133 xfree(buffers); 134fail_buffers: 135 return NULL; 136} 137 138static void 139driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) 140{ 141 ScreenPtr pScreen = pDraw->pScreen; 142 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 143 modesettingPtr ms = modesettingPTR(pScrn); 144 BufferPrivatePtr private; 145 int i; 146 (void)ms; 147 148 for (i = 0; i < count; i++) { 149 private = buffers[i].driverPrivate; 150 151 if (private->pPixmap) 152 (*pScreen->DestroyPixmap)(private->pPixmap); 153 154 pipe_texture_reference(&private->tex, NULL); 155 pipe_buffer_reference(&private->buf, NULL); 156 } 157 158 if (buffers) { 159 xfree(buffers[0].driverPrivate); 160 xfree(buffers); 161 } 162} 163 164static void 165driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, 166 DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) 167{ 168 ScreenPtr pScreen = pDraw->pScreen; 169 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 170 modesettingPtr ms = modesettingPTR(pScrn); 171 BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; 172 BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; 173 174 struct pipe_surface *dst_surf = 175 ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0, 176 PIPE_BUFFER_USAGE_GPU_WRITE); 177 struct pipe_surface *src_surf = 178 ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0, 179 PIPE_BUFFER_USAGE_GPU_READ); 180 181#if 0 182 ms->ctx->surface_copy(ms->ctx, dst_surf, 0, 0, src_surf, 183 0, 0, pDraw->width, pDraw->height); 184#else 185 util_surface_copy(ms->ctx, false, dst_surf, 0, 0, src_surf, 186 0, 0, pDraw->width, pDraw->height); 187#endif 188 189 pipe_surface_reference(&dst_surf, NULL); 190 pipe_surface_reference(&src_surf, NULL); 191} 192 193Bool 194driScreenInit(ScreenPtr pScreen) 195{ 196 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 197 modesettingPtr ms = modesettingPTR(pScrn); 198 DRI2InfoRec dri2info; 199 200 dri2info.version = 1; 201 dri2info.fd = ms->fd; 202#if 0 203 dri2info.driverName = pScrn->name; 204#else 205 dri2info.driverName = "i915"; /* FIXME */ 206#endif 207 dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ 208 209 dri2info.CreateBuffers = driCreateBuffers; 210 dri2info.DestroyBuffers = driDestroyBuffers; 211 dri2info.CopyRegion = driCopyRegion; 212 213 return DRI2ScreenInit(pScreen, &dri2info); 214} 215 216void 217driCloseScreen(ScreenPtr pScreen) 218{ 219 DRI2CloseScreen(pScreen); 220} 221 222/* vim: set sw=4 ts=8 sts=4: */ 223