/************************************************************************** * * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ /* * Authors: * Keith Whitwell * Michel Dänzer */ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "i915_context.h" #include "i915_resource.h" static boolean i915_buffer_get_handle(struct pipe_screen *screen, struct pipe_resource *resource, struct winsys_handle *handle) { return FALSE; } static void i915_buffer_destroy(struct pipe_screen *screen, struct pipe_resource *resource) { struct i915_buffer *buffer = i915_buffer(resource); if (buffer->free_on_destroy) align_free(buffer->data); FREE(buffer); } static struct pipe_transfer * i915_get_transfer(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, unsigned usage, const struct pipe_box *box) { struct i915_context *i915 = i915_context(pipe); struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); if (transfer == NULL) return NULL; transfer->resource = resource; transfer->level = level; transfer->usage = usage; transfer->box = *box; /* Note strides are zero, this is ok for buffers, but not for * textures 2d & higher at least. */ return transfer; } static void i915_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct i915_context *i915 = i915_context(pipe); util_slab_free(&i915->transfer_pool, transfer); } static void * i915_buffer_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) { struct i915_buffer *buffer = i915_buffer(transfer->resource); return buffer->data + transfer->box.x; } static void i915_buffer_transfer_inline_write( struct pipe_context *rm_ctx, struct pipe_resource *resource, unsigned level, unsigned usage, const struct pipe_box *box, const void *data, unsigned stride, unsigned layer_stride) { struct i915_buffer *buffer = i915_buffer(resource); memcpy(buffer->data + box->x, data, box->width); } struct u_resource_vtbl i915_buffer_vtbl = { i915_buffer_get_handle, /* get_handle */ i915_buffer_destroy, /* resource_destroy */ NULL, /* is_resource_referenced */ i915_get_transfer, /* get_transfer */ i915_transfer_destroy, /* transfer_destroy */ i915_buffer_transfer_map, /* transfer_map */ u_default_transfer_flush_region, /* transfer_flush_region */ u_default_transfer_unmap, /* transfer_unmap */ i915_buffer_transfer_inline_write /* transfer_inline_write */ }; struct pipe_resource * i915_buffer_create(struct pipe_screen *screen, const struct pipe_resource *template) { struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); if (!buf) return NULL; buf->b.b = *template; buf->b.vtbl = &i915_buffer_vtbl; pipe_reference_init(&buf->b.b.reference, 1); buf->b.b.screen = screen; buf->data = MALLOC(template->width0); buf->free_on_destroy = TRUE; if (!buf->data) goto err; return &buf->b.b; err: FREE(buf); return NULL; } struct pipe_resource * i915_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, unsigned bind) { struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); if (!buf) return NULL; pipe_reference_init(&buf->b.b.reference, 1); buf->b.vtbl = &i915_buffer_vtbl; buf->b.b.screen = screen; buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ buf->b.b.usage = PIPE_USAGE_IMMUTABLE; buf->b.b.bind = bind; buf->b.b.flags = 0; buf->b.b.width0 = bytes; buf->b.b.height0 = 1; buf->b.b.depth0 = 1; buf->b.b.array_size = 1; buf->data = ptr; buf->free_on_destroy = FALSE; return &buf->b.b; }