123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- /**************************************************************************
- *
- * Copyright 2007 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.
- *
- **************************************************************************/
-
- #ifndef U_INLINES_H
- #define U_INLINES_H
-
- #include "pipe/p_context.h"
- #include "pipe/p_defines.h"
- #include "pipe/p_state.h"
- #include "pipe/p_screen.h"
- #include "util/u_debug.h"
- #include "util/u_atomic.h"
- #include "util/u_box.h"
-
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
-
- /*
- * Reference counting helper functions.
- */
-
-
- static INLINE void
- pipe_reference_init(struct pipe_reference *reference, unsigned count)
- {
- p_atomic_set(&reference->count, count);
- }
-
- static INLINE boolean
- pipe_is_referenced(struct pipe_reference *reference)
- {
- return p_atomic_read(&reference->count) != 0;
- }
-
- /**
- * Update reference counting.
- * The old thing pointed to, if any, will be unreferenced.
- * Both 'ptr' and 'reference' may be NULL.
- * \return TRUE if the object's refcount hits zero and should be destroyed.
- */
- static INLINE boolean
- pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
- {
- boolean destroy = FALSE;
-
- if(ptr != reference) {
- /* bump the reference.count first */
- if (reference) {
- assert(pipe_is_referenced(reference));
- p_atomic_inc(&reference->count);
- }
-
- if (ptr) {
- assert(pipe_is_referenced(ptr));
- if (p_atomic_dec_zero(&ptr->count)) {
- destroy = TRUE;
- }
- }
- }
-
- return destroy;
- }
-
-
- static INLINE void
- pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
- {
- struct pipe_surface *old_surf = *ptr;
-
- if (pipe_reference(&(*ptr)->reference, &surf->reference))
- old_surf->texture->screen->tex_surface_destroy(old_surf);
- *ptr = surf;
- }
-
-
- static INLINE void
- pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex)
- {
- struct pipe_resource *old_tex = *ptr;
-
- if (pipe_reference(&(*ptr)->reference, &tex->reference))
- old_tex->screen->resource_destroy(old_tex->screen, old_tex);
- *ptr = tex;
- }
-
-
- static INLINE void
- pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
- {
- struct pipe_sampler_view *old_view = *ptr;
-
- if (pipe_reference(&(*ptr)->reference, &view->reference))
- old_view->context->sampler_view_destroy(old_view->context, old_view);
- *ptr = view;
- }
-
-
- /*
- * Convenience wrappers for screen buffer functions.
- */
-
- static INLINE struct pipe_resource *
- pipe_buffer_create( struct pipe_screen *screen,
- unsigned bind,
- unsigned size )
- {
- struct pipe_resource buffer;
- memset(&buffer, 0, sizeof buffer);
- buffer.target = PIPE_BUFFER;
- buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
- buffer.bind = bind;
- buffer._usage = PIPE_USAGE_DEFAULT;
- buffer.flags = 0;
- buffer.width0 = size;
- buffer.height0 = 1;
- buffer.depth0 = 1;
- return screen->resource_create(screen, &buffer);
- }
-
-
- static INLINE struct pipe_resource *
- pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size,
- unsigned usage )
- {
- return screen->user_buffer_create(screen, ptr, size, usage);
- }
-
- static INLINE void *
- pipe_buffer_map_range(struct pipe_context *pipe,
- struct pipe_resource *buffer,
- unsigned offset,
- unsigned length,
- unsigned usage,
- struct pipe_transfer **transfer)
- {
- struct pipe_box box;
- char *map;
-
- assert(offset < buffer->width0);
- assert(offset + length <= buffer->width0);
- assert(length);
-
- u_box_1d(offset, length, &box);
-
- *transfer = pipe->get_transfer( pipe,
- buffer,
- u_subresource(0, 0),
- usage,
- &box);
-
- if (*transfer == NULL)
- return NULL;
-
- map = pipe->transfer_map( pipe, *transfer );
- if (map == NULL) {
- pipe->transfer_destroy( pipe, *transfer );
- return NULL;
- }
-
- /* Match old screen->buffer_map_range() behaviour, return pointer
- * to where the beginning of the buffer would be:
- */
- return (void *)(map - offset);
- }
-
-
- static INLINE void *
- pipe_buffer_map(struct pipe_context *pipe,
- struct pipe_resource *buffer,
- unsigned usage,
- struct pipe_transfer **transfer)
- {
- return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer);
- }
-
-
- static INLINE void
- pipe_buffer_unmap(struct pipe_context *pipe,
- struct pipe_resource *buf,
- struct pipe_transfer *transfer)
- {
- if (transfer) {
- pipe->transfer_unmap(pipe, transfer);
- pipe->transfer_destroy(pipe, transfer);
- }
- }
-
- static INLINE void
- pipe_buffer_flush_mapped_range(struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- unsigned offset,
- unsigned length)
- {
- struct pipe_box box;
- int transfer_offset;
-
- assert(length);
- assert(transfer->box.x <= offset);
- assert(transfer->box.x + transfer->box.width <= offset + length);
-
- /* Match old screen->buffer_flush_mapped_range() behaviour, where
- * offset parameter is relative to the start of the buffer, not the
- * mapped range.
- */
- transfer_offset = offset - transfer->box.x;
-
- u_box_1d(transfer_offset, length, &box);
-
- pipe->transfer_flush_region(pipe, transfer, &box);
- }
-
- static INLINE void
- pipe_buffer_write(struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned offset,
- unsigned size,
- const void *data)
- {
- struct pipe_box box;
-
- u_box_1d(offset, size, &box);
-
- pipe->transfer_inline_write( pipe,
- buf,
- u_subresource(0,0),
- PIPE_TRANSFER_WRITE,
- &box,
- data,
- size,
- 0);
- }
-
- /**
- * Special case for writing non-overlapping ranges.
- *
- * We can avoid GPU/CPU synchronization when writing range that has never
- * been written before.
- */
- static INLINE void
- pipe_buffer_write_nooverlap(struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned offset, unsigned size,
- const void *data)
- {
- struct pipe_box box;
-
- u_box_1d(offset, size, &box);
-
- pipe->transfer_inline_write(pipe,
- buf,
- u_subresource(0,0),
- (PIPE_TRANSFER_WRITE |
- PIPE_TRANSFER_NOOVERWRITE),
- &box,
- data,
- 0, 0);
- }
-
- static INLINE void
- pipe_buffer_read(struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned offset,
- unsigned size,
- void *data)
- {
- struct pipe_transfer *src_transfer;
- ubyte *map;
-
- map = (ubyte *) pipe_buffer_map_range(pipe,
- buf,
- offset, size,
- PIPE_TRANSFER_READ,
- &src_transfer);
-
- if (map)
- memcpy(data, map + offset, size);
-
- pipe_buffer_unmap(pipe, buf, src_transfer);
- }
-
- static INLINE struct pipe_transfer *
- pipe_get_transfer( struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned face, unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y,
- unsigned w, unsigned h)
- {
- struct pipe_box box;
- u_box_2d_zslice( x, y, zslice, w, h, &box );
- return context->get_transfer( context,
- resource,
- u_subresource(face, level),
- usage,
- &box );
- }
-
- static INLINE void *
- pipe_transfer_map( struct pipe_context *context,
- struct pipe_transfer *transfer )
- {
- return context->transfer_map( context, transfer );
- }
-
- static INLINE void
- pipe_transfer_unmap( struct pipe_context *context,
- struct pipe_transfer *transfer )
- {
- context->transfer_unmap( context, transfer );
- }
-
-
- static INLINE void
- pipe_transfer_destroy( struct pipe_context *context,
- struct pipe_transfer *transfer )
- {
- context->transfer_destroy(context, transfer);
- }
-
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif /* U_INLINES_H */
|