xa_context.c revision 9f2f5b3d7fd70663b98da5d302fcdfd5bc93db05
1/********************************************************** 2 * Copyright 2009-2011 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 ********************************************************* 25 * Authors: 26 * Zack Rusin <zackr-at-vmware-dot-com> 27 * Thomas Hellstrom <thellstrom-at-vmware-dot-com> 28 */ 29#include "xa_context.h" 30#include "xa_priv.h" 31#include "cso_cache/cso_context.h" 32#include "util/u_inlines.h" 33#include "util/u_rect.h" 34#include "pipe/p_context.h" 35 36 37struct xa_context * 38xa_context_default(struct xa_tracker *xa) 39{ 40 return xa->default_ctx; 41} 42 43struct xa_context * 44xa_context_create(struct xa_tracker *xa) 45{ 46 struct xa_context *ctx = calloc(1, sizeof(*ctx)); 47 48 ctx->xa = xa; 49 ctx->pipe = xa->screen->context_create(xa->screen, NULL); 50 ctx->cso = cso_create_context(ctx->pipe); 51 ctx->shaders = xa_shaders_create(ctx); 52 renderer_init_state(ctx); 53 54 return ctx; 55} 56 57void 58xa_context_destroy(struct xa_context *r) 59{ 60 struct pipe_resource **vsbuf = &r->vs_const_buffer; 61 struct pipe_resource **fsbuf = &r->fs_const_buffer; 62 63 if (*vsbuf) 64 pipe_resource_reference(vsbuf, NULL); 65 66 if (*fsbuf) 67 pipe_resource_reference(fsbuf, NULL); 68 69 if (r->shaders) { 70 xa_shaders_destroy(r->shaders); 71 r->shaders = NULL; 72 } 73 74 if (r->cso) { 75 cso_release_all(r->cso); 76 cso_destroy_context(r->cso); 77 r->cso = NULL; 78 } 79} 80 81int 82xa_surface_dma(struct xa_context *ctx, 83 struct xa_surface *srf, 84 void *data, 85 unsigned int pitch, 86 int to_surface, struct xa_box *boxes, unsigned int num_boxes) 87{ 88 struct pipe_transfer *transfer; 89 void *map; 90 int w, h, i; 91 enum pipe_transfer_usage transfer_direction; 92 struct pipe_context *pipe = ctx->pipe; 93 94 transfer_direction = (to_surface ? PIPE_TRANSFER_WRITE : 95 PIPE_TRANSFER_READ); 96 97 for (i = 0; i < num_boxes; ++i, ++boxes) { 98 w = boxes->x2 - boxes->x1; 99 h = boxes->y2 - boxes->y1; 100 101 transfer = pipe_get_transfer(pipe, srf->tex, 0, 0, 102 transfer_direction, boxes->x1, boxes->y1, 103 w, h); 104 if (!transfer) 105 return -XA_ERR_NORES; 106 107 map = pipe_transfer_map(ctx->pipe, transfer); 108 if (!map) 109 goto out_no_map; 110 111 if (to_surface) { 112 util_copy_rect(map, srf->tex->format, transfer->stride, 113 0, 0, w, h, data, pitch, boxes->x1, boxes->y1); 114 } else { 115 util_copy_rect(data, srf->tex->format, pitch, 116 boxes->x1, boxes->y1, w, h, map, transfer->stride, 0, 117 0); 118 } 119 pipe->transfer_unmap(pipe, transfer); 120 pipe->transfer_destroy(pipe, transfer); 121 if (to_surface) 122 pipe->flush(pipe, &ctx->last_fence); 123 } 124 return XA_ERR_NONE; 125 out_no_map: 126 pipe->transfer_destroy(pipe, transfer); 127 return -XA_ERR_NORES; 128} 129 130void * 131xa_surface_map(struct xa_context *ctx, 132 struct xa_surface *srf, unsigned int usage) 133{ 134 void *map; 135 unsigned int transfer_direction = 0; 136 struct pipe_context *pipe = ctx->pipe; 137 138 if (srf->transfer) 139 return NULL; 140 141 if (usage & XA_MAP_READ) 142 transfer_direction = PIPE_TRANSFER_READ; 143 if (usage & XA_MAP_WRITE) 144 transfer_direction = PIPE_TRANSFER_WRITE; 145 146 if (!transfer_direction) 147 return NULL; 148 149 srf->transfer = pipe_get_transfer(pipe, srf->tex, 0, 0, 150 transfer_direction, 0, 0, 151 srf->tex->width0, srf->tex->height0); 152 if (!srf->transfer) 153 return NULL; 154 155 map = pipe_transfer_map(pipe, srf->transfer); 156 if (!map) 157 pipe->transfer_destroy(pipe, srf->transfer); 158 159 srf->mapping_pipe = pipe; 160 return map; 161} 162 163void 164xa_surface_unmap(struct xa_surface *srf) 165{ 166 if (srf->transfer) { 167 struct pipe_context *pipe = srf->mapping_pipe; 168 169 pipe->transfer_unmap(pipe, srf->transfer); 170 pipe->transfer_destroy(pipe, srf->transfer); 171 srf->transfer = NULL; 172 } 173} 174 175int 176xa_copy_prepare(struct xa_context *ctx, 177 struct xa_surface *dst, struct xa_surface *src) 178{ 179 if (src == dst || src->tex->format != dst->tex->format) 180 return -XA_ERR_INVAL; 181 182 ctx->src = src; 183 ctx->dst = dst; 184 185 return 0; 186} 187 188void 189xa_copy(struct xa_context *ctx, 190 int dx, int dy, int sx, int sy, int width, int height) 191{ 192 struct pipe_box src_box; 193 194 u_box_2d(sx, sy, width, height, &src_box); 195 ctx->pipe->resource_copy_region(ctx->pipe, 196 ctx->dst->tex, 0, dx, dy, 0, ctx->src->tex, 197 0, &src_box); 198 199} 200 201void 202xa_copy_done(struct xa_context *ctx) 203{ 204 ctx->pipe->flush(ctx->pipe, &ctx->last_fence); 205} 206 207struct xa_fence * 208xa_fence_get(struct xa_context *ctx) 209{ 210 struct xa_fence *fence = malloc(sizeof(*fence)); 211 struct pipe_screen *screen = ctx->xa->screen; 212 213 if (!fence) 214 return NULL; 215 216 fence->xa = ctx->xa; 217 218 if (ctx->last_fence == NULL) 219 fence->pipe_fence = NULL; 220 else 221 screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence); 222 223 return fence; 224} 225 226int 227xa_fence_wait(struct xa_fence *fence, uint64_t timeout) 228{ 229 if (!fence) 230 return XA_ERR_NONE; 231 232 if (fence->pipe_fence) { 233 struct pipe_screen *screen = fence->xa->screen; 234 boolean timed_out; 235 236 timed_out = !screen->fence_finish(screen, fence->pipe_fence, timeout); 237 if (timed_out) 238 return -XA_ERR_BUSY; 239 240 screen->fence_reference(screen, &fence->pipe_fence, NULL); 241 } 242 return XA_ERR_NONE; 243} 244 245void 246xa_fence_destroy(struct xa_fence *fence) 247{ 248 if (!fence) 249 return; 250 251 if (fence->pipe_fence) { 252 struct pipe_screen *screen = fence->xa->screen; 253 254 screen->fence_reference(screen, &fence->pipe_fence, NULL); 255 } 256 257 free(fence); 258} 259