X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_inlines.h;h=0e80cef0b08480f097a21c4f615a77b5cfb88b45;hb=b284f1f7f9afa560d6f4c0863681a7e36913955c;hp=2ec1ccfe9d3204cf85aeb0f80118ee18037d0c2d;hpb=1a840cc5925f52079916feb2c456816a7a91d627;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 2ec1ccfe9d3..0e80cef0b08 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * 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 + * IN NO EVENT SHALL VMWARE 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. @@ -30,6 +30,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" #include "pipe/p_screen.h" #include "util/u_debug.h" @@ -50,13 +51,13 @@ extern "C" { */ -static INLINE void +static inline void pipe_reference_init(struct pipe_reference *reference, unsigned count) { p_atomic_set(&reference->count, count); } -static INLINE boolean +static inline boolean pipe_is_referenced(struct pipe_reference *reference) { return p_atomic_read(&reference->count) != 0; @@ -68,7 +69,7 @@ pipe_is_referenced(struct pipe_reference *reference) * Both 'ptr' and 'reference' may be NULL. * \return TRUE if the object's refcount hits zero and should be destroyed. */ -static INLINE boolean +static inline boolean pipe_reference_described(struct pipe_reference *ptr, struct pipe_reference *reference, debug_reference_descriptor get_desc) @@ -95,14 +96,14 @@ pipe_reference_described(struct pipe_reference *ptr, return destroy; } -static INLINE boolean +static inline boolean pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) { return pipe_reference_described(ptr, reference, (debug_reference_descriptor)debug_describe_reference); } -static INLINE void +static inline void pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) { struct pipe_surface *old_surf = *ptr; @@ -113,7 +114,23 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) *ptr = surf; } -static INLINE void +/** + * Similar to pipe_surface_reference() but always set the pointer to NULL + * and pass in an explicit context. The explicit context avoids the problem + * of using a deleted context's surface_destroy() method when freeing a surface + * that's shared by multiple contexts. + */ +static inline void +pipe_surface_release(struct pipe_context *pipe, struct pipe_surface **ptr) +{ + if (pipe_reference_described(&(*ptr)->reference, NULL, + (debug_reference_descriptor)debug_describe_surface)) + pipe->surface_destroy(pipe, *ptr); + *ptr = NULL; +} + + +static inline void pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex) { struct pipe_resource *old_tex = *ptr; @@ -124,7 +141,7 @@ pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex) *ptr = tex; } -static INLINE void +static inline void pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) { struct pipe_sampler_view *old_view = *ptr; @@ -141,7 +158,7 @@ pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_ * work-around for fixing a dangling context pointer problem when textures * are shared by multiple contexts. XXX fix this someday. */ -static INLINE void +static inline void pipe_sampler_view_release(struct pipe_context *ctx, struct pipe_sampler_view **ptr) { @@ -156,8 +173,7 @@ pipe_sampler_view_release(struct pipe_context *ctx, *ptr = NULL; } - -static INLINE void +static inline void pipe_so_target_reference(struct pipe_stream_output_target **ptr, struct pipe_stream_output_target *target) { @@ -169,33 +185,30 @@ pipe_so_target_reference(struct pipe_stream_output_target **ptr, *ptr = target; } -static INLINE void +static inline void pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps, - struct pipe_resource *pt, unsigned level, unsigned layer, - unsigned flags) + struct pipe_resource *pt, unsigned level, unsigned layer) { pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); - ps->usage = flags; ps->u.tex.level = level; ps->u.tex.first_layer = ps->u.tex.last_layer = layer; ps->context = ctx; } -static INLINE void +static inline void pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps, - struct pipe_resource *pt, unsigned level, unsigned layer, - unsigned flags) + struct pipe_resource *pt, unsigned level, unsigned layer) { ps->texture = 0; pipe_reference_init(&ps->reference, 1); - pipe_surface_reset(ctx, ps, pt, level, layer, flags); + pipe_surface_reset(ctx, ps, pt, level, layer); } /* Return true if the surfaces are equal. */ -static INLINE boolean +static inline boolean pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2) { return s1->texture == s2->texture && @@ -213,7 +226,13 @@ pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2) * Convenience wrappers for screen buffer functions. */ -static INLINE struct pipe_resource * + +/** + * Create a new resource. + * \param bind bitmask of PIPE_BIND_x flags + * \param usage bitmask of PIPE_USAGE_x flags + */ +static inline struct pipe_resource * pipe_buffer_create( struct pipe_screen *screen, unsigned bind, unsigned usage, @@ -234,19 +253,19 @@ pipe_buffer_create( struct pipe_screen *screen, } -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 * +/** + * Map a range of a resource. + * \param offset start of region, in bytes + * \param length size of region, in bytes + * \param access bitmask of PIPE_TRANSFER_x flags + * \param transfer returns a transfer object + */ +static inline void * pipe_buffer_map_range(struct pipe_context *pipe, struct pipe_resource *buffer, unsigned offset, unsigned length, - unsigned usage, + unsigned access, struct pipe_transfer **transfer) { struct pipe_box box; @@ -258,19 +277,8 @@ pipe_buffer_map_range(struct pipe_context *pipe, u_box_1d(offset, length, &box); - *transfer = pipe->get_transfer( pipe, - buffer, - 0, - usage, - &box); - - if (*transfer == NULL) - return NULL; - - map = pipe->transfer_map( pipe, *transfer ); - if (map == NULL) { - pipe->transfer_destroy( pipe, *transfer ); - *transfer = NULL; + map = pipe->transfer_map(pipe, buffer, 0, access, &box, transfer); + if (!map) { return NULL; } @@ -278,27 +286,29 @@ pipe_buffer_map_range(struct pipe_context *pipe, } -static INLINE void * +/** + * Map whole resource. + * \param access bitmask of PIPE_TRANSFER_x flags + * \param transfer returns a transfer object + */ +static inline void * pipe_buffer_map(struct pipe_context *pipe, struct pipe_resource *buffer, - unsigned usage, + unsigned access, struct pipe_transfer **transfer) { - return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer); + return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, access, transfer); } -static INLINE void +static inline void pipe_buffer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { - if (transfer) { - pipe->transfer_unmap(pipe, transfer); - pipe->transfer_destroy(pipe, transfer); - } + pipe->transfer_unmap(pipe, transfer); } -static INLINE void +static inline void pipe_buffer_flush_mapped_range(struct pipe_context *pipe, struct pipe_transfer *transfer, unsigned offset, @@ -308,8 +318,8 @@ pipe_buffer_flush_mapped_range(struct pipe_context *pipe, int transfer_offset; assert(length); - assert(transfer->box.x <= offset); - assert(offset + length <= transfer->box.x + transfer->box.width); + assert(transfer->box.x <= (int) offset); + assert((int) (offset + length) <= transfer->box.x + transfer->box.width); /* Match old screen->buffer_flush_mapped_range() behaviour, where * offset parameter is relative to the start of the buffer, not the @@ -322,7 +332,7 @@ pipe_buffer_flush_mapped_range(struct pipe_context *pipe, pipe->transfer_flush_region(pipe, transfer, &box); } -static INLINE void +static inline void pipe_buffer_write(struct pipe_context *pipe, struct pipe_resource *buf, unsigned offset, @@ -330,12 +340,12 @@ pipe_buffer_write(struct pipe_context *pipe, const void *data) { struct pipe_box box; - unsigned usage = PIPE_TRANSFER_WRITE; + unsigned access = PIPE_TRANSFER_WRITE; if (offset == 0 && size == buf->width0) { - usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; + access |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; } else { - usage |= PIPE_TRANSFER_DISCARD_RANGE; + access |= PIPE_TRANSFER_DISCARD_RANGE; } u_box_1d(offset, size, &box); @@ -343,7 +353,7 @@ pipe_buffer_write(struct pipe_context *pipe, pipe->transfer_inline_write( pipe, buf, 0, - usage, + access, &box, data, size, @@ -356,7 +366,7 @@ pipe_buffer_write(struct pipe_context *pipe, * We can avoid GPU/CPU synchronization when writing range that has never * been written before. */ -static INLINE void +static inline void pipe_buffer_write_nooverlap(struct pipe_context *pipe, struct pipe_resource *buf, unsigned offset, unsigned size, @@ -376,12 +386,18 @@ pipe_buffer_write_nooverlap(struct pipe_context *pipe, 0, 0); } -static INLINE struct pipe_resource * + +/** + * Create a new resource and immediately put data into it + * \param bind bitmask of PIPE_BIND_x flags + * \param usage bitmask of PIPE_USAGE_x flags + */ +static inline struct pipe_resource * pipe_buffer_create_with_data(struct pipe_context *pipe, unsigned bind, unsigned usage, unsigned size, - void *ptr) + const void *ptr) { struct pipe_resource *res = pipe_buffer_create(pipe->screen, bind, usage, size); @@ -389,7 +405,7 @@ pipe_buffer_create_with_data(struct pipe_context *pipe, return res; } -static INLINE void +static inline void pipe_buffer_read(struct pipe_context *pipe, struct pipe_resource *buf, unsigned offset, @@ -404,53 +420,67 @@ pipe_buffer_read(struct pipe_context *pipe, offset, size, PIPE_TRANSFER_READ, &src_transfer); + if (!map) + return; - if (map) - memcpy(data, map, size); - + memcpy(data, map, size); pipe_buffer_unmap(pipe, src_transfer); } -static INLINE struct pipe_transfer * -pipe_get_transfer( struct pipe_context *context, - struct pipe_resource *resource, - unsigned level, unsigned layer, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, - unsigned w, unsigned h) + +/** + * Map a resource for reading/writing. + * \param access bitmask of PIPE_TRANSFER_x flags + */ +static inline void * +pipe_transfer_map(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, unsigned layer, + unsigned access, + unsigned x, unsigned y, + unsigned w, unsigned h, + struct pipe_transfer **transfer) { struct pipe_box box; - u_box_2d_zslice( x, y, layer, w, h, &box ); - return context->get_transfer( context, - resource, - level, - usage, - &box ); + u_box_2d_zslice(x, y, layer, w, h, &box); + return context->transfer_map(context, + resource, + level, + access, + &box, transfer); } -static INLINE void * -pipe_transfer_map( struct pipe_context *context, - struct pipe_transfer *transfer ) + +/** + * Map a 3D (texture) resource for reading/writing. + * \param access bitmask of PIPE_TRANSFER_x flags + */ +static inline void * +pipe_transfer_map_3d(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + unsigned access, + unsigned x, unsigned y, unsigned z, + unsigned w, unsigned h, unsigned d, + struct pipe_transfer **transfer) { - return context->transfer_map( context, transfer ); + struct pipe_box box; + u_box_3d(x, y, z, w, h, d, &box); + return context->transfer_map(context, + resource, + level, + access, + &box, transfer); } -static INLINE void +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); -} - -static INLINE void +static inline void pipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_resource *buf) { @@ -467,9 +497,13 @@ pipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, } -static INLINE boolean util_get_offset( - const struct pipe_rasterizer_state *templ, - unsigned fill_mode) +/** + * Get the polygon offset enable/disable flag for the given polygon fill mode. + * \param fill_mode one of PIPE_POLYGON_MODE_POINT/LINE/FILL + */ +static inline boolean +util_get_offset(const struct pipe_rasterizer_state *templ, + unsigned fill_mode) { switch(fill_mode) { case PIPE_POLYGON_MODE_POINT: @@ -484,46 +518,17 @@ static INLINE boolean util_get_offset( } } -/** - * This function is used to copy an array of pipe_vertex_buffer structures, - * while properly referencing the pipe_vertex_buffer::buffer member. - * - * \sa util_copy_framebuffer_state - */ -static INLINE void util_copy_vertex_buffers(struct pipe_vertex_buffer *dst, - unsigned *dst_count, - const struct pipe_vertex_buffer *src, - unsigned src_count) -{ - unsigned i; - - /* Reference the buffers of 'src' in 'dst'. */ - for (i = 0; i < src_count; i++) { - pipe_resource_reference(&dst[i].buffer, src[i].buffer); - } - /* Unreference the rest of the buffers in 'dst'. */ - for (; i < *dst_count; i++) { - pipe_resource_reference(&dst[i].buffer, NULL); - } - - /* Update the size of 'dst' and copy over the other members - * of pipe_vertex_buffer. */ - *dst_count = src_count; - memcpy(dst, src, src_count * sizeof(struct pipe_vertex_buffer)); -} - -static INLINE float +static inline float util_get_min_point_size(const struct pipe_rasterizer_state *state) { /* The point size should be clamped to this value at the rasterizer stage. */ - return state->gl_rasterization_rules && - !state->point_quad_rasterization && + return !state->point_quad_rasterization && !state->point_smooth && !state->multisample ? 1.0f : 0.0f; } -static INLINE void +static inline void util_query_clear_result(union pipe_query_result *result, unsigned type) { switch (type) { @@ -548,8 +553,122 @@ util_query_clear_result(union pipe_query_result *result, unsigned type) case PIPE_QUERY_PIPELINE_STATISTICS: memset(&result->pipeline_statistics, 0, sizeof(result->pipeline_statistics)); break; + default: + memset(result, 0, sizeof(*result)); + } +} + +/** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */ +static inline unsigned +util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target, + unsigned nr_samples) +{ + switch (pipe_tex_target) { + case PIPE_BUFFER: + return TGSI_TEXTURE_BUFFER; + + case PIPE_TEXTURE_1D: + assert(nr_samples <= 1); + return TGSI_TEXTURE_1D; + + case PIPE_TEXTURE_2D: + return nr_samples > 1 ? TGSI_TEXTURE_2D_MSAA : TGSI_TEXTURE_2D; + + case PIPE_TEXTURE_RECT: + assert(nr_samples <= 1); + return TGSI_TEXTURE_RECT; + + case PIPE_TEXTURE_3D: + assert(nr_samples <= 1); + return TGSI_TEXTURE_3D; + + case PIPE_TEXTURE_CUBE: + assert(nr_samples <= 1); + return TGSI_TEXTURE_CUBE; + + case PIPE_TEXTURE_1D_ARRAY: + assert(nr_samples <= 1); + return TGSI_TEXTURE_1D_ARRAY; + + case PIPE_TEXTURE_2D_ARRAY: + return nr_samples > 1 ? TGSI_TEXTURE_2D_ARRAY_MSAA : + TGSI_TEXTURE_2D_ARRAY; + + case PIPE_TEXTURE_CUBE_ARRAY: + return TGSI_TEXTURE_CUBE_ARRAY; + + default: + assert(0 && "unexpected texture target"); + return TGSI_TEXTURE_UNKNOWN; + } +} + + +static inline void +util_copy_constant_buffer(struct pipe_constant_buffer *dst, + const struct pipe_constant_buffer *src) +{ + if (src) { + pipe_resource_reference(&dst->buffer, src->buffer); + dst->buffer_offset = src->buffer_offset; + dst->buffer_size = src->buffer_size; + dst->user_buffer = src->user_buffer; + } + else { + pipe_resource_reference(&dst->buffer, NULL); + dst->buffer_offset = 0; + dst->buffer_size = 0; + dst->user_buffer = NULL; + } +} + +static inline void +util_copy_image_view(struct pipe_image_view *dst, + const struct pipe_image_view *src) +{ + pipe_resource_reference(&dst->resource, src->resource); + dst->format = src->format; + dst->access = src->access; + dst->u = src->u; +} + +static inline unsigned +util_max_layer(const struct pipe_resource *r, unsigned level) +{ + switch (r->target) { + case PIPE_TEXTURE_3D: + return u_minify(r->depth0, level) - 1; + case PIPE_TEXTURE_CUBE: + assert(r->array_size == 6); + /* fall-through */ + case PIPE_TEXTURE_1D_ARRAY: + case PIPE_TEXTURE_2D_ARRAY: + case PIPE_TEXTURE_CUBE_ARRAY: + return r->array_size - 1; + default: + return 0; + } +} + +static inline unsigned +util_pipe_shader_from_tgsi_processor(unsigned processor) +{ + switch (processor) { + case TGSI_PROCESSOR_VERTEX: + return PIPE_SHADER_VERTEX; + case TGSI_PROCESSOR_TESS_CTRL: + return PIPE_SHADER_TESS_CTRL; + case TGSI_PROCESSOR_TESS_EVAL: + return PIPE_SHADER_TESS_EVAL; + case TGSI_PROCESSOR_GEOMETRY: + return PIPE_SHADER_GEOMETRY; + case TGSI_PROCESSOR_FRAGMENT: + return PIPE_SHADER_FRAGMENT; + case TGSI_PROCESSOR_COMPUTE: + return PIPE_SHADER_COMPUTE; default: assert(0); + return PIPE_SHADER_VERTEX; } }