/************************************************************************** * * Copyright 2010 VMware, Inc. * 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 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. * **************************************************************************/ #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/simple_list.h" #include "tgsi/tgsi_parse.h" #include "rbug_screen.h" #include "rbug_objects.h" #include "rbug_context.h" struct pipe_resource * rbug_resource_create(struct rbug_screen *rb_screen, struct pipe_resource *resource) { struct rbug_resource *rb_resource; if (!resource) goto error; assert(resource->screen == rb_screen->screen); rb_resource = CALLOC_STRUCT(rbug_resource); if (!rb_resource) goto error; memcpy(&rb_resource->base, resource, sizeof(struct pipe_resource)); pipe_reference_init(&rb_resource->base.reference, 1); rb_resource->base.screen = &rb_screen->base; rb_resource->resource = resource; if (resource->target != PIPE_BUFFER) rbug_screen_add_to_list(rb_screen, resources, rb_resource); return &rb_resource->base; error: pipe_resource_reference(&resource, NULL); return NULL; } void rbug_resource_destroy(struct rbug_resource *rb_resource) { struct rbug_screen *rb_screen = rbug_screen(rb_resource->base.screen); if (rb_resource->base.target != PIPE_BUFFER) rbug_screen_remove_from_list(rb_screen, resources, rb_resource); pipe_resource_reference(&rb_resource->resource, NULL); FREE(rb_resource); } struct pipe_surface * rbug_surface_create(struct rbug_context *rb_context, struct rbug_resource *rb_resource, struct pipe_surface *surface) { struct rbug_surface *rb_surface; if (!surface) goto error; assert(surface->texture == rb_resource->resource); rb_surface = CALLOC_STRUCT(rbug_surface); if (!rb_surface) goto error; memcpy(&rb_surface->base, surface, sizeof(struct pipe_surface)); pipe_reference_init(&rb_surface->base.reference, 1); rb_surface->base.texture = NULL; rb_surface->base.context = &rb_context->base; rb_surface->surface = surface; /* we own the surface already */ pipe_resource_reference(&rb_surface->base.texture, &rb_resource->base); return &rb_surface->base; error: pipe_surface_reference(&surface, NULL); return NULL; } void rbug_surface_destroy(struct rbug_context *rb_context, struct rbug_surface *rb_surface) { pipe_resource_reference(&rb_surface->base.texture, NULL); pipe_surface_reference(&rb_surface->surface, NULL); FREE(rb_surface); } struct pipe_sampler_view * rbug_sampler_view_create(struct rbug_context *rb_context, struct rbug_resource *rb_resource, struct pipe_sampler_view *view) { struct rbug_sampler_view *rb_view; if (!view) goto error; assert(view->texture == rb_resource->resource); rb_view = MALLOC(sizeof(struct rbug_sampler_view)); rb_view->base = *view; rb_view->base.reference.count = 1; rb_view->base.texture = NULL; pipe_resource_reference(&rb_view->base.texture, &rb_resource->base); rb_view->base.context = &rb_context->base; rb_view->sampler_view = view; return &rb_view->base; error: return NULL; } void rbug_sampler_view_destroy(struct rbug_context *rb_context, struct rbug_sampler_view *rb_view) { pipe_resource_reference(&rb_view->base.texture, NULL); pipe_sampler_view_reference(&rb_view->sampler_view, NULL); FREE(rb_view); } struct pipe_transfer * rbug_transfer_create(struct rbug_context *rb_context, struct rbug_resource *rb_resource, struct pipe_transfer *transfer) { struct rbug_transfer *rb_transfer; if (!transfer) goto error; assert(transfer->resource == rb_resource->resource); rb_transfer = CALLOC_STRUCT(rbug_transfer); if (!rb_transfer) goto error; memcpy(&rb_transfer->base, transfer, sizeof(struct pipe_transfer)); rb_transfer->base.resource = NULL; rb_transfer->transfer = transfer; rb_transfer->pipe = rb_context->pipe; pipe_resource_reference(&rb_transfer->base.resource, &rb_resource->base); assert(rb_transfer->base.resource == &rb_resource->base); return &rb_transfer->base; error: rb_context->pipe->transfer_unmap(rb_context->pipe, transfer); return NULL; } void rbug_transfer_destroy(struct rbug_context *rb_context, struct rbug_transfer *rb_transfer) { pipe_resource_reference(&rb_transfer->base.resource, NULL); FREE(rb_transfer); } void * rbug_shader_create(struct rbug_context *rb_context, const struct pipe_shader_state *state, void *result, enum rbug_shader_type type) { struct rbug_shader *rb_shader = CALLOC_STRUCT(rbug_shader); rb_shader->type = type; rb_shader->shader = result; rb_shader->tokens = tgsi_dup_tokens(state->tokens); /* works on context as well since its just a macro */ rbug_screen_add_to_list(rb_context, shaders, rb_shader); return rb_shader; } void rbug_shader_destroy(struct rbug_context *rb_context, struct rbug_shader *rb_shader) { struct pipe_context *pipe = rb_context->pipe; /* works on context as well since its just a macro */ rbug_screen_remove_from_list(rb_context, shaders, rb_shader); switch(rb_shader->type) { case RBUG_SHADER_FRAGMENT: if (rb_shader->replaced_shader) pipe->delete_fs_state(pipe, rb_shader->replaced_shader); pipe->delete_fs_state(pipe, rb_shader->shader); break; case RBUG_SHADER_VERTEX: if (rb_shader->replaced_shader) pipe->delete_vs_state(pipe, rb_shader->replaced_shader); pipe->delete_vs_state(pipe, rb_shader->shader); break; case RBUG_SHADER_GEOM: if (rb_shader->replaced_shader) pipe->delete_gs_state(pipe, rb_shader->replaced_shader); pipe->delete_gs_state(pipe, rb_shader->shader); break; default: assert(0); } FREE(rb_shader->replaced_tokens); FREE(rb_shader->tokens); FREE(rb_shader); }