From: Jakob Bornecrantz Date: Tue, 4 May 2010 11:06:37 +0000 (+0100) Subject: rbug: Break out of trace X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2c3fb4ecce27f4c2468892241216a06fc77143c4;p=mesa.git rbug: Break out of trace --- diff --git a/SConstruct b/SConstruct index 3a4ff9a3fac..5181e1957f9 100644 --- a/SConstruct +++ b/SConstruct @@ -33,10 +33,10 @@ import common default_statetrackers = 'mesa' if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_drivers = 'softpipe,failover,svga,i915,i965,trace,identity,llvmpipe' + default_drivers = 'softpipe,failover,svga,i915,i965,trace,rbug,identity,llvmpipe' default_winsys = 'xlib' elif common.default_platform in ('winddk',): - default_drivers = 'softpipe,svga,i915,i965,trace,identity' + default_drivers = 'softpipe,svga,i915,i965,trace,rbug,identity' default_winsys = 'all' elif common.default_platform in ('embedded',): default_drivers = 'softpipe,llvmpipe' @@ -50,7 +50,7 @@ common.AddOptions(opts) opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python', 'xorg'])) opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, - ['softpipe', 'failover', 'svga', 'i915', 'i965', 'trace', 'r300', 'identity', 'llvmpipe', 'nouveau', 'nv50', 'nvfx'])) + ['softpipe', 'failover', 'svga', 'i915', 'i965', 'trace', 'rbug', 'r300', 'identity', 'llvmpipe', 'nouveau', 'nv50', 'nvfx'])) opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'vmware', 'i915', 'i965', 'gdi', 'radeon', 'graw-xlib'])) @@ -102,9 +102,11 @@ Export([ ####################################################################### # Environment setup -# Always build trace, identity, softpipe, and llvmpipe (where possible) +# Always build trace, rbug, identity, softpipe, and llvmpipe (where possible) if 'trace' not in env['drivers']: env['drivers'].append('trace') +if 'rbug' not in env['drivers']: + env['drivers'].append('rbug') if 'identity' not in env['drivers']: env['drivers'].append('identity') if 'softpipe' not in env['drivers']: diff --git a/configs/default b/configs/default index 4a5d3fd37a0..f0395ce7d9e 100644 --- a/configs/default +++ b/configs/default @@ -108,7 +108,7 @@ EGL_DRIVERS_DIRS = glx # Gallium directories and GALLIUM_DIRS = auxiliary drivers state_trackers GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a -GALLIUM_DRIVERS_DIRS = softpipe trace identity i915 i965 svga r300 nvfx nv50 failover +GALLIUM_DRIVERS_DIRS = softpipe trace rbug identity i915 i965 svga r300 nvfx nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = sw sw/xlib GALLIUM_TARGET_DIRS = libgl-xlib diff --git a/configs/linux-cell b/configs/linux-cell index ac6a2088d31..2b0c41ed6ac 100644 --- a/configs/linux-cell +++ b/configs/linux-cell @@ -6,7 +6,7 @@ CONFIG_NAME = linux-cell # Omiting other gallium drivers: -GALLIUM_DRIVERS_DIRS = cell softpipe trace identity +GALLIUM_DRIVERS_DIRS = cell softpipe trace rbug identity # Compiler and flags diff --git a/configs/linux-opengl-es b/configs/linux-opengl-es index 5e31b8c52f2..fb65c02277d 100644 --- a/configs/linux-opengl-es +++ b/configs/linux-opengl-es @@ -23,7 +23,7 @@ GALLIUM_DRIVERS_DIRS = softpipe GALLIUM_STATE_TRACKERS_DIRS = es # build egl_x11_{swrast,i915}.so -GALLIUM_DRIVERS_DIRS += trace i915 +GALLIUM_DRIVERS_DIRS += trace rbug i915 GALLIUM_STATE_TRACKERS_DIRS += egl GALLIUM_WINSYS_DIRS += drm/intel GALLIUM_TARGET_DIRS += egl-swrast egl-i915 diff --git a/configure.ac b/configure.ac index 4acc6d5bacc..7f6f8db2463 100644 --- a/configure.ac +++ b/configure.ac @@ -474,7 +474,7 @@ GLU_DIRS="sgi" GALLIUM_DIRS="auxiliary drivers state_trackers" GALLIUM_TARGET_DIRS="" GALLIUM_WINSYS_DIRS="sw" -GALLIUM_DRIVERS_DIRS="softpipe failover trace identity" +GALLIUM_DRIVERS_DIRS="softpipe failover trace rbug identity" GALLIUM_STATE_TRACKERS_DIRS="" case "$mesa_driver" in diff --git a/src/gallium/drivers/rbug/Makefile b/src/gallium/drivers/rbug/Makefile new file mode 100644 index 00000000000..64e172fe5c1 --- /dev/null +++ b/src/gallium/drivers/rbug/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = rbug + +C_SOURCES = \ + rbug_core.c \ + rbug_context.c \ + rbug_objects.c \ + rbug_screen.c + +include ../../Makefile.template diff --git a/src/gallium/drivers/rbug/SConscript b/src/gallium/drivers/rbug/SConscript new file mode 100644 index 00000000000..3da6ac104a4 --- /dev/null +++ b/src/gallium/drivers/rbug/SConscript @@ -0,0 +1,14 @@ +Import('*') + +env = env.Clone() + +rbug = env.ConvenienceLibrary( + target = 'rbug', + source = [ + 'rbug_context.c', + 'rbug_core.c', + 'rbug_objects.c', + 'rbug_screen.c', + ]) + +Export('rbug') diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c new file mode 100644 index 00000000000..0bc9b32ab90 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -0,0 +1,908 @@ +/************************************************************************** + * + * 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 "pipe/p_context.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" + +#include "rbug_context.h" +#include "rbug_objects.h" + + +static void +rbug_destroy(struct pipe_context *_pipe) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->destroy(pipe); + + FREE(rb_pipe); +} + +static void +rbug_draw_arrays(struct pipe_context *_pipe, + unsigned prim, + unsigned start, + unsigned count) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->draw_arrays(pipe, + prim, + start, + count); +} + +static void +rbug_draw_elements(struct pipe_context *_pipe, + struct pipe_resource *_indexResource, + unsigned indexSize, + int indexBias, + unsigned prim, + unsigned start, + unsigned count) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_indexResource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *indexResource = rb_resource->resource; + + pipe->draw_elements(pipe, + indexResource, + indexSize, + indexBias, + prim, + start, + count); +} + +static void +rbug_draw_range_elements(struct pipe_context *_pipe, + struct pipe_resource *_indexResource, + unsigned indexSize, + int indexBias, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_indexResource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *indexResource = rb_resource->resource; + + pipe->draw_range_elements(pipe, + indexResource, + indexSize, + indexBias, + minIndex, + maxIndex, + mode, + start, + count); +} + +static struct pipe_query * +rbug_create_query(struct pipe_context *_pipe, + unsigned query_type) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_query(pipe, + query_type); +} + +static void +rbug_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->destroy_query(pipe, + query); +} + +static void +rbug_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->begin_query(pipe, + query); +} + +static void +rbug_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->end_query(pipe, + query); +} + +static boolean +rbug_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + uint64_t *result) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->get_query_result(pipe, + query, + wait, + result); +} + +static void * +rbug_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *blend) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_blend_state(pipe, + blend); +} + +static void +rbug_bind_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_blend_state(pipe, + blend); +} + +static void +rbug_delete_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_blend_state(pipe, + blend); +} + +static void * +rbug_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *sampler) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_sampler_state(pipe, + sampler); +} + +static void +rbug_bind_fragment_sampler_states(struct pipe_context *_pipe, + unsigned num_samplers, + void **samplers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_fragment_sampler_states(pipe, + num_samplers, + samplers); +} + +static void +rbug_bind_vertex_sampler_states(struct pipe_context *_pipe, + unsigned num_samplers, + void **samplers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_vertex_sampler_states(pipe, + num_samplers, + samplers); +} + +static void +rbug_delete_sampler_state(struct pipe_context *_pipe, + void *sampler) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_sampler_state(pipe, + sampler); +} + +static void * +rbug_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_rasterizer_state(pipe, + rasterizer); +} + +static void +rbug_bind_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_rasterizer_state(pipe, + rasterizer); +} + +static void +rbug_delete_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_rasterizer_state(pipe, + rasterizer); +} + +static void * +rbug_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +rbug_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +rbug_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void * +rbug_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *fs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_fs_state(pipe, + fs); +} + +static void +rbug_bind_fs_state(struct pipe_context *_pipe, + void *fs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_fs_state(pipe, + fs); +} + +static void +rbug_delete_fs_state(struct pipe_context *_pipe, + void *fs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_fs_state(pipe, + fs); +} + +static void * +rbug_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_vs_state(pipe, + vs); +} + +static void +rbug_bind_vs_state(struct pipe_context *_pipe, + void *vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_vs_state(pipe, + vs); +} + +static void +rbug_delete_vs_state(struct pipe_context *_pipe, + void *vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_vs_state(pipe, + vs); +} + + +static void * +rbug_create_vertex_elements_state(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *vertex_elements) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + return pipe->create_vertex_elements_state(pipe, + num_elements, + vertex_elements); +} + +static void +rbug_bind_vertex_elements_state(struct pipe_context *_pipe, + void *velems) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->bind_vertex_elements_state(pipe, + velems); +} + +static void +rbug_delete_vertex_elements_state(struct pipe_context *_pipe, + void *velems) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->delete_vertex_elements_state(pipe, + velems); +} + +static void +rbug_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *blend_color) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_blend_color(pipe, + blend_color); +} + +static void +rbug_set_stencil_ref(struct pipe_context *_pipe, + const struct pipe_stencil_ref *stencil_ref) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_stencil_ref(pipe, + stencil_ref); +} + +static void +rbug_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *clip) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_clip_state(pipe, + clip); +} + +static void +rbug_set_constant_buffer(struct pipe_context *_pipe, + uint shader, + uint index, + struct pipe_resource *_resource) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *unwrapped_resource; + struct pipe_resource *resource = NULL; + + /* XXX hmm? unwrap the input state */ + if (_resource) { + unwrapped_resource = rbug_resource_unwrap(_resource); + resource = unwrapped_resource; + } + + pipe->set_constant_buffer(pipe, + shader, + index, + resource); +} + +static void +rbug_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *_state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_framebuffer_state unwrapped_state; + struct pipe_framebuffer_state *state = NULL; + unsigned i; + + /* unwrap the input state */ + if (_state) { + memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); + for(i = 0; i < _state->nr_cbufs; i++) + unwrapped_state.cbufs[i] = rbug_surface_unwrap(_state->cbufs[i]); + for (; i < PIPE_MAX_COLOR_BUFS; i++) + unwrapped_state.cbufs[i] = NULL; + unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf); + state = &unwrapped_state; + } + + pipe->set_framebuffer_state(pipe, + state); +} + +static void +rbug_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *poly_stipple) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_polygon_stipple(pipe, + poly_stipple); +} + +static void +rbug_set_scissor_state(struct pipe_context *_pipe, + const struct pipe_scissor_state *scissor) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_scissor_state(pipe, + scissor); +} + +static void +rbug_set_viewport_state(struct pipe_context *_pipe, + const struct pipe_viewport_state *viewport) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->set_viewport_state(pipe, + viewport); +} + +static void +rbug_set_fragment_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **_views) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view **views = NULL; + unsigned i; + + if (_views) { + for (i = 0; i < num; i++) + unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]); + for (; i < PIPE_MAX_SAMPLERS; i++) + unwrapped_views[i] = NULL; + + views = unwrapped_views; + } + + pipe->set_fragment_sampler_views(pipe, num, views); +} + +static void +rbug_set_vertex_sampler_views(struct pipe_context *_pipe, + unsigned num, + struct pipe_sampler_view **_views) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view **views = NULL; + unsigned i; + + if (_views) { + for (i = 0; i < num; i++) + unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]); + for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++) + unwrapped_views[i] = NULL; + + views = unwrapped_views; + } + + pipe->set_vertex_sampler_views(pipe, num, views); +} + +static void +rbug_set_vertex_buffers(struct pipe_context *_pipe, + unsigned num_buffers, + const struct pipe_vertex_buffer *_buffers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS]; + struct pipe_vertex_buffer *buffers = NULL; + unsigned i; + + if (num_buffers) { + memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); + for (i = 0; i < num_buffers; i++) + unwrapped_buffers[i].buffer = rbug_resource_unwrap(_buffers[i].buffer); + buffers = unwrapped_buffers; + } + + pipe->set_vertex_buffers(pipe, + num_buffers, + buffers); +} +static void +rbug_surface_copy(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + struct pipe_surface *_src, + unsigned srcx, + unsigned srcy, + unsigned width, + unsigned height) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_surface *rb_surface_dst = rbug_surface(_dst); + struct rbug_surface *rb_surface_src = rbug_surface(_src); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_surface *dst = rb_surface_dst->surface; + struct pipe_surface *src = rb_surface_src->surface; + + pipe->surface_copy(pipe, + dst, + dstx, + dsty, + src, + srcx, + srcy, + width, + height); +} + +static void +rbug_surface_fill(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + unsigned width, + unsigned height, + unsigned value) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_surface *rb_surface_dst = rbug_surface(_dst); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_surface *dst = rb_surface_dst->surface; + + pipe->surface_fill(pipe, + dst, + dstx, + dsty, + width, + height, + value); +} + +static void +rbug_clear(struct pipe_context *_pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->clear(pipe, + buffers, + rgba, + depth, + stencil); +} + +static void +rbug_flush(struct pipe_context *_pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + pipe->flush(pipe, + flags, + fence); +} + +static unsigned int +rbug_is_resource_referenced(struct pipe_context *_pipe, + struct pipe_resource *_resource, + unsigned face, + unsigned level) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + + return pipe->is_resource_referenced(pipe, + resource, + face, + level); +} + +static struct pipe_sampler_view * +rbug_context_create_sampler_view(struct pipe_context *_pipe, + struct pipe_resource *_resource, + const struct pipe_sampler_view *templ) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + struct pipe_sampler_view *result; + + result = pipe->create_sampler_view(pipe, + resource, + templ); + + if (result) + return rbug_sampler_view_create(rb_pipe, rb_resource, result); + return NULL; +} + +static void +rbug_context_sampler_view_destroy(struct pipe_context *_pipe, + struct pipe_sampler_view *_view) +{ + rbug_sampler_view_destroy(rbug_context(_pipe), + rbug_sampler_view(_view)); +} + +static struct pipe_transfer * +rbug_context_get_transfer(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + struct pipe_transfer *result; + + result = context->get_transfer(context, + resource, + sr, + usage, + box); + + if (result) + return rbug_transfer_create(rb_pipe, rb_resource, result); + return NULL; +} + +static void +rbug_context_transfer_destroy(struct pipe_context *_pipe, + struct pipe_transfer *_transfer) +{ + rbug_transfer_destroy(rbug_context(_pipe), + rbug_transfer(_transfer)); +} + +static void * +rbug_context_transfer_map(struct pipe_context *_context, + struct pipe_transfer *_transfer) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_transfer *transfer = rb_transfer->transfer; + + return context->transfer_map(context, + transfer); +} + + + +static void +rbug_context_transfer_flush_region(struct pipe_context *_context, + struct pipe_transfer *_transfer, + const struct pipe_box *box) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_transfer *transfer = rb_transfer->transfer; + + context->transfer_flush_region(context, + transfer, + box); +} + + +static void +rbug_context_transfer_unmap(struct pipe_context *_context, + struct pipe_transfer *_transfer) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_transfer *transfer = rb_transfer->transfer; + + context->transfer_unmap(context, + transfer); +} + + +static void +rbug_context_transfer_inline_write(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) +{ + struct rbug_context *rb_pipe = rbug_context(_context); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_context *context = rb_pipe->pipe; + struct pipe_resource *resource = rb_resource->resource; + + context->transfer_inline_write(context, + resource, + sr, + usage, + box, + data, + stride, + slice_stride); +} + + +struct pipe_context * +rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) +{ + struct rbug_context *rb_pipe; + (void)rbug_screen(_screen); + + rb_pipe = CALLOC_STRUCT(rbug_context); + if (!rb_pipe) { + return NULL; + } + + rb_pipe->base.winsys = NULL; + rb_pipe->base.screen = _screen; + rb_pipe->base.priv = pipe->priv; /* expose wrapped data */ + rb_pipe->base.draw = NULL; + + rb_pipe->base.destroy = rbug_destroy; + rb_pipe->base.draw_arrays = rbug_draw_arrays; + rb_pipe->base.draw_elements = rbug_draw_elements; + rb_pipe->base.draw_range_elements = rbug_draw_range_elements; + rb_pipe->base.create_query = rbug_create_query; + rb_pipe->base.destroy_query = rbug_destroy_query; + rb_pipe->base.begin_query = rbug_begin_query; + rb_pipe->base.end_query = rbug_end_query; + rb_pipe->base.get_query_result = rbug_get_query_result; + rb_pipe->base.create_blend_state = rbug_create_blend_state; + rb_pipe->base.bind_blend_state = rbug_bind_blend_state; + rb_pipe->base.delete_blend_state = rbug_delete_blend_state; + rb_pipe->base.create_sampler_state = rbug_create_sampler_state; + rb_pipe->base.bind_fragment_sampler_states = rbug_bind_fragment_sampler_states; + rb_pipe->base.bind_vertex_sampler_states = rbug_bind_vertex_sampler_states; + rb_pipe->base.delete_sampler_state = rbug_delete_sampler_state; + rb_pipe->base.create_rasterizer_state = rbug_create_rasterizer_state; + rb_pipe->base.bind_rasterizer_state = rbug_bind_rasterizer_state; + rb_pipe->base.delete_rasterizer_state = rbug_delete_rasterizer_state; + rb_pipe->base.create_depth_stencil_alpha_state = rbug_create_depth_stencil_alpha_state; + rb_pipe->base.bind_depth_stencil_alpha_state = rbug_bind_depth_stencil_alpha_state; + rb_pipe->base.delete_depth_stencil_alpha_state = rbug_delete_depth_stencil_alpha_state; + rb_pipe->base.create_fs_state = rbug_create_fs_state; + rb_pipe->base.bind_fs_state = rbug_bind_fs_state; + rb_pipe->base.delete_fs_state = rbug_delete_fs_state; + rb_pipe->base.create_vs_state = rbug_create_vs_state; + rb_pipe->base.bind_vs_state = rbug_bind_vs_state; + rb_pipe->base.delete_vs_state = rbug_delete_vs_state; + rb_pipe->base.create_vertex_elements_state = rbug_create_vertex_elements_state; + rb_pipe->base.bind_vertex_elements_state = rbug_bind_vertex_elements_state; + rb_pipe->base.delete_vertex_elements_state = rbug_delete_vertex_elements_state; + rb_pipe->base.set_blend_color = rbug_set_blend_color; + rb_pipe->base.set_stencil_ref = rbug_set_stencil_ref; + rb_pipe->base.set_clip_state = rbug_set_clip_state; + rb_pipe->base.set_constant_buffer = rbug_set_constant_buffer; + rb_pipe->base.set_framebuffer_state = rbug_set_framebuffer_state; + rb_pipe->base.set_polygon_stipple = rbug_set_polygon_stipple; + rb_pipe->base.set_scissor_state = rbug_set_scissor_state; + rb_pipe->base.set_viewport_state = rbug_set_viewport_state; + rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views; + rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views; + rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers; + rb_pipe->base.surface_copy = rbug_surface_copy; + rb_pipe->base.surface_fill = rbug_surface_fill; + rb_pipe->base.clear = rbug_clear; + rb_pipe->base.flush = rbug_flush; + rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced; + rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view; + rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy; + rb_pipe->base.get_transfer = rbug_context_get_transfer; + rb_pipe->base.transfer_destroy = rbug_context_transfer_destroy; + rb_pipe->base.transfer_map = rbug_context_transfer_map; + rb_pipe->base.transfer_unmap = rbug_context_transfer_unmap; + rb_pipe->base.transfer_flush_region = rbug_context_transfer_flush_region; + rb_pipe->base.transfer_inline_write = rbug_context_transfer_inline_write; + + rb_pipe->pipe = pipe; + + return &rb_pipe->base; +} diff --git a/src/gallium/drivers/rbug/rbug_context.h b/src/gallium/drivers/rbug/rbug_context.h new file mode 100644 index 00000000000..08ff050a9a3 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_context.h @@ -0,0 +1,108 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef RBUG_CONTEXT_H +#define RBUG_CONTEXT_H + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + +#include "rbug_screen.h" + + +struct rbug_context { + struct pipe_context base; /**< base class */ + + struct pipe_context *pipe; + + struct rbug_list list; + + /* call locking */ + pipe_mutex call_mutex; + + /* current state */ + struct { + struct rbug_shader *fs; + struct rbug_shader *vs; + + struct rbug_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; + unsigned num_sampler_views; + + struct rbug_sampler_view *vert_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned num_vert_sampler_views; + + unsigned nr_cbufs; + struct rbug_resource *cbufs[PIPE_MAX_COLOR_BUFS]; + struct rbug_resource *zsbuf; + } curr; + + /* draw locking */ + pipe_mutex draw_mutex; + pipe_condvar draw_cond; + unsigned draw_num_rules; + int draw_blocker; + int draw_blocked; + + struct { + struct rbug_shader *fs; + struct rbug_shader *vs; + + struct rbug_sampler_view *sampler_view; + struct rbug_resource *surf; + + int blocker; + } draw_rule; + + /* list of state objects */ + pipe_mutex list_mutex; + unsigned num_shaders; + struct rbug_list shaders; +}; + +static INLINE struct rbug_context * +rbug_context(struct pipe_context *pipe) +{ + return (struct rbug_context *)pipe; +} + + +/********************************************************** + * rbug_context.c + */ + +struct pipe_context * +rbug_context_create(struct pipe_screen *screen, struct pipe_context *pipe); + + +/********************************************************** + * rbug_core.c + */ + +void rbug_notify_draw_blocked(struct rbug_context *rb_context); + + +#endif /* RBUG_CONTEXT_H */ diff --git a/src/gallium/drivers/rbug/rbug_core.c b/src/gallium/drivers/rbug/rbug_core.c new file mode 100644 index 00000000000..c0b1d97f460 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_core.c @@ -0,0 +1,869 @@ +/************************************************************************** + * + * 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 "os/os_thread.h" +#include "util/u_format.h" +#include "util/u_string.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_simple_list.h" +#include "util/u_network.h" +#include "os/os_time.h" + +#include "tgsi/tgsi_parse.h" + +#include "rbug_context.h" +#include "rbug_objects.h" + +#include "rbug/rbug.h" + +#include + +#define U642VOID(x) ((void *)(unsigned long)(x)) +#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) + +struct rbug_rbug +{ + struct rbug_screen *rb_screen; + struct rbug_connection *con; + pipe_thread thread; + boolean running; +}; + +PIPE_THREAD_ROUTINE(rbug_thread, void_rbug); + + +/********************************************************** + * Helper functions + */ + + +static struct rbug_context * +rbug_get_context_locked(struct rbug_screen *rb_screen, rbug_context_t ctx) +{ + struct rbug_context *rb_context = NULL; + struct rbug_list *ptr; + + foreach(ptr, &rb_screen->contexts) { + rb_context = (struct rbug_context *)((char*)ptr - offsetof(struct rbug_context, list)); + if (ctx == VOID2U64(rb_context)) + break; + rb_context = NULL; + } + + return rb_context; +} + +static struct rbug_shader * +rbug_get_shader_locked(struct rbug_context *rb_context, rbug_shader_t shdr) +{ + struct rbug_shader *tr_shdr = NULL; + struct rbug_list *ptr; + + foreach(ptr, &rb_context->shaders) { + tr_shdr = (struct rbug_shader *)((char*)ptr - offsetof(struct rbug_shader, list)); + if (shdr == VOID2U64(tr_shdr)) + break; + tr_shdr = NULL; + } + + return tr_shdr; +} + +static void * +rbug_shader_create_locked(struct pipe_context *pipe, + struct rbug_shader *tr_shdr, + struct tgsi_token *tokens) +{ + void *state = NULL; + struct pipe_shader_state pss = { 0 }; + pss.tokens = tokens; + +#if 0 + if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { + state = pipe->create_fs_state(pipe, &pss); + } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { + state = pipe->create_vs_state(pipe, &pss); + } else + assert(0); +#endif + + return state; +} + +static void +rbug_shader_bind_locked(struct pipe_context *pipe, + struct rbug_shader *tr_shdr, + void *state) +{ +#if 0 + if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { + pipe->bind_fs_state(pipe, state); + } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { + pipe->bind_vs_state(pipe, state); + } else + assert(0); +#endif +} + +static void +rbug_shader_delete_locked(struct pipe_context *pipe, + struct rbug_shader *tr_shdr, + void *state) +{ +#if 0 + if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { + pipe->delete_fs_state(pipe, state); + } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { + pipe->delete_vs_state(pipe, state); + } else + assert(0); +#endif +} + +/************************************************ + * Request handler functions + */ + + +static int +rbug_texture_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_resource *tr_tex = NULL; + struct rbug_list *ptr; + rbug_texture_t *texs; + int i = 0; + + pipe_mutex_lock(rb_screen->list_mutex); + texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t)); + foreach(ptr, &rb_screen->resources) { + tr_tex = (struct rbug_resource *)((char*)ptr - offsetof(struct rbug_resource, list)); + texs[i++] = VOID2U64(tr_tex); + } + pipe_mutex_unlock(rb_screen->list_mutex); + + rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL); + FREE(texs); + + return 0; +} + +static int +rbug_texture_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_resource *tr_tex = NULL; + struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header; + struct rbug_list *ptr; + struct pipe_resource *t; + + pipe_mutex_lock(rb_screen->list_mutex); + foreach(ptr, &rb_screen->resources) { + tr_tex = (struct rbug_resource *)((char*)ptr - offsetof(struct rbug_resource, list)); + if (gpti->texture == VOID2U64(tr_tex)) + break; + tr_tex = NULL; + } + + if (!tr_tex) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + t = tr_tex->resource; + rbug_send_texture_info_reply(tr_rbug->con, serial, + t->target, t->format, + &t->width0, 1, + &t->height0, 1, + &t->depth0, 1, + util_format_get_blockwidth(t->format), + util_format_get_blockheight(t->format), + util_format_get_blocksize(t->format), + t->last_level, + t->nr_samples, + t->bind, + NULL); + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_resource *tr_tex = NULL; + struct rbug_list *ptr; + + struct pipe_context *context = rb_screen->private_context; + struct pipe_resource *tex; + struct pipe_transfer *t; + + void *map; + + pipe_mutex_lock(rb_screen->list_mutex); + foreach(ptr, &rb_screen->resources) { + tr_tex = (struct rbug_resource *)((char*)ptr - offsetof(struct rbug_resource, list)); + if (gptr->texture == VOID2U64(tr_tex)) + break; + tr_tex = NULL; + } + + if (!tr_tex) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + tex = tr_tex->resource; + t = pipe_get_transfer(context, tex, + gptr->face, gptr->level, gptr->zslice, + PIPE_TRANSFER_READ, + gptr->x, gptr->y, gptr->w, gptr->h); + + map = context->transfer_map(context, t); + + rbug_send_texture_read_reply(tr_rbug->con, serial, + t->resource->format, + util_format_get_blockwidth(t->resource->format), + util_format_get_blockheight(t->resource->format), + util_format_get_blocksize(t->resource->format), + (uint8_t*)map, + t->stride * util_format_get_nblocksy(t->resource->format, + t->box.height), + t->stride, + NULL); + + context->transfer_unmap(context, t); + context->transfer_destroy(context, t); + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_list *ptr; + struct rbug_context *rb_context = NULL; + rbug_context_t *ctxs; + int i = 0; + + pipe_mutex_lock(rb_screen->list_mutex); + ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t)); + foreach(ptr, &rb_screen->contexts) { + rb_context = (struct rbug_context *)((char*)ptr - offsetof(struct rbug_context, list)); + ctxs[i++] = VOID2U64(rb_context); + } + pipe_mutex_unlock(rb_screen->list_mutex); + + rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL); + FREE(ctxs); + + return 0; +} + +static int +rbug_context_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS]; + rbug_texture_t texs[PIPE_MAX_SAMPLERS]; + int i; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, info->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(rb_context->draw_mutex); + pipe_mutex_lock(rb_context->call_mutex); + + for (i = 0; i < rb_context->curr.nr_cbufs; i++) + cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]); + + for (i = 0; i < rb_context->curr.num_sampler_views; i++) + texs[i] = VOID2U64(rb_context->curr.sampler_views[i]); + + rbug_send_context_info_reply(tr_rbug->con, serial, + VOID2U64(rb_context->curr.vs), VOID2U64(rb_context->curr.fs), + texs, rb_context->curr.num_sampler_views, + cbufs, rb_context->curr.nr_cbufs, + VOID2U64(rb_context->curr.zsbuf), + rb_context->draw_blocker, rb_context->draw_blocked, NULL); + + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_context->draw_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_block(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, block->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + rb_context->draw_blocker |= block->block; + pipe_mutex_unlock(rb_context->draw_mutex); + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, step->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + if (rb_context->draw_blocked & RBUG_BLOCK_RULE) { + if (step->step & RBUG_BLOCK_RULE) + rb_context->draw_blocked &= ~RBUG_BLOCK_MASK; + } else { + rb_context->draw_blocked &= ~step->step; + } + pipe_mutex_unlock(rb_context->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(rb_context->draw_cond); +#endif + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, unblock->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + if (rb_context->draw_blocked & RBUG_BLOCK_RULE) { + if (unblock->unblock & RBUG_BLOCK_RULE) + rb_context->draw_blocked &= ~RBUG_BLOCK_MASK; + } else { + rb_context->draw_blocked &= ~unblock->unblock; + } + rb_context->draw_blocker &= ~unblock->unblock; + pipe_mutex_unlock(rb_context->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(rb_context->draw_cond); +#endif + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, rule->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->draw_mutex); + rb_context->draw_rule.vs = U642VOID(rule->vertex); + rb_context->draw_rule.fs = U642VOID(rule->fragment); + rb_context->draw_rule.sampler_view = U642VOID(rule->texture); + rb_context->draw_rule.surf = U642VOID(rule->surface); + rb_context->draw_rule.blocker = rule->block; + rb_context->draw_blocker |= RBUG_BLOCK_RULE; + pipe_mutex_unlock(rb_context->draw_mutex); + +#ifdef PIPE_THREAD_HAVE_CONDVAR + pipe_condvar_broadcast(rb_context->draw_cond); +#endif + + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, flush->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(rb_context->call_mutex); + + rb_context->pipe->flush(rb_context->pipe, flush->flags, NULL); + + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + struct rbug_list *ptr; + rbug_shader_t *shdrs; + int i = 0; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, list->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t)); + foreach(ptr, &rb_context->shaders) { + tr_shdr = (struct rbug_shader *)((char*)ptr - offsetof(struct rbug_shader, list)); + shdrs[i++] = VOID2U64(tr_shdr); + } + + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL); + FREE(shdrs); + + return 0; +} + +static int +rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + unsigned original_len; + unsigned replaced_len; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, info->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, info->shader); + + if (!tr_shdr) { + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* just in case */ + assert(sizeof(struct tgsi_token) == 4); + + original_len = tgsi_num_tokens(tr_shdr->tokens); + if (tr_shdr->replaced_tokens) + replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens); + else + replaced_len = 0; + + rbug_send_shader_info_reply(tr_rbug->con, serial, + (uint32_t*)tr_shdr->tokens, original_len, + (uint32_t*)tr_shdr->replaced_tokens, replaced_len, + tr_shdr->disabled, + NULL); + + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header) +{ + struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, dis->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, dis->shader); + + if (!tr_shdr) { + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + tr_shdr->disabled = dis->disable; + + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; +} + +static int +rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header) +{ + struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header; + + struct rbug_screen *rb_screen = tr_rbug->rb_screen; + struct rbug_context *rb_context = NULL; + struct rbug_shader *tr_shdr = NULL; + struct pipe_context *pipe = NULL; + void *state; + + pipe_mutex_lock(rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, rep->context); + + if (!rb_context) { + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + pipe_mutex_lock(rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, rep->shader); + + if (!tr_shdr) { + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + pipe_mutex_lock(rb_context->call_mutex); + + pipe = rb_context->pipe; + + /* remove old replaced shader */ + if (tr_shdr->replaced_shader) { + /* if this shader is bound rebind the original shader */ + if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr) + rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader); + + FREE(tr_shdr->replaced_tokens); + rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader); + tr_shdr->replaced_shader = NULL; + tr_shdr->replaced_tokens = NULL; + } + + /* empty inputs means restore old which we did above */ + if (rep->tokens_len == 0) + goto out; + + tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens); + if (!tr_shdr->replaced_tokens) + goto err; + + state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens); + if (!state) + goto err; + + /* bind new shader if the shader is currently a bound */ + if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr) + rbug_shader_bind_locked(pipe, tr_shdr, state); + + /* save state */ + tr_shdr->replaced_shader = state; + +out: + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + + return 0; + +err: + FREE(tr_shdr->replaced_tokens); + tr_shdr->replaced_shader = NULL; + tr_shdr->replaced_tokens = NULL; + + pipe_mutex_unlock(rb_context->call_mutex); + pipe_mutex_unlock(rb_context->list_mutex); + pipe_mutex_unlock(rb_screen->list_mutex); + return -EINVAL; +} + +static boolean +rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial) +{ + int ret = 0; + + switch(header->opcode) { + case RBUG_OP_PING: + rbug_send_ping_reply(tr_rbug->con, serial, NULL); + break; + case RBUG_OP_TEXTURE_LIST: + ret = rbug_texture_list(tr_rbug, header, serial); + break; + case RBUG_OP_TEXTURE_INFO: + ret = rbug_texture_info(tr_rbug, header, serial); + break; + case RBUG_OP_TEXTURE_READ: + ret = rbug_texture_read(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_LIST: + ret = rbug_context_list(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_INFO: + ret = rbug_context_info(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_BLOCK: + ret = rbug_context_draw_block(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_STEP: + ret = rbug_context_draw_step(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_UNBLOCK: + ret = rbug_context_draw_unblock(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_DRAW_RULE: + ret = rbug_context_draw_rule(tr_rbug, header, serial); + break; + case RBUG_OP_CONTEXT_FLUSH: + ret = rbug_context_flush(tr_rbug, header, serial); + break; + case RBUG_OP_SHADER_LIST: + ret = rbug_shader_list(tr_rbug, header, serial); + break; + case RBUG_OP_SHADER_INFO: + ret = rbug_shader_info(tr_rbug, header, serial); + break; + case RBUG_OP_SHADER_DISABLE: + ret = rbug_shader_disable(tr_rbug, header); + break; + case RBUG_OP_SHADER_REPLACE: + ret = rbug_shader_replace(tr_rbug, header); + break; + default: + debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode); + ret = -ENOSYS; + break; + } + rbug_free_header(header); + + if (ret) + rbug_send_error_reply(tr_rbug->con, serial, ret, NULL); + + return TRUE; +} + +static void +rbug_con(struct rbug_rbug *tr_rbug) +{ + struct rbug_header *header; + uint32_t serial; + + debug_printf("%s - connection received\n", __FUNCTION__); + + while(tr_rbug->running) { + header = rbug_get_message(tr_rbug->con, &serial); + if (!header) + break; + + if (!rbug_header(tr_rbug, header, serial)) + break; + } + + debug_printf("%s - connection closed\n", __FUNCTION__); + + rbug_disconnect(tr_rbug->con); + tr_rbug->con = NULL; +} + +PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug) +{ + struct rbug_rbug *tr_rbug = void_tr_rbug; + uint16_t port = 13370; + int s = -1; + int c; + + u_socket_init(); + + for (;port <= 13379 && s < 0; port++) + s = u_socket_listen_on_port(port); + + if (s < 0) { + debug_printf("rbug_rbug - failed to listen\n"); + return NULL; + } + + u_socket_block(s, false); + + debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port); + + while(tr_rbug->running) { + os_time_sleep(1); + + c = u_socket_accept(s); + if (c < 0) + continue; + + u_socket_block(c, true); + tr_rbug->con = rbug_from_socket(c); + + rbug_con(tr_rbug); + + u_socket_close(c); + } + + u_socket_close(s); + + u_socket_stop(); + + return NULL; +} + +/********************************************************** + * + */ + +struct rbug_rbug * +rbug_start(struct rbug_screen *rb_screen) +{ + struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug); + if (!tr_rbug) + return NULL; + + tr_rbug->rb_screen = rb_screen; + tr_rbug->running = TRUE; + tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug); + + return tr_rbug; +} + +void +rbug_stop(struct rbug_rbug *tr_rbug) +{ + if (!tr_rbug) + return; + + tr_rbug->running = false; + pipe_thread_wait(tr_rbug->thread); + + FREE(tr_rbug); + + return; +} + +void +rbug_notify_draw_blocked(struct rbug_context *rb_context) +{ + struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen); + struct rbug_rbug *tr_rbug = rb_screen->rbug; + + if (tr_rbug && tr_rbug->con) + rbug_send_context_draw_blocked(tr_rbug->con, + VOID2U64(rb_context), rb_context->draw_blocked, NULL); +} diff --git a/src/gallium/drivers/rbug/rbug_objects.c b/src/gallium/drivers/rbug/rbug_objects.c new file mode 100644 index 00000000000..4f9b23263b9 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_objects.c @@ -0,0 +1,195 @@ +/************************************************************************** + * + * 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/u_simple_list.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; + + 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); + 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_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; + pipe_resource_reference(&rb_surface->base.texture, &rb_resource->base); + rb_surface->surface = surface; + + return &rb_surface->base; + +error: + pipe_surface_reference(&surface, NULL); + return NULL; +} + +void +rbug_surface_destroy(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->resource); + rb_view->base.context = rb_context->pipe; + 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); + rb_context->pipe->sampler_view_destroy(rb_context->pipe, + rb_view->sampler_view); + 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_destroy(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); + rb_transfer->pipe->transfer_destroy(rb_context->pipe, + rb_transfer->transfer); + FREE(rb_transfer); +} + diff --git a/src/gallium/drivers/rbug/rbug_objects.h b/src/gallium/drivers/rbug/rbug_objects.h new file mode 100644 index 00000000000..7f48c01b577 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_objects.h @@ -0,0 +1,209 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef RBUG_OBJECTS_H +#define RBUG_OBJECTS_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "rbug_screen.h" + +struct rbug_context; + + +struct rbug_resource +{ + struct pipe_resource base; + + struct pipe_resource *resource; + + struct rbug_list list; +}; + + +struct rbug_shader +{ + struct rbug_list list; + + void *shader; + void *tokens; + void *replaced_shader; + void *replaced_tokens; + + boolean disabled; +}; + + +struct rbug_sampler_view +{ + struct pipe_sampler_view base; + + struct pipe_sampler_view *sampler_view; +}; + + +struct rbug_surface +{ + struct pipe_surface base; + + struct pipe_surface *surface; +}; + + +struct rbug_transfer +{ + struct pipe_transfer base; + + struct pipe_context *pipe; + struct pipe_transfer *transfer; +}; + + +static INLINE struct rbug_resource * +rbug_resource(struct pipe_resource *_resource) +{ + if (!_resource) + return NULL; + (void)rbug_screen(_resource->screen); + return (struct rbug_resource *)_resource; +} + +static INLINE struct rbug_sampler_view * +rbug_sampler_view(struct pipe_sampler_view *_sampler_view) +{ + if (!_sampler_view) + return NULL; + (void)rbug_resource(_sampler_view->texture); + return (struct rbug_sampler_view *)_sampler_view; +} + +static INLINE struct rbug_surface * +rbug_surface(struct pipe_surface *_surface) +{ + if (!_surface) + return NULL; + (void)rbug_resource(_surface->texture); + return (struct rbug_surface *)_surface; +} + +static INLINE struct rbug_transfer * +rbug_transfer(struct pipe_transfer *_transfer) +{ + if (!_transfer) + return NULL; + (void)rbug_resource(_transfer->resource); + return (struct rbug_transfer *)_transfer; +} + +static INLINE struct rbug_shader * +rbug_shader(void *_state) +{ + if (!_state) + return NULL; + return (struct rbug_shader *)_state; +} + +static INLINE struct pipe_resource * +rbug_resource_unwrap(struct pipe_resource *_resource) +{ + if (!_resource) + return NULL; + return rbug_resource(_resource)->resource; +} + +static INLINE struct pipe_sampler_view * +rbug_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view) +{ + if (!_sampler_view) + return NULL; + return rbug_sampler_view(_sampler_view)->sampler_view; +} + +static INLINE struct pipe_surface * +rbug_surface_unwrap(struct pipe_surface *_surface) +{ + if (!_surface) + return NULL; + return rbug_surface(_surface)->surface; +} + +static INLINE struct pipe_transfer * +rbug_transfer_unwrap(struct pipe_transfer *_transfer) +{ + if (!_transfer) + return NULL; + return rbug_transfer(_transfer)->transfer; +} + +static INLINE void * +rbug_shader_unwrap(void *_state) +{ + struct rbug_shader *shader; + if (!_state) + return NULL; + + shader = rbug_shader(_state); + return shader->replaced_shader ? shader->replaced_shader : shader->shader; +} + + +struct pipe_resource * +rbug_resource_create(struct rbug_screen *rb_screen, + struct pipe_resource *resource); + +void +rbug_resource_destroy(struct rbug_resource *rb_resource); + +struct pipe_surface * +rbug_surface_create(struct rbug_resource *rb_resource, + struct pipe_surface *surface); + +void +rbug_surface_destroy(struct rbug_surface *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); + +void +rbug_sampler_view_destroy(struct rbug_context *rb_context, + struct rbug_sampler_view *rb_sampler_view); + +struct pipe_transfer * +rbug_transfer_create(struct rbug_context *rb_context, + struct rbug_resource *rb_resource, + struct pipe_transfer *transfer); + +void +rbug_transfer_destroy(struct rbug_context *rb_context, + struct rbug_transfer *rb_transfer); + + +#endif /* RBUG_OBJECTS_H */ diff --git a/src/gallium/drivers/rbug/rbug_public.h b/src/gallium/drivers/rbug/rbug_public.h new file mode 100644 index 00000000000..f3cb19a3405 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_public.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef RBUG_PUBLIC_H +#define RBUG_PUBLIC_H + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +rbug_screen_create(struct pipe_screen *screen); + +#endif /* RBUG_PUBLIC_H */ diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c new file mode 100644 index 00000000000..acdb1f6dc01 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_screen.c @@ -0,0 +1,345 @@ +/************************************************************************** + * + * 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 "pipe/p_screen.h" +#include "pipe/p_state.h" +#include "util/u_memory.h" +#include "util/u_debug.h" +#include "util/u_simple_list.h" + +#include "rbug_public.h" +#include "rbug_screen.h" +#include "rbug_context.h" +#include "rbug_objects.h" + +DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE); + +static void +rbug_screen_destroy(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + screen->destroy(screen); + + FREE(rb_screen); +} + +static const char * +rbug_screen_get_name(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_name(screen); +} + +static const char * +rbug_screen_get_vendor(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_vendor(screen); +} + +static int +rbug_screen_get_param(struct pipe_screen *_screen, + enum pipe_cap param) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_param(screen, + param); +} + +static float +rbug_screen_get_paramf(struct pipe_screen *_screen, + enum pipe_cap param) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_paramf(screen, + param); +} + +static boolean +rbug_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->is_format_supported(screen, + format, + target, + tex_usage, + geom_flags); +} + +static struct pipe_context * +rbug_screen_context_create(struct pipe_screen *_screen, + void *priv) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_context *result; + + result = screen->context_create(screen, priv); + if (result) + return rbug_context_create(_screen, result); + return NULL; +} + +static struct pipe_resource * +rbug_screen_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *result; + + result = screen->resource_create(screen, + templat); + + if (result) + return rbug_resource_create(rb_screen, result); + return NULL; +} + +static struct pipe_resource * +rbug_screen_resource_from_handle(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct winsys_handle *handle) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *result; + + result = screen->resource_from_handle(screen, templ, handle); + + result = rbug_resource_create(rbug_screen(_screen), result); + + return result; +} + +static boolean +rbug_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_resource *_resource, + struct winsys_handle *handle) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *resource = rb_resource->resource; + + return screen->resource_get_handle(screen, resource, handle); +} + + + +static void +rbug_screen_resource_destroy(struct pipe_screen *screen, + struct pipe_resource *_resource) +{ + rbug_resource_destroy(rbug_resource(_resource)); +} + +static struct pipe_surface * +rbug_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_resource *_resource, + unsigned face, + unsigned level, + unsigned zslice, + unsigned usage) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *resource = rb_resource->resource; + struct pipe_surface *result; + + result = screen->get_tex_surface(screen, + resource, + face, + level, + zslice, + usage); + + if (result) + return rbug_surface_create(rb_resource, result); + return NULL; +} + +static void +rbug_screen_tex_surface_destroy(struct pipe_surface *_surface) +{ + rbug_surface_destroy(rbug_surface(_surface)); +} + + + +static struct pipe_resource * +rbug_screen_user_buffer_create(struct pipe_screen *_screen, + void *ptr, + unsigned bytes, + unsigned usage) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *result; + + result = screen->user_buffer_create(screen, + ptr, + bytes, + usage); + + if (result) + return rbug_resource_create(rb_screen, result); + return NULL; +} + + + +static void +rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *_surface, + void *context_private) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_surface *rb_surface = rbug_surface(_surface); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_surface *surface = rb_surface->surface; + + screen->flush_frontbuffer(screen, + surface, + context_private); +} + +static void +rbug_screen_fence_reference(struct pipe_screen *_screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + screen->fence_reference(screen, + ptr, + fence); +} + +static int +rbug_screen_fence_signalled(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->fence_signalled(screen, + fence, + flags); +} + +static int +rbug_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->fence_finish(screen, + fence, + flags); +} + +struct pipe_screen * +rbug_screen_create(struct pipe_screen *screen) +{ + struct rbug_screen *rb_screen; + + if (!debug_get_option_rbug()) + return screen; + + rb_screen = CALLOC_STRUCT(rbug_screen); + if (!rb_screen) + return screen; + + pipe_mutex_init(rb_screen->list_mutex); + make_empty_list(&rb_screen->contexts); + make_empty_list(&rb_screen->resources); + make_empty_list(&rb_screen->surfaces); + make_empty_list(&rb_screen->transfers); + + rb_screen->base.winsys = NULL; + + rb_screen->base.destroy = rbug_screen_destroy; + rb_screen->base.get_name = rbug_screen_get_name; + rb_screen->base.get_vendor = rbug_screen_get_vendor; + rb_screen->base.get_param = rbug_screen_get_param; + rb_screen->base.get_paramf = rbug_screen_get_paramf; + rb_screen->base.is_format_supported = rbug_screen_is_format_supported; + rb_screen->base.context_create = rbug_screen_context_create; + rb_screen->base.resource_create = rbug_screen_resource_create; + rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle; + rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle; + rb_screen->base.resource_destroy = rbug_screen_resource_destroy; + rb_screen->base.get_tex_surface = rbug_screen_get_tex_surface; + rb_screen->base.tex_surface_destroy = rbug_screen_tex_surface_destroy; + rb_screen->base.user_buffer_create = rbug_screen_user_buffer_create; + rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer; + rb_screen->base.fence_reference = rbug_screen_fence_reference; + rb_screen->base.fence_signalled = rbug_screen_fence_signalled; + rb_screen->base.fence_finish = rbug_screen_fence_finish; + + rb_screen->screen = screen; + + rb_screen->private_context = screen->context_create(screen, NULL); + if (!rb_screen->private_context) + goto err_free; + + rb_screen->rbug = rbug_start(rb_screen); + + if (!rb_screen->rbug) + goto err_context; + + return &rb_screen->base; + +err_context: + rb_screen->private_context->destroy(rb_screen->private_context); +err_free: + FREE(rb_screen); + return screen; +} diff --git a/src/gallium/drivers/rbug/rbug_screen.h b/src/gallium/drivers/rbug/rbug_screen.h new file mode 100644 index 00000000000..a53afac05e9 --- /dev/null +++ b/src/gallium/drivers/rbug/rbug_screen.h @@ -0,0 +1,100 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef RBUG_SCREEN_H +#define RBUG_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + +#include "os/os_thread.h" + +struct rbug_list { + struct rbug_list *next; + struct rbug_list *prev; +}; + + +struct rbug_screen +{ + struct pipe_screen base; + + struct pipe_screen *screen; + struct pipe_context *private_context; + + /* remote debugger */ + struct rbug_rbug *rbug; + + pipe_mutex list_mutex; + int num_contexts; + int num_resources; + int num_surfaces; + int num_transfers; + struct rbug_list contexts; + struct rbug_list resources; + struct rbug_list surfaces; + struct rbug_list transfers; +}; + +static INLINE struct rbug_screen * +rbug_screen(struct pipe_screen *screen) +{ + return (struct rbug_screen *)screen; +} + +#define rbug_screen_add_to_list(scr, name, obj) \ + do { \ + pipe_mutex_lock(scr->list_mutex); \ + insert_at_head(&scr->name, &obj->list); \ + scr->num_##name++; \ + pipe_mutex_unlock(scr->list_mutex); \ + } while (0) + +#define rbug_screen_remove_from_list(scr, name, obj) \ + do { \ + pipe_mutex_lock(scr->list_mutex); \ + remove_from_list(&obj->list); \ + scr->num_##name--; \ + pipe_mutex_unlock(scr->list_mutex); \ + } while (0) + + + +/********************************************************** + * rbug_core.c + */ + +struct rbug_rbug; + +struct rbug_rbug * +rbug_start(struct rbug_screen *rb_screen); + +void +rbug_stop(struct rbug_rbug *rbug); + + +#endif /* RBUG_SCREEN_H */