From: Marek Olšák Date: Sat, 7 Apr 2018 18:01:12 +0000 (-0400) Subject: gallium: move ddebug, noop, rbug, trace to auxiliary to improve build times X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6ff0c6f4ebcb87ea6c6fe5a4ba90b548f666067d;p=mesa.git gallium: move ddebug, noop, rbug, trace to auxiliary to improve build times which also simplifies the build scripts. --- diff --git a/configure.ac b/configure.ac index 4ff3fceed29..33c8d0820d6 100644 --- a/configure.ac +++ b/configure.ac @@ -3011,21 +3011,17 @@ AC_CONFIG_FILES([Makefile src/gallium/auxiliary/Makefile src/gallium/auxiliary/pipe-loader/Makefile src/gallium/drivers/freedreno/Makefile - src/gallium/drivers/ddebug/Makefile src/gallium/drivers/i915/Makefile src/gallium/drivers/llvmpipe/Makefile - src/gallium/drivers/noop/Makefile src/gallium/drivers/nouveau/Makefile src/gallium/drivers/pl111/Makefile src/gallium/drivers/r300/Makefile src/gallium/drivers/r600/Makefile src/gallium/drivers/radeonsi/Makefile - src/gallium/drivers/rbug/Makefile src/gallium/drivers/softpipe/Makefile src/gallium/drivers/svga/Makefile src/gallium/drivers/swr/Makefile src/gallium/drivers/tegra/Makefile - src/gallium/drivers/trace/Makefile src/gallium/drivers/etnaviv/Makefile src/gallium/drivers/imx/Makefile src/gallium/drivers/vc4/Makefile diff --git a/src/gallium/Makefile.am b/src/gallium/Makefile.am index f1fd22cece2..e2e8eaece10 100644 --- a/src/gallium/Makefile.am +++ b/src/gallium/Makefile.am @@ -11,12 +11,6 @@ SUBDIRS += auxiliary/pipe-loader ## Gallium pipe drivers and their respective winsys' ## -SUBDIRS += \ - drivers/ddebug \ - drivers/noop \ - drivers/trace \ - drivers/rbug - ## freedreno/msm/kgsl if HAVE_GALLIUM_FREEDRENO SUBDIRS += drivers/freedreno winsys/freedreno/drm diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 9273db7e498..358c31e847e 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -14,10 +14,8 @@ SConscript('auxiliary/pipe-loader/SConscript') # These are common and work across all platforms SConscript([ 'drivers/llvmpipe/SConscript', - 'drivers/rbug/SConscript', 'drivers/softpipe/SConscript', 'drivers/svga/SConscript', - 'drivers/trace/SConscript', 'drivers/swr/SConscript', ]) diff --git a/src/gallium/auxiliary/Makefile.am b/src/gallium/auxiliary/Makefile.am index 95a325f96b3..07856e5a528 100644 --- a/src/gallium/auxiliary/Makefile.am +++ b/src/gallium/auxiliary/Makefile.am @@ -108,6 +108,9 @@ endif # NEED_GALLIUM_VL EXTRA_DIST = \ SConscript \ + driver_rbug/README \ + driver_trace/README \ + driver_trace/trace.xsl \ indices/u_indices.c \ indices/u_unfilled_indices.c \ indices/u_indices_gen.py \ diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index d70eb04e798..066746f2d0d 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -57,6 +57,35 @@ C_SOURCES := \ draw/draw_vs_exec.c \ draw/draw_vs.h \ draw/draw_vs_variant.c \ + driver_ddebug/dd_context.c \ + driver_ddebug/dd_draw.c \ + driver_ddebug/dd_pipe.h \ + driver_ddebug/dd_public.h \ + driver_ddebug/dd_screen.c \ + driver_ddebug/dd_util.h \ + driver_noop/noop_pipe.c \ + driver_noop/noop_public.h \ + driver_noop/noop_state.c \ + driver_rbug/rbug_context.c \ + driver_rbug/rbug_context.h \ + driver_rbug/rbug_core.c \ + driver_rbug/rbug_objects.c \ + driver_rbug/rbug_objects.h \ + driver_rbug/rbug_public.h \ + driver_rbug/rbug_screen.c \ + driver_rbug/rbug_screen.h \ + driver_trace/tr_context.c \ + driver_trace/tr_context.h \ + driver_trace/tr_dump.c \ + driver_trace/tr_dump_defines.h \ + driver_trace/tr_dump.h \ + driver_trace/tr_dump_state.c \ + driver_trace/tr_dump_state.h \ + driver_trace/tr_public.h \ + driver_trace/tr_screen.c \ + driver_trace/tr_screen.h \ + driver_trace/tr_texture.c \ + driver_trace/tr_texture.h \ hud/font.c \ hud/font.h \ hud/hud_context.c \ diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c new file mode 100644 index 00000000000..dd7b3e086cd --- /dev/null +++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c @@ -0,0 +1,877 @@ +/************************************************************************** + * + * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2008 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "dd_pipe.h" +#include "tgsi/tgsi_parse.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" + + +static void +safe_memcpy(void *dst, const void *src, size_t size) +{ + if (src) + memcpy(dst, src, size); + else + memset(dst, 0, size); +} + + +/******************************************************************** + * queries + */ + +static struct pipe_query * +dd_context_create_query(struct pipe_context *_pipe, unsigned query_type, + unsigned index) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct pipe_query *query; + + query = pipe->create_query(pipe, query_type, index); + + /* Wrap query object. */ + if (query) { + struct dd_query *dd_query = CALLOC_STRUCT(dd_query); + if (dd_query) { + dd_query->type = query_type; + dd_query->query = query; + query = (struct pipe_query *)dd_query; + } else { + pipe->destroy_query(pipe, query); + query = NULL; + } + } + + return query; +} + +static struct pipe_query * +dd_context_create_batch_query(struct pipe_context *_pipe, unsigned num_queries, + unsigned *query_types) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct pipe_query *query; + + query = pipe->create_batch_query(pipe, num_queries, query_types); + + /* Wrap query object. */ + if (query) { + struct dd_query *dd_query = CALLOC_STRUCT(dd_query); + if (dd_query) { + /* no special handling for batch queries yet */ + dd_query->type = query_types[0]; + dd_query->query = query; + query = (struct pipe_query *)dd_query; + } else { + pipe->destroy_query(pipe, query); + query = NULL; + } + } + + return query; +} + +static void +dd_context_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->destroy_query(pipe, dd_query_unwrap(query)); + FREE(query); +} + +static boolean +dd_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + return pipe->begin_query(pipe, dd_query_unwrap(query)); +} + +static bool +dd_context_end_query(struct pipe_context *_pipe, struct pipe_query *query) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + return pipe->end_query(pipe, dd_query_unwrap(query)); +} + +static boolean +dd_context_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, boolean wait, + union pipe_query_result *result) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, result); +} + +static void +dd_context_set_active_query_state(struct pipe_context *_pipe, boolean enable) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->set_active_query_state(pipe, enable); +} + +static void +dd_context_render_condition(struct pipe_context *_pipe, + struct pipe_query *query, boolean condition, + enum pipe_render_cond_flag mode) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_state *dstate = &dctx->draw_state; + + pipe->render_condition(pipe, dd_query_unwrap(query), condition, mode); + dstate->render_cond.query = dd_query(query); + dstate->render_cond.condition = condition; + dstate->render_cond.mode = mode; +} + + +/******************************************************************** + * constant (immutable) non-shader states + */ + +#define DD_CSO_CREATE(name, shortname) \ + static void * \ + dd_context_create_##name##_state(struct pipe_context *_pipe, \ + const struct pipe_##name##_state *state) \ + { \ + struct pipe_context *pipe = dd_context(_pipe)->pipe; \ + struct dd_state *hstate = CALLOC_STRUCT(dd_state); \ + \ + if (!hstate) \ + return NULL; \ + hstate->cso = pipe->create_##name##_state(pipe, state); \ + hstate->state.shortname = *state; \ + return hstate; \ + } + +#define DD_CSO_BIND(name, shortname) \ + static void \ + dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \ + { \ + struct dd_context *dctx = dd_context(_pipe); \ + struct pipe_context *pipe = dctx->pipe; \ + struct dd_state *hstate = state; \ + \ + dctx->draw_state.shortname = hstate; \ + pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \ + } + +#define DD_CSO_DELETE(name) \ + static void \ + dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \ + { \ + struct dd_context *dctx = dd_context(_pipe); \ + struct pipe_context *pipe = dctx->pipe; \ + struct dd_state *hstate = state; \ + \ + pipe->delete_##name##_state(pipe, hstate->cso); \ + FREE(hstate); \ + } + +#define DD_CSO_WHOLE(name, shortname) \ + DD_CSO_CREATE(name, shortname) \ + DD_CSO_BIND(name, shortname) \ + DD_CSO_DELETE(name) + +DD_CSO_WHOLE(blend, blend) +DD_CSO_WHOLE(rasterizer, rs) +DD_CSO_WHOLE(depth_stencil_alpha, dsa) + +DD_CSO_CREATE(sampler, sampler) +DD_CSO_DELETE(sampler) + +static void +dd_context_bind_sampler_states(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, unsigned count, void **states) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + memcpy(&dctx->draw_state.sampler_states[shader][start], states, + sizeof(void*) * count); + + if (states) { + void *samp[PIPE_MAX_SAMPLERS]; + int i; + + for (i = 0; i < count; i++) { + struct dd_state *s = states[i]; + samp[i] = s ? s->cso : NULL; + } + + pipe->bind_sampler_states(pipe, shader, start, count, samp); + } + else + pipe->bind_sampler_states(pipe, shader, start, count, NULL); +} + +static void * +dd_context_create_vertex_elements_state(struct pipe_context *_pipe, + unsigned num_elems, + const struct pipe_vertex_element *elems) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct dd_state *hstate = CALLOC_STRUCT(dd_state); + + if (!hstate) + return NULL; + hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems); + memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems); + hstate->state.velems.count = num_elems; + return hstate; +} + +DD_CSO_BIND(vertex_elements, velems) +DD_CSO_DELETE(vertex_elements) + + +/******************************************************************** + * shaders + */ + +#define DD_SHADER_NOCREATE(NAME, name) \ + static void \ + dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \ + { \ + struct dd_context *dctx = dd_context(_pipe); \ + struct pipe_context *pipe = dctx->pipe; \ + struct dd_state *hstate = state; \ + \ + dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \ + pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \ + } \ + \ + static void \ + dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \ + { \ + struct dd_context *dctx = dd_context(_pipe); \ + struct pipe_context *pipe = dctx->pipe; \ + struct dd_state *hstate = state; \ + \ + pipe->delete_##name##_state(pipe, hstate->cso); \ + if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \ + tgsi_free_tokens(hstate->state.shader.tokens); \ + FREE(hstate); \ + } + +#define DD_SHADER(NAME, name) \ + static void * \ + dd_context_create_##name##_state(struct pipe_context *_pipe, \ + const struct pipe_shader_state *state) \ + { \ + struct pipe_context *pipe = dd_context(_pipe)->pipe; \ + struct dd_state *hstate = CALLOC_STRUCT(dd_state); \ + \ + if (!hstate) \ + return NULL; \ + hstate->cso = pipe->create_##name##_state(pipe, state); \ + hstate->state.shader = *state; \ + if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \ + hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \ + return hstate; \ + } \ + \ + DD_SHADER_NOCREATE(NAME, name) + +DD_SHADER(FRAGMENT, fs) +DD_SHADER(VERTEX, vs) +DD_SHADER(GEOMETRY, gs) +DD_SHADER(TESS_CTRL, tcs) +DD_SHADER(TESS_EVAL, tes) + +static void * \ +dd_context_create_compute_state(struct pipe_context *_pipe, + const struct pipe_compute_state *state) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct dd_state *hstate = CALLOC_STRUCT(dd_state); + + if (!hstate) + return NULL; + hstate->cso = pipe->create_compute_state(pipe, state); + + hstate->state.shader.type = state->ir_type; + + if (state->ir_type == PIPE_SHADER_IR_TGSI) + hstate->state.shader.tokens = tgsi_dup_tokens(state->prog); + + return hstate; +} + +DD_SHADER_NOCREATE(COMPUTE, compute) + +/******************************************************************** + * immediate states + */ + +#define DD_IMM_STATE(name, type, deref, ref) \ + static void \ + dd_context_set_##name(struct pipe_context *_pipe, type deref) \ + { \ + struct dd_context *dctx = dd_context(_pipe); \ + struct pipe_context *pipe = dctx->pipe; \ + \ + dctx->draw_state.name = deref; \ + pipe->set_##name(pipe, ref); \ + } + +DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state) +DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state) +DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state) +DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask) +DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples) +DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state) +DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state) + +static void +dd_context_set_constant_buffer(struct pipe_context *_pipe, + enum pipe_shader_type shader, uint index, + const struct pipe_constant_buffer *constant_buffer) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.constant_buffers[shader][index], + constant_buffer, sizeof(*constant_buffer)); + pipe->set_constant_buffer(pipe, shader, index, constant_buffer); +} + +static void +dd_context_set_scissor_states(struct pipe_context *_pipe, + unsigned start_slot, unsigned num_scissors, + const struct pipe_scissor_state *states) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.scissors[start_slot], states, + sizeof(*states) * num_scissors); + pipe->set_scissor_states(pipe, start_slot, num_scissors, states); +} + +static void +dd_context_set_viewport_states(struct pipe_context *_pipe, + unsigned start_slot, unsigned num_viewports, + const struct pipe_viewport_state *states) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.viewports[start_slot], states, + sizeof(*states) * num_viewports); + pipe->set_viewport_states(pipe, start_slot, num_viewports, states); +} + +static void dd_context_set_tess_state(struct pipe_context *_pipe, + const float default_outer_level[4], + const float default_inner_level[2]) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + memcpy(dctx->draw_state.tess_default_levels, default_outer_level, + sizeof(float) * 4); + memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level, + sizeof(float) * 2); + pipe->set_tess_state(pipe, default_outer_level, default_inner_level); +} + + +/******************************************************************** + * views + */ + +static struct pipe_surface * +dd_context_create_surface(struct pipe_context *_pipe, + struct pipe_resource *resource, + const struct pipe_surface *surf_tmpl) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct pipe_surface *view = + pipe->create_surface(pipe, resource, surf_tmpl); + + if (!view) + return NULL; + view->context = _pipe; + return view; +} + +static void +dd_context_surface_destroy(struct pipe_context *_pipe, + struct pipe_surface *surf) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->surface_destroy(pipe, surf); +} + +static struct pipe_sampler_view * +dd_context_create_sampler_view(struct pipe_context *_pipe, + struct pipe_resource *resource, + const struct pipe_sampler_view *templ) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct pipe_sampler_view *view = + pipe->create_sampler_view(pipe, resource, templ); + + if (!view) + return NULL; + view->context = _pipe; + return view; +} + +static void +dd_context_sampler_view_destroy(struct pipe_context *_pipe, + struct pipe_sampler_view *view) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->sampler_view_destroy(pipe, view); +} + +static struct pipe_stream_output_target * +dd_context_create_stream_output_target(struct pipe_context *_pipe, + struct pipe_resource *res, + unsigned buffer_offset, + unsigned buffer_size) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + struct pipe_stream_output_target *view = + pipe->create_stream_output_target(pipe, res, buffer_offset, + buffer_size); + + if (!view) + return NULL; + view->context = _pipe; + return view; +} + +static void +dd_context_stream_output_target_destroy(struct pipe_context *_pipe, + struct pipe_stream_output_target *target) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->stream_output_target_destroy(pipe, target); +} + + +/******************************************************************** + * set states + */ + +static void +dd_context_set_sampler_views(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, unsigned num, + struct pipe_sampler_view **views) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views, + sizeof(views[0]) * num); + pipe->set_sampler_views(pipe, shader, start, num, views); +} + +static void +dd_context_set_shader_images(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, unsigned num, + const struct pipe_image_view *views) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.shader_images[shader][start], views, + sizeof(views[0]) * num); + pipe->set_shader_images(pipe, shader, start, num, views); +} + +static void +dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader, + unsigned start, unsigned num_buffers, + const struct pipe_shader_buffer *buffers) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers, + sizeof(buffers[0]) * num_buffers); + pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers); +} + +static void +dd_context_set_vertex_buffers(struct pipe_context *_pipe, + unsigned start, unsigned num_buffers, + const struct pipe_vertex_buffer *buffers) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers, + sizeof(buffers[0]) * num_buffers); + pipe->set_vertex_buffers(pipe, start, num_buffers, buffers); +} + +static void +dd_context_set_stream_output_targets(struct pipe_context *_pipe, + unsigned num_targets, + struct pipe_stream_output_target **tgs, + const unsigned *offsets) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_state *dstate = &dctx->draw_state; + + dstate->num_so_targets = num_targets; + safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets); + safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets); + pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets); +} + +void +dd_thread_join(struct dd_context *dctx) +{ + mtx_lock(&dctx->mutex); + dctx->kill_thread = true; + cnd_signal(&dctx->cond); + mtx_unlock(&dctx->mutex); + thrd_join(dctx->thread, NULL); +} + +static void +dd_context_destroy(struct pipe_context *_pipe) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + dd_thread_join(dctx); + mtx_destroy(&dctx->mutex); + cnd_destroy(&dctx->cond); + + assert(list_empty(&dctx->records)); + assert(!dctx->record_pending); + + if (pipe->set_log_context) { + pipe->set_log_context(pipe, NULL); + + if (dd_screen(dctx->base.screen)->dump_mode == DD_DUMP_ALL_CALLS) { + FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen), 0); + if (f) { + fprintf(f, "Remainder of driver log:\n\n"); + } + + u_log_new_page_print(&dctx->log, f); + fclose(f); + } + } + u_log_context_destroy(&dctx->log); + + pipe->destroy(pipe); + FREE(dctx); +} + + +/******************************************************************** + * miscellaneous + */ + +static void +dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->texture_barrier(pipe, flags); +} + +static void +dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->memory_barrier(pipe, flags); +} + +static bool +dd_context_resource_commit(struct pipe_context *_pipe, + struct pipe_resource *resource, + unsigned level, struct pipe_box *box, bool commit) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->resource_commit(pipe, resource, level, box, commit); +} + +static void +dd_context_get_sample_position(struct pipe_context *_pipe, + unsigned sample_count, unsigned sample_index, + float *out_value) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->get_sample_position(pipe, sample_count, sample_index, + out_value); +} + +static void +dd_context_invalidate_resource(struct pipe_context *_pipe, + struct pipe_resource *resource) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->invalidate_resource(pipe, resource); +} + +static enum pipe_reset_status +dd_context_get_device_reset_status(struct pipe_context *_pipe) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->get_device_reset_status(pipe); +} + +static void +dd_context_set_device_reset_callback(struct pipe_context *_pipe, + const struct pipe_device_reset_callback *cb) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->set_device_reset_callback(pipe, cb); +} + +static void +dd_context_emit_string_marker(struct pipe_context *_pipe, + const char *string, int len) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + pipe->emit_string_marker(pipe, string, len); + dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number); +} + +static void +dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream, + unsigned flags) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->dump_debug_state(pipe, stream, flags); +} + +static uint64_t +dd_context_create_texture_handle(struct pipe_context *_pipe, + struct pipe_sampler_view *view, + const struct pipe_sampler_state *state) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->create_texture_handle(pipe, view, state); +} + +static void +dd_context_delete_texture_handle(struct pipe_context *_pipe, uint64_t handle) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->delete_texture_handle(pipe, handle); +} + +static void +dd_context_make_texture_handle_resident(struct pipe_context *_pipe, + uint64_t handle, bool resident) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->make_texture_handle_resident(pipe, handle, resident); +} + +static uint64_t +dd_context_create_image_handle(struct pipe_context *_pipe, + const struct pipe_image_view *image) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + return pipe->create_image_handle(pipe, image); +} + +static void +dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->delete_image_handle(pipe, handle); +} + +static void +dd_context_make_image_handle_resident(struct pipe_context *_pipe, + uint64_t handle, unsigned access, + bool resident) +{ + struct pipe_context *pipe = dd_context(_pipe)->pipe; + + pipe->make_image_handle_resident(pipe, handle, access, resident); +} + +struct pipe_context * +dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe) +{ + struct dd_context *dctx; + + if (!pipe) + return NULL; + + dctx = CALLOC_STRUCT(dd_context); + if (!dctx) + goto fail; + + dctx->pipe = pipe; + dctx->base.priv = pipe->priv; /* expose wrapped priv data */ + dctx->base.screen = &dscreen->base; + dctx->base.stream_uploader = pipe->stream_uploader; + dctx->base.const_uploader = pipe->const_uploader; + + dctx->base.destroy = dd_context_destroy; + + CTX_INIT(render_condition); + CTX_INIT(create_query); + CTX_INIT(create_batch_query); + CTX_INIT(destroy_query); + CTX_INIT(begin_query); + CTX_INIT(end_query); + CTX_INIT(get_query_result); + CTX_INIT(set_active_query_state); + CTX_INIT(create_blend_state); + CTX_INIT(bind_blend_state); + CTX_INIT(delete_blend_state); + CTX_INIT(create_sampler_state); + CTX_INIT(bind_sampler_states); + CTX_INIT(delete_sampler_state); + CTX_INIT(create_rasterizer_state); + CTX_INIT(bind_rasterizer_state); + CTX_INIT(delete_rasterizer_state); + CTX_INIT(create_depth_stencil_alpha_state); + CTX_INIT(bind_depth_stencil_alpha_state); + CTX_INIT(delete_depth_stencil_alpha_state); + CTX_INIT(create_fs_state); + CTX_INIT(bind_fs_state); + CTX_INIT(delete_fs_state); + CTX_INIT(create_vs_state); + CTX_INIT(bind_vs_state); + CTX_INIT(delete_vs_state); + CTX_INIT(create_gs_state); + CTX_INIT(bind_gs_state); + CTX_INIT(delete_gs_state); + CTX_INIT(create_tcs_state); + CTX_INIT(bind_tcs_state); + CTX_INIT(delete_tcs_state); + CTX_INIT(create_tes_state); + CTX_INIT(bind_tes_state); + CTX_INIT(delete_tes_state); + CTX_INIT(create_compute_state); + CTX_INIT(bind_compute_state); + CTX_INIT(delete_compute_state); + CTX_INIT(create_vertex_elements_state); + CTX_INIT(bind_vertex_elements_state); + CTX_INIT(delete_vertex_elements_state); + CTX_INIT(set_blend_color); + CTX_INIT(set_stencil_ref); + CTX_INIT(set_sample_mask); + CTX_INIT(set_min_samples); + CTX_INIT(set_clip_state); + CTX_INIT(set_constant_buffer); + CTX_INIT(set_framebuffer_state); + CTX_INIT(set_polygon_stipple); + CTX_INIT(set_scissor_states); + CTX_INIT(set_viewport_states); + CTX_INIT(set_sampler_views); + CTX_INIT(set_tess_state); + CTX_INIT(set_shader_buffers); + CTX_INIT(set_shader_images); + CTX_INIT(set_vertex_buffers); + CTX_INIT(create_stream_output_target); + CTX_INIT(stream_output_target_destroy); + CTX_INIT(set_stream_output_targets); + CTX_INIT(create_sampler_view); + CTX_INIT(sampler_view_destroy); + CTX_INIT(create_surface); + CTX_INIT(surface_destroy); + CTX_INIT(texture_barrier); + CTX_INIT(memory_barrier); + CTX_INIT(resource_commit); + /* create_video_codec */ + /* create_video_buffer */ + /* set_compute_resources */ + /* set_global_binding */ + CTX_INIT(get_sample_position); + CTX_INIT(invalidate_resource); + CTX_INIT(get_device_reset_status); + CTX_INIT(set_device_reset_callback); + CTX_INIT(dump_debug_state); + CTX_INIT(emit_string_marker); + CTX_INIT(create_texture_handle); + CTX_INIT(delete_texture_handle); + CTX_INIT(make_texture_handle_resident); + CTX_INIT(create_image_handle); + CTX_INIT(delete_image_handle); + CTX_INIT(make_image_handle_resident); + + dd_init_draw_functions(dctx); + + u_log_context_init(&dctx->log); + if (pipe->set_log_context) + pipe->set_log_context(pipe, &dctx->log); + + dctx->draw_state.sample_mask = ~0; + + list_inithead(&dctx->records); + (void) mtx_init(&dctx->mutex, mtx_plain); + (void) cnd_init(&dctx->cond); + dctx->thread = u_thread_create(dd_thread_main, dctx); + if (!dctx->thread) { + mtx_destroy(&dctx->mutex); + goto fail; + } + + return &dctx->base; + +fail: + FREE(dctx); + pipe->destroy(pipe); + return NULL; +} diff --git a/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/src/gallium/auxiliary/driver_ddebug/dd_draw.c new file mode 100644 index 00000000000..c404ea0607f --- /dev/null +++ b/src/gallium/auxiliary/driver_ddebug/dd_draw.c @@ -0,0 +1,1645 @@ +/************************************************************************** + * + * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2008 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "dd_pipe.h" + +#include "util/u_dump.h" +#include "util/u_format.h" +#include "util/u_framebuffer.h" +#include "util/u_helpers.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" +#include "util/os_time.h" +#include + + +static void +dd_write_header(FILE *f, struct pipe_screen *screen, unsigned apitrace_call_number) +{ + char cmd_line[4096]; + if (os_get_command_line(cmd_line, sizeof(cmd_line))) + fprintf(f, "Command: %s\n", cmd_line); + fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen)); + fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen)); + fprintf(f, "Device name: %s\n\n", screen->get_name(screen)); + + if (apitrace_call_number) + fprintf(f, "Last apitrace call: %u\n\n", apitrace_call_number); +} + +FILE * +dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number) +{ + struct pipe_screen *screen = dscreen->screen; + + FILE *f = dd_get_debug_file(dscreen->verbose); + if (!f) + return NULL; + + dd_write_header(f, screen, apitrace_call_number); + return f; +} + +static void +dd_dump_dmesg(FILE *f) +{ + char line[2000]; + FILE *p = popen("dmesg | tail -n60", "r"); + + if (!p) + return; + + fprintf(f, "\nLast 60 lines of dmesg:\n\n"); + while (fgets(line, sizeof(line), p)) + fputs(line, f); + + pclose(p); +} + +static unsigned +dd_num_active_viewports(struct dd_draw_state *dstate) +{ + struct tgsi_shader_info info; + const struct tgsi_token *tokens; + + if (dstate->shaders[PIPE_SHADER_GEOMETRY]) + tokens = dstate->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens; + else if (dstate->shaders[PIPE_SHADER_TESS_EVAL]) + tokens = dstate->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens; + else if (dstate->shaders[PIPE_SHADER_VERTEX]) + tokens = dstate->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens; + else + return 1; + + if (tokens) { + tgsi_scan_shader(tokens, &info); + if (info.writes_viewport_index) + return PIPE_MAX_VIEWPORTS; + } + + return 1; +} + +#define COLOR_RESET "\033[0m" +#define COLOR_SHADER "\033[1;32m" +#define COLOR_STATE "\033[1;33m" + +#define DUMP(name, var) do { \ + fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \ + util_dump_##name(f, var); \ + fprintf(f, "\n"); \ +} while(0) + +#define DUMP_I(name, var, i) do { \ + fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \ + util_dump_##name(f, var); \ + fprintf(f, "\n"); \ +} while(0) + +#define DUMP_M(name, var, member) do { \ + fprintf(f, " " #member ": "); \ + util_dump_##name(f, (var)->member); \ + fprintf(f, "\n"); \ +} while(0) + +#define DUMP_M_ADDR(name, var, member) do { \ + fprintf(f, " " #member ": "); \ + util_dump_##name(f, &(var)->member); \ + fprintf(f, "\n"); \ +} while(0) + +#define PRINT_NAMED(type, name, value) \ +do { \ + fprintf(f, COLOR_STATE "%s" COLOR_RESET " = ", name); \ + util_dump_##type(f, value); \ + fprintf(f, "\n"); \ +} while (0) + +static void +util_dump_uint(FILE *f, unsigned i) +{ + fprintf(f, "%u", i); +} + +static void +util_dump_int(FILE *f, int i) +{ + fprintf(f, "%d", i); +} + +static void +util_dump_hex(FILE *f, unsigned i) +{ + fprintf(f, "0x%x", i); +} + +static void +util_dump_double(FILE *f, double d) +{ + fprintf(f, "%f", d); +} + +static void +util_dump_format(FILE *f, enum pipe_format format) +{ + fprintf(f, "%s", util_format_name(format)); +} + +static void +util_dump_color_union(FILE *f, const union pipe_color_union *color) +{ + fprintf(f, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}", + color->f[0], color->f[1], color->f[2], color->f[3], + color->ui[0], color->ui[1], color->ui[2], color->ui[3]); +} + +static void +dd_dump_render_condition(struct dd_draw_state *dstate, FILE *f) +{ + if (dstate->render_cond.query) { + fprintf(f, "render condition:\n"); + DUMP_M(query_type, &dstate->render_cond, query->type); + DUMP_M(uint, &dstate->render_cond, condition); + DUMP_M(uint, &dstate->render_cond, mode); + fprintf(f, "\n"); + } +} + +static void +dd_dump_shader(struct dd_draw_state *dstate, enum pipe_shader_type sh, FILE *f) +{ + int i; + const char *shader_str[PIPE_SHADER_TYPES]; + + shader_str[PIPE_SHADER_VERTEX] = "VERTEX"; + shader_str[PIPE_SHADER_TESS_CTRL] = "TESS_CTRL"; + shader_str[PIPE_SHADER_TESS_EVAL] = "TESS_EVAL"; + shader_str[PIPE_SHADER_GEOMETRY] = "GEOMETRY"; + shader_str[PIPE_SHADER_FRAGMENT] = "FRAGMENT"; + shader_str[PIPE_SHADER_COMPUTE] = "COMPUTE"; + + if (sh == PIPE_SHADER_TESS_CTRL && + !dstate->shaders[PIPE_SHADER_TESS_CTRL] && + dstate->shaders[PIPE_SHADER_TESS_EVAL]) + fprintf(f, "tess_state: {default_outer_level = {%f, %f, %f, %f}, " + "default_inner_level = {%f, %f}}\n", + dstate->tess_default_levels[0], + dstate->tess_default_levels[1], + dstate->tess_default_levels[2], + dstate->tess_default_levels[3], + dstate->tess_default_levels[4], + dstate->tess_default_levels[5]); + + if (sh == PIPE_SHADER_FRAGMENT) + if (dstate->rs) { + unsigned num_viewports = dd_num_active_viewports(dstate); + + if (dstate->rs->state.rs.clip_plane_enable) + DUMP(clip_state, &dstate->clip_state); + + for (i = 0; i < num_viewports; i++) + DUMP_I(viewport_state, &dstate->viewports[i], i); + + if (dstate->rs->state.rs.scissor) + for (i = 0; i < num_viewports; i++) + DUMP_I(scissor_state, &dstate->scissors[i], i); + + DUMP(rasterizer_state, &dstate->rs->state.rs); + + if (dstate->rs->state.rs.poly_stipple_enable) + DUMP(poly_stipple, &dstate->polygon_stipple); + fprintf(f, "\n"); + } + + if (!dstate->shaders[sh]) + return; + + fprintf(f, COLOR_SHADER "begin shader: %s" COLOR_RESET "\n", shader_str[sh]); + DUMP(shader_state, &dstate->shaders[sh]->state.shader); + + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) + if (dstate->constant_buffers[sh][i].buffer || + dstate->constant_buffers[sh][i].user_buffer) { + DUMP_I(constant_buffer, &dstate->constant_buffers[sh][i], i); + if (dstate->constant_buffers[sh][i].buffer) + DUMP_M(resource, &dstate->constant_buffers[sh][i], buffer); + } + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + if (dstate->sampler_states[sh][i]) + DUMP_I(sampler_state, &dstate->sampler_states[sh][i]->state.sampler, i); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + if (dstate->sampler_views[sh][i]) { + DUMP_I(sampler_view, dstate->sampler_views[sh][i], i); + DUMP_M(resource, dstate->sampler_views[sh][i], texture); + } + + for (i = 0; i < PIPE_MAX_SHADER_IMAGES; i++) + if (dstate->shader_images[sh][i].resource) { + DUMP_I(image_view, &dstate->shader_images[sh][i], i); + if (dstate->shader_images[sh][i].resource) + DUMP_M(resource, &dstate->shader_images[sh][i], resource); + } + + for (i = 0; i < PIPE_MAX_SHADER_BUFFERS; i++) + if (dstate->shader_buffers[sh][i].buffer) { + DUMP_I(shader_buffer, &dstate->shader_buffers[sh][i], i); + if (dstate->shader_buffers[sh][i].buffer) + DUMP_M(resource, &dstate->shader_buffers[sh][i], buffer); + } + + fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]); +} + +static void +dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f) +{ + int sh, i; + + DUMP(draw_info, info); + if (info->count_from_stream_output) + DUMP_M(stream_output_target, info, + count_from_stream_output); + if (info->indirect) { + DUMP_M(resource, info, indirect->buffer); + if (info->indirect->indirect_draw_count) + DUMP_M(resource, info, indirect->indirect_draw_count); + } + + fprintf(f, "\n"); + + /* TODO: dump active queries */ + + dd_dump_render_condition(dstate, f); + + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) + if (dstate->vertex_buffers[i].buffer.resource) { + DUMP_I(vertex_buffer, &dstate->vertex_buffers[i], i); + if (!dstate->vertex_buffers[i].is_user_buffer) + DUMP_M(resource, &dstate->vertex_buffers[i], buffer.resource); + } + + if (dstate->velems) { + PRINT_NAMED(uint, "num vertex elements", + dstate->velems->state.velems.count); + for (i = 0; i < dstate->velems->state.velems.count; i++) { + fprintf(f, " "); + DUMP_I(vertex_element, &dstate->velems->state.velems.velems[i], i); + } + } + + PRINT_NAMED(uint, "num stream output targets", dstate->num_so_targets); + for (i = 0; i < dstate->num_so_targets; i++) + if (dstate->so_targets[i]) { + DUMP_I(stream_output_target, dstate->so_targets[i], i); + DUMP_M(resource, dstate->so_targets[i], buffer); + fprintf(f, " offset = %i\n", dstate->so_offsets[i]); + } + + fprintf(f, "\n"); + for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { + if (sh == PIPE_SHADER_COMPUTE) + continue; + + dd_dump_shader(dstate, sh, f); + } + + if (dstate->dsa) + DUMP(depth_stencil_alpha_state, &dstate->dsa->state.dsa); + DUMP(stencil_ref, &dstate->stencil_ref); + + if (dstate->blend) + DUMP(blend_state, &dstate->blend->state.blend); + DUMP(blend_color, &dstate->blend_color); + + PRINT_NAMED(uint, "min_samples", dstate->min_samples); + PRINT_NAMED(hex, "sample_mask", dstate->sample_mask); + fprintf(f, "\n"); + + DUMP(framebuffer_state, &dstate->framebuffer_state); + for (i = 0; i < dstate->framebuffer_state.nr_cbufs; i++) + if (dstate->framebuffer_state.cbufs[i]) { + fprintf(f, " " COLOR_STATE "cbufs[%i]:" COLOR_RESET "\n ", i); + DUMP(surface, dstate->framebuffer_state.cbufs[i]); + fprintf(f, " "); + DUMP(resource, dstate->framebuffer_state.cbufs[i]->texture); + } + if (dstate->framebuffer_state.zsbuf) { + fprintf(f, " " COLOR_STATE "zsbuf:" COLOR_RESET "\n "); + DUMP(surface, dstate->framebuffer_state.zsbuf); + fprintf(f, " "); + DUMP(resource, dstate->framebuffer_state.zsbuf->texture); + } + fprintf(f, "\n"); +} + +static void +dd_dump_launch_grid(struct dd_draw_state *dstate, struct pipe_grid_info *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP(grid_info, info); + fprintf(f, "\n"); + + dd_dump_shader(dstate, PIPE_SHADER_COMPUTE, f); + fprintf(f, "\n"); +} + +static void +dd_dump_resource_copy_region(struct dd_draw_state *dstate, + struct call_resource_copy_region *info, + FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M(resource, info, dst); + DUMP_M(uint, info, dst_level); + DUMP_M(uint, info, dstx); + DUMP_M(uint, info, dsty); + DUMP_M(uint, info, dstz); + DUMP_M(resource, info, src); + DUMP_M(uint, info, src_level); + DUMP_M_ADDR(box, info, src_box); +} + +static void +dd_dump_blit(struct dd_draw_state *dstate, struct pipe_blit_info *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M(resource, info, dst.resource); + DUMP_M(uint, info, dst.level); + DUMP_M_ADDR(box, info, dst.box); + DUMP_M(format, info, dst.format); + + DUMP_M(resource, info, src.resource); + DUMP_M(uint, info, src.level); + DUMP_M_ADDR(box, info, src.box); + DUMP_M(format, info, src.format); + + DUMP_M(hex, info, mask); + DUMP_M(uint, info, filter); + DUMP_M(uint, info, scissor_enable); + DUMP_M_ADDR(scissor_state, info, scissor); + DUMP_M(uint, info, render_condition_enable); + + if (info->render_condition_enable) + dd_dump_render_condition(dstate, f); +} + +static void +dd_dump_generate_mipmap(struct dd_draw_state *dstate, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + /* TODO */ +} + +static void +dd_dump_get_query_result_resource(struct call_get_query_result_resource *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__ + 8); + DUMP_M(query_type, info, query_type); + DUMP_M(uint, info, wait); + DUMP_M(query_value_type, info, result_type); + DUMP_M(int, info, index); + DUMP_M(resource, info, resource); + DUMP_M(uint, info, offset); +} + +static void +dd_dump_flush_resource(struct dd_draw_state *dstate, struct pipe_resource *res, + FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP(resource, res); +} + +static void +dd_dump_clear(struct dd_draw_state *dstate, struct call_clear *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M(uint, info, buffers); + DUMP_M_ADDR(color_union, info, color); + DUMP_M(double, info, depth); + DUMP_M(hex, info, stencil); +} + +static void +dd_dump_clear_buffer(struct dd_draw_state *dstate, struct call_clear_buffer *info, + FILE *f) +{ + int i; + const char *value = (const char*)info->clear_value; + + fprintf(f, "%s:\n", __func__+8); + DUMP_M(resource, info, res); + DUMP_M(uint, info, offset); + DUMP_M(uint, info, size); + DUMP_M(uint, info, clear_value_size); + + fprintf(f, " clear_value:"); + for (i = 0; i < info->clear_value_size; i++) + fprintf(f, " %02x", value[i]); + fprintf(f, "\n"); +} + +static void +dd_dump_transfer_map(struct call_transfer_map *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M_ADDR(transfer, info, transfer); + DUMP_M(ptr, info, transfer_ptr); + DUMP_M(ptr, info, ptr); +} + +static void +dd_dump_transfer_flush_region(struct call_transfer_flush_region *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M_ADDR(transfer, info, transfer); + DUMP_M(ptr, info, transfer_ptr); + DUMP_M_ADDR(box, info, box); +} + +static void +dd_dump_transfer_unmap(struct call_transfer_unmap *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M_ADDR(transfer, info, transfer); + DUMP_M(ptr, info, transfer_ptr); +} + +static void +dd_dump_buffer_subdata(struct call_buffer_subdata *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M(resource, info, resource); + DUMP_M(transfer_usage, info, usage); + DUMP_M(uint, info, offset); + DUMP_M(uint, info, size); + DUMP_M(ptr, info, data); +} + +static void +dd_dump_texture_subdata(struct call_texture_subdata *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M(resource, info, resource); + DUMP_M(uint, info, level); + DUMP_M(transfer_usage, info, usage); + DUMP_M_ADDR(box, info, box); + DUMP_M(ptr, info, data); + DUMP_M(uint, info, stride); + DUMP_M(uint, info, layer_stride); +} + +static void +dd_dump_clear_texture(struct dd_draw_state *dstate, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + /* TODO */ +} + +static void +dd_dump_clear_render_target(struct dd_draw_state *dstate, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + /* TODO */ +} + +static void +dd_dump_clear_depth_stencil(struct dd_draw_state *dstate, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + /* TODO */ +} + +static void +dd_dump_driver_state(struct dd_context *dctx, FILE *f, unsigned flags) +{ + if (dctx->pipe->dump_debug_state) { + fprintf(f,"\n\n**************************************************" + "***************************\n"); + fprintf(f, "Driver-specific state:\n\n"); + dctx->pipe->dump_debug_state(dctx->pipe, f, flags); + } +} + +static void +dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call) +{ + switch (call->type) { + case CALL_DRAW_VBO: + dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f); + break; + case CALL_LAUNCH_GRID: + dd_dump_launch_grid(state, &call->info.launch_grid, f); + break; + case CALL_RESOURCE_COPY_REGION: + dd_dump_resource_copy_region(state, + &call->info.resource_copy_region, f); + break; + case CALL_BLIT: + dd_dump_blit(state, &call->info.blit, f); + break; + case CALL_FLUSH_RESOURCE: + dd_dump_flush_resource(state, call->info.flush_resource, f); + break; + case CALL_CLEAR: + dd_dump_clear(state, &call->info.clear, f); + break; + case CALL_CLEAR_BUFFER: + dd_dump_clear_buffer(state, &call->info.clear_buffer, f); + break; + case CALL_CLEAR_TEXTURE: + dd_dump_clear_texture(state, f); + break; + case CALL_CLEAR_RENDER_TARGET: + dd_dump_clear_render_target(state, f); + break; + case CALL_CLEAR_DEPTH_STENCIL: + dd_dump_clear_depth_stencil(state, f); + break; + case CALL_GENERATE_MIPMAP: + dd_dump_generate_mipmap(state, f); + break; + case CALL_GET_QUERY_RESULT_RESOURCE: + dd_dump_get_query_result_resource(&call->info.get_query_result_resource, f); + break; + case CALL_TRANSFER_MAP: + dd_dump_transfer_map(&call->info.transfer_map, f); + break; + case CALL_TRANSFER_FLUSH_REGION: + dd_dump_transfer_flush_region(&call->info.transfer_flush_region, f); + break; + case CALL_TRANSFER_UNMAP: + dd_dump_transfer_unmap(&call->info.transfer_unmap, f); + break; + case CALL_BUFFER_SUBDATA: + dd_dump_buffer_subdata(&call->info.buffer_subdata, f); + break; + case CALL_TEXTURE_SUBDATA: + dd_dump_texture_subdata(&call->info.texture_subdata, f); + break; + } +} + +static void +dd_kill_process(void) +{ + sync(); + fprintf(stderr, "dd: Aborting the process...\n"); + fflush(stdout); + fflush(stderr); + exit(1); +} + +static void +dd_unreference_copy_of_call(struct dd_call *dst) +{ + switch (dst->type) { + case CALL_DRAW_VBO: + pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL); + pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL); + pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL); + if (dst->info.draw_vbo.draw.index_size && + !dst->info.draw_vbo.draw.has_user_indices) + pipe_resource_reference(&dst->info.draw_vbo.draw.index.resource, NULL); + else + dst->info.draw_vbo.draw.index.user = NULL; + break; + case CALL_LAUNCH_GRID: + pipe_resource_reference(&dst->info.launch_grid.indirect, NULL); + break; + case CALL_RESOURCE_COPY_REGION: + pipe_resource_reference(&dst->info.resource_copy_region.dst, NULL); + pipe_resource_reference(&dst->info.resource_copy_region.src, NULL); + break; + case CALL_BLIT: + pipe_resource_reference(&dst->info.blit.dst.resource, NULL); + pipe_resource_reference(&dst->info.blit.src.resource, NULL); + break; + case CALL_FLUSH_RESOURCE: + pipe_resource_reference(&dst->info.flush_resource, NULL); + break; + case CALL_CLEAR: + break; + case CALL_CLEAR_BUFFER: + pipe_resource_reference(&dst->info.clear_buffer.res, NULL); + break; + case CALL_CLEAR_TEXTURE: + break; + case CALL_CLEAR_RENDER_TARGET: + break; + case CALL_CLEAR_DEPTH_STENCIL: + break; + case CALL_GENERATE_MIPMAP: + pipe_resource_reference(&dst->info.generate_mipmap.res, NULL); + break; + case CALL_GET_QUERY_RESULT_RESOURCE: + pipe_resource_reference(&dst->info.get_query_result_resource.resource, NULL); + break; + case CALL_TRANSFER_MAP: + pipe_resource_reference(&dst->info.transfer_map.transfer.resource, NULL); + break; + case CALL_TRANSFER_FLUSH_REGION: + pipe_resource_reference(&dst->info.transfer_flush_region.transfer.resource, NULL); + break; + case CALL_TRANSFER_UNMAP: + pipe_resource_reference(&dst->info.transfer_unmap.transfer.resource, NULL); + break; + case CALL_BUFFER_SUBDATA: + pipe_resource_reference(&dst->info.buffer_subdata.resource, NULL); + break; + case CALL_TEXTURE_SUBDATA: + pipe_resource_reference(&dst->info.texture_subdata.resource, NULL); + break; + } +} + +static void +dd_init_copy_of_draw_state(struct dd_draw_state_copy *state) +{ + unsigned i,j; + + /* Just clear pointers to gallium objects. Don't clear the whole structure, + * because it would kill performance with its size of 130 KB. + */ + memset(state->base.vertex_buffers, 0, + sizeof(state->base.vertex_buffers)); + memset(state->base.so_targets, 0, + sizeof(state->base.so_targets)); + memset(state->base.constant_buffers, 0, + sizeof(state->base.constant_buffers)); + memset(state->base.sampler_views, 0, + sizeof(state->base.sampler_views)); + memset(state->base.shader_images, 0, + sizeof(state->base.shader_images)); + memset(state->base.shader_buffers, 0, + sizeof(state->base.shader_buffers)); + memset(&state->base.framebuffer_state, 0, + sizeof(state->base.framebuffer_state)); + + memset(state->shaders, 0, sizeof(state->shaders)); + + state->base.render_cond.query = &state->render_cond; + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + state->base.shaders[i] = &state->shaders[i]; + for (j = 0; j < PIPE_MAX_SAMPLERS; j++) + state->base.sampler_states[i][j] = &state->sampler_states[i][j]; + } + + state->base.velems = &state->velems; + state->base.rs = &state->rs; + state->base.dsa = &state->dsa; + state->base.blend = &state->blend; +} + +static void +dd_unreference_copy_of_draw_state(struct dd_draw_state_copy *state) +{ + struct dd_draw_state *dst = &state->base; + unsigned i,j; + + for (i = 0; i < ARRAY_SIZE(dst->vertex_buffers); i++) + pipe_vertex_buffer_unreference(&dst->vertex_buffers[i]); + for (i = 0; i < ARRAY_SIZE(dst->so_targets); i++) + pipe_so_target_reference(&dst->so_targets[i], NULL); + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + if (dst->shaders[i]) + tgsi_free_tokens(dst->shaders[i]->state.shader.tokens); + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) + pipe_resource_reference(&dst->constant_buffers[i][j].buffer, NULL); + for (j = 0; j < PIPE_MAX_SAMPLERS; j++) + pipe_sampler_view_reference(&dst->sampler_views[i][j], NULL); + for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++) + pipe_resource_reference(&dst->shader_images[i][j].resource, NULL); + for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++) + pipe_resource_reference(&dst->shader_buffers[i][j].buffer, NULL); + } + + util_unreference_framebuffer_state(&dst->framebuffer_state); +} + +static void +dd_copy_draw_state(struct dd_draw_state *dst, struct dd_draw_state *src) +{ + unsigned i,j; + + if (src->render_cond.query) { + *dst->render_cond.query = *src->render_cond.query; + dst->render_cond.condition = src->render_cond.condition; + dst->render_cond.mode = src->render_cond.mode; + } else { + dst->render_cond.query = NULL; + } + + for (i = 0; i < ARRAY_SIZE(src->vertex_buffers); i++) { + pipe_vertex_buffer_reference(&dst->vertex_buffers[i], + &src->vertex_buffers[i]); + } + + dst->num_so_targets = src->num_so_targets; + for (i = 0; i < src->num_so_targets; i++) + pipe_so_target_reference(&dst->so_targets[i], src->so_targets[i]); + memcpy(dst->so_offsets, src->so_offsets, sizeof(src->so_offsets)); + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + if (!src->shaders[i]) { + dst->shaders[i] = NULL; + continue; + } + + if (src->shaders[i]) { + dst->shaders[i]->state.shader = src->shaders[i]->state.shader; + if (src->shaders[i]->state.shader.tokens) { + dst->shaders[i]->state.shader.tokens = + tgsi_dup_tokens(src->shaders[i]->state.shader.tokens); + } else { + dst->shaders[i]->state.shader.ir.nir = NULL; + } + } else { + dst->shaders[i] = NULL; + } + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + pipe_resource_reference(&dst->constant_buffers[i][j].buffer, + src->constant_buffers[i][j].buffer); + memcpy(&dst->constant_buffers[i][j], &src->constant_buffers[i][j], + sizeof(src->constant_buffers[i][j])); + } + + for (j = 0; j < PIPE_MAX_SAMPLERS; j++) { + pipe_sampler_view_reference(&dst->sampler_views[i][j], + src->sampler_views[i][j]); + if (src->sampler_states[i][j]) + dst->sampler_states[i][j]->state.sampler = + src->sampler_states[i][j]->state.sampler; + else + dst->sampler_states[i][j] = NULL; + } + + for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++) { + pipe_resource_reference(&dst->shader_images[i][j].resource, + src->shader_images[i][j].resource); + memcpy(&dst->shader_images[i][j], &src->shader_images[i][j], + sizeof(src->shader_images[i][j])); + } + + for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++) { + pipe_resource_reference(&dst->shader_buffers[i][j].buffer, + src->shader_buffers[i][j].buffer); + memcpy(&dst->shader_buffers[i][j], &src->shader_buffers[i][j], + sizeof(src->shader_buffers[i][j])); + } + } + + if (src->velems) + dst->velems->state.velems = src->velems->state.velems; + else + dst->velems = NULL; + + if (src->rs) + dst->rs->state.rs = src->rs->state.rs; + else + dst->rs = NULL; + + if (src->dsa) + dst->dsa->state.dsa = src->dsa->state.dsa; + else + dst->dsa = NULL; + + if (src->blend) + dst->blend->state.blend = src->blend->state.blend; + else + dst->blend = NULL; + + dst->blend_color = src->blend_color; + dst->stencil_ref = src->stencil_ref; + dst->sample_mask = src->sample_mask; + dst->min_samples = src->min_samples; + dst->clip_state = src->clip_state; + util_copy_framebuffer_state(&dst->framebuffer_state, &src->framebuffer_state); + memcpy(dst->scissors, src->scissors, sizeof(src->scissors)); + memcpy(dst->viewports, src->viewports, sizeof(src->viewports)); + memcpy(dst->tess_default_levels, src->tess_default_levels, + sizeof(src->tess_default_levels)); + dst->apitrace_call_number = src->apitrace_call_number; +} + +static void +dd_free_record(struct pipe_screen *screen, struct dd_draw_record *record) +{ + u_log_page_destroy(record->log_page); + dd_unreference_copy_of_call(&record->call); + dd_unreference_copy_of_draw_state(&record->draw_state); + screen->fence_reference(screen, &record->prev_bottom_of_pipe, NULL); + screen->fence_reference(screen, &record->top_of_pipe, NULL); + screen->fence_reference(screen, &record->bottom_of_pipe, NULL); + util_queue_fence_destroy(&record->driver_finished); + FREE(record); +} + +static void +dd_write_record(FILE *f, struct dd_draw_record *record) +{ + PRINT_NAMED(ptr, "pipe", record->dctx->pipe); + PRINT_NAMED(ns, "time before (API call)", record->time_before); + PRINT_NAMED(ns, "time after (driver done)", record->time_after); + fprintf(f, "\n"); + + dd_dump_call(f, &record->draw_state.base, &record->call); + + if (record->log_page) { + fprintf(f,"\n\n**************************************************" + "***************************\n"); + fprintf(f, "Context Log:\n\n"); + u_log_page_print(record->log_page, f); + } +} + +static void +dd_maybe_dump_record(struct dd_screen *dscreen, struct dd_draw_record *record) +{ + if (dscreen->dump_mode == DD_DUMP_ONLY_HANGS || + (dscreen->dump_mode == DD_DUMP_APITRACE_CALL && + dscreen->apitrace_dump_call != record->draw_state.base.apitrace_call_number)) + return; + + char name[512]; + dd_get_debug_filename_and_mkdir(name, sizeof(name), dscreen->verbose); + FILE *f = fopen(name, "w"); + if (!f) { + fprintf(stderr, "dd: failed to open %s\n", name); + return; + } + + dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number); + dd_write_record(f, record); + + fclose(f); +} + +static const char * +dd_fence_state(struct pipe_screen *screen, struct pipe_fence_handle *fence, + bool *not_reached) +{ + if (!fence) + return "---"; + + bool ok = screen->fence_finish(screen, NULL, fence, 0); + + if (not_reached && !ok) + *not_reached = true; + + return ok ? "YES" : "NO "; +} + +static void +dd_report_hang(struct dd_context *dctx) +{ + struct dd_screen *dscreen = dd_screen(dctx->base.screen); + struct pipe_screen *screen = dscreen->screen; + bool encountered_hang = false; + bool stop_output = false; + unsigned num_later = 0; + + fprintf(stderr, "GPU hang detected, collecting information...\n\n"); + + fprintf(stderr, "Draw # driver prev BOP TOP BOP dump file\n" + "-------------------------------------------------------------\n"); + + list_for_each_entry(struct dd_draw_record, record, &dctx->records, list) { + if (!encountered_hang && + screen->fence_finish(screen, NULL, record->bottom_of_pipe, 0)) { + dd_maybe_dump_record(dscreen, record); + continue; + } + + if (stop_output) { + dd_maybe_dump_record(dscreen, record); + num_later++; + continue; + } + + bool driver = util_queue_fence_is_signalled(&record->driver_finished); + bool top_not_reached = false; + const char *prev_bop = dd_fence_state(screen, record->prev_bottom_of_pipe, NULL); + const char *top = dd_fence_state(screen, record->top_of_pipe, &top_not_reached); + const char *bop = dd_fence_state(screen, record->bottom_of_pipe, NULL); + + fprintf(stderr, "%-9u %s %s %s %s ", + record->draw_call, driver ? "YES" : "NO ", prev_bop, top, bop); + + char name[512]; + dd_get_debug_filename_and_mkdir(name, sizeof(name), false); + + FILE *f = fopen(name, "w"); + if (!f) { + fprintf(stderr, "fopen failed\n"); + } else { + fprintf(stderr, "%s\n", name); + + dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number); + dd_write_record(f, record); + + if (!encountered_hang) { + dd_dump_driver_state(dctx, f, PIPE_DUMP_DEVICE_STATUS_REGISTERS); + dd_dump_dmesg(f); + } + + fclose(f); + } + + if (top_not_reached) + stop_output = true; + encountered_hang = true; + } + + if (num_later || dctx->record_pending) { + fprintf(stderr, "... and %u%s additional draws.\n", num_later, + dctx->record_pending ? "+1 (pending)" : ""); + } + + fprintf(stderr, "\nDone.\n"); + dd_kill_process(); +} + +int +dd_thread_main(void *input) +{ + struct dd_context *dctx = (struct dd_context *)input; + struct dd_screen *dscreen = dd_screen(dctx->base.screen); + struct pipe_screen *screen = dscreen->screen; + + mtx_lock(&dctx->mutex); + + for (;;) { + struct list_head records; + struct pipe_fence_handle *fence; + struct pipe_fence_handle *fence2 = NULL; + + list_replace(&dctx->records, &records); + list_inithead(&dctx->records); + dctx->num_records = 0; + + if (dctx->api_stalled) + cnd_signal(&dctx->cond); + + if (!list_empty(&records)) { + /* Wait for the youngest draw. This means hangs can take a bit longer + * to detect, but it's more efficient this way. */ + struct dd_draw_record *youngest = + LIST_ENTRY(struct dd_draw_record, records.prev, list); + fence = youngest->bottom_of_pipe; + } else if (dctx->record_pending) { + /* Wait for pending fences, in case the driver ends up hanging internally. */ + fence = dctx->record_pending->prev_bottom_of_pipe; + fence2 = dctx->record_pending->top_of_pipe; + } else if (dctx->kill_thread) { + break; + } else { + cnd_wait(&dctx->cond, &dctx->mutex); + continue; + } + mtx_unlock(&dctx->mutex); + + /* Fences can be NULL legitimately when timeout detection is disabled. */ + if ((fence && + !screen->fence_finish(screen, NULL, fence, + (uint64_t)dscreen->timeout_ms * 1000*1000)) || + (fence2 && + !screen->fence_finish(screen, NULL, fence2, + (uint64_t)dscreen->timeout_ms * 1000*1000))) { + mtx_lock(&dctx->mutex); + list_splice(&records, &dctx->records); + dd_report_hang(dctx); + /* we won't actually get here */ + mtx_unlock(&dctx->mutex); + } + + list_for_each_entry_safe(struct dd_draw_record, record, &records, list) { + dd_maybe_dump_record(dscreen, record); + list_del(&record->list); + dd_free_record(screen, record); + } + + mtx_lock(&dctx->mutex); + } + mtx_unlock(&dctx->mutex); + return 0; +} + +static struct dd_draw_record * +dd_create_record(struct dd_context *dctx) +{ + struct dd_draw_record *record; + + record = MALLOC_STRUCT(dd_draw_record); + if (!record) + return NULL; + + record->dctx = dctx; + record->draw_call = dctx->num_draw_calls; + + record->prev_bottom_of_pipe = NULL; + record->top_of_pipe = NULL; + record->bottom_of_pipe = NULL; + record->log_page = NULL; + util_queue_fence_init(&record->driver_finished); + + dd_init_copy_of_draw_state(&record->draw_state); + dd_copy_draw_state(&record->draw_state.base, &dctx->draw_state); + + return record; +} + +static void +dd_context_flush(struct pipe_context *_pipe, + struct pipe_fence_handle **fence, unsigned flags) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + pipe->flush(pipe, fence, flags); +} + +static void +dd_before_draw(struct dd_context *dctx, struct dd_draw_record *record) +{ + struct dd_screen *dscreen = dd_screen(dctx->base.screen); + struct pipe_context *pipe = dctx->pipe; + struct pipe_screen *screen = dscreen->screen; + + record->time_before = os_time_get_nano(); + + if (dscreen->timeout_ms > 0) { + if (dscreen->flush_always && dctx->num_draw_calls >= dscreen->skip_count) { + pipe->flush(pipe, &record->prev_bottom_of_pipe, 0); + screen->fence_reference(screen, &record->top_of_pipe, record->prev_bottom_of_pipe); + } else { + pipe->flush(pipe, &record->prev_bottom_of_pipe, + PIPE_FLUSH_DEFERRED | PIPE_FLUSH_BOTTOM_OF_PIPE); + pipe->flush(pipe, &record->top_of_pipe, + PIPE_FLUSH_DEFERRED | PIPE_FLUSH_TOP_OF_PIPE); + } + + mtx_lock(&dctx->mutex); + dctx->record_pending = record; + if (list_empty(&dctx->records)) + cnd_signal(&dctx->cond); + mtx_unlock(&dctx->mutex); + } +} + +static void +dd_after_draw_async(void *data) +{ + struct dd_draw_record *record = (struct dd_draw_record *)data; + struct dd_context *dctx = record->dctx; + struct dd_screen *dscreen = dd_screen(dctx->base.screen); + + record->log_page = u_log_new_page(&dctx->log); + record->time_after = os_time_get_nano(); + + if (!util_queue_fence_is_signalled(&record->driver_finished)) + util_queue_fence_signal(&record->driver_finished); + + if (dscreen->dump_mode == DD_DUMP_APITRACE_CALL && + dscreen->apitrace_dump_call > dctx->draw_state.apitrace_call_number) { + dd_thread_join(dctx); + /* No need to continue. */ + exit(0); + } +} + +static void +dd_after_draw(struct dd_context *dctx, struct dd_draw_record *record) +{ + struct dd_screen *dscreen = dd_screen(dctx->base.screen); + struct pipe_context *pipe = dctx->pipe; + + if (dscreen->timeout_ms > 0) { + unsigned flush_flags; + if (dscreen->flush_always && dctx->num_draw_calls >= dscreen->skip_count) + flush_flags = 0; + else + flush_flags = PIPE_FLUSH_DEFERRED | PIPE_FLUSH_BOTTOM_OF_PIPE; + pipe->flush(pipe, &record->bottom_of_pipe, flush_flags); + + assert(record == dctx->record_pending); + } + + if (pipe->callback) { + util_queue_fence_reset(&record->driver_finished); + pipe->callback(pipe, dd_after_draw_async, record, true); + } else { + dd_after_draw_async(record); + } + + mtx_lock(&dctx->mutex); + if (unlikely(dctx->num_records > 10000)) { + dctx->api_stalled = true; + /* Since this is only a heuristic to prevent the API thread from getting + * too far ahead, we don't need a loop here. */ + cnd_wait(&dctx->cond, &dctx->mutex); + dctx->api_stalled = false; + } + + if (list_empty(&dctx->records)) + cnd_signal(&dctx->cond); + + list_addtail(&record->list, &dctx->records); + dctx->record_pending = NULL; + dctx->num_records++; + mtx_unlock(&dctx->mutex); + + ++dctx->num_draw_calls; + if (dscreen->skip_count && dctx->num_draw_calls % 10000 == 0) + fprintf(stderr, "Gallium debugger reached %u draw calls.\n", + dctx->num_draw_calls); +} + +static void +dd_context_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_DRAW_VBO; + record->call.info.draw_vbo.draw = *info; + record->call.info.draw_vbo.draw.count_from_stream_output = NULL; + pipe_so_target_reference(&record->call.info.draw_vbo.draw.count_from_stream_output, + info->count_from_stream_output); + if (info->index_size && !info->has_user_indices) { + record->call.info.draw_vbo.draw.index.resource = NULL; + pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource, + info->index.resource); + } + + if (info->indirect) { + record->call.info.draw_vbo.indirect = *info->indirect; + record->call.info.draw_vbo.draw.indirect = &record->call.info.draw_vbo.indirect; + + record->call.info.draw_vbo.indirect.buffer = NULL; + pipe_resource_reference(&record->call.info.draw_vbo.indirect.buffer, + info->indirect->buffer); + record->call.info.draw_vbo.indirect.indirect_draw_count = NULL; + pipe_resource_reference(&record->call.info.draw_vbo.indirect.indirect_draw_count, + info->indirect->indirect_draw_count); + } else { + memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*info->indirect)); + } + + dd_before_draw(dctx, record); + pipe->draw_vbo(pipe, info); + dd_after_draw(dctx, record); +} + +static void +dd_context_launch_grid(struct pipe_context *_pipe, + const struct pipe_grid_info *info) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_LAUNCH_GRID; + record->call.info.launch_grid = *info; + record->call.info.launch_grid.indirect = NULL; + pipe_resource_reference(&record->call.info.launch_grid.indirect, info->indirect); + + dd_before_draw(dctx, record); + pipe->launch_grid(pipe, info); + dd_after_draw(dctx, record); +} + +static void +dd_context_resource_copy_region(struct pipe_context *_pipe, + struct pipe_resource *dst, unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_RESOURCE_COPY_REGION; + record->call.info.resource_copy_region.dst = NULL; + pipe_resource_reference(&record->call.info.resource_copy_region.dst, dst); + record->call.info.resource_copy_region.dst_level = dst_level; + record->call.info.resource_copy_region.dstx = dstx; + record->call.info.resource_copy_region.dsty = dsty; + record->call.info.resource_copy_region.dstz = dstz; + record->call.info.resource_copy_region.src = NULL; + pipe_resource_reference(&record->call.info.resource_copy_region.src, src); + record->call.info.resource_copy_region.src_level = src_level; + record->call.info.resource_copy_region.src_box = *src_box; + + dd_before_draw(dctx, record); + pipe->resource_copy_region(pipe, + dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); + dd_after_draw(dctx, record); +} + +static void +dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_BLIT; + record->call.info.blit = *info; + record->call.info.blit.dst.resource = NULL; + pipe_resource_reference(&record->call.info.blit.dst.resource, info->dst.resource); + record->call.info.blit.src.resource = NULL; + pipe_resource_reference(&record->call.info.blit.src.resource, info->src.resource); + + dd_before_draw(dctx, record); + pipe->blit(pipe, info); + dd_after_draw(dctx, record); +} + +static boolean +dd_context_generate_mipmap(struct pipe_context *_pipe, + struct pipe_resource *res, + enum pipe_format format, + unsigned base_level, + unsigned last_level, + unsigned first_layer, + unsigned last_layer) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + boolean result; + + record->call.type = CALL_GENERATE_MIPMAP; + record->call.info.generate_mipmap.res = NULL; + pipe_resource_reference(&record->call.info.generate_mipmap.res, res); + record->call.info.generate_mipmap.format = format; + record->call.info.generate_mipmap.base_level = base_level; + record->call.info.generate_mipmap.last_level = last_level; + record->call.info.generate_mipmap.first_layer = first_layer; + record->call.info.generate_mipmap.last_layer = last_layer; + + dd_before_draw(dctx, record); + result = pipe->generate_mipmap(pipe, res, format, base_level, last_level, + first_layer, last_layer); + dd_after_draw(dctx, record); + return result; +} + +static void +dd_context_get_query_result_resource(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + enum pipe_query_value_type result_type, + int index, + struct pipe_resource *resource, + unsigned offset) +{ + struct dd_context *dctx = dd_context(_pipe); + struct dd_query *dquery = dd_query(query); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_GET_QUERY_RESULT_RESOURCE; + record->call.info.get_query_result_resource.query = query; + record->call.info.get_query_result_resource.wait = wait; + record->call.info.get_query_result_resource.result_type = result_type; + record->call.info.get_query_result_resource.index = index; + record->call.info.get_query_result_resource.resource = NULL; + pipe_resource_reference(&record->call.info.get_query_result_resource.resource, + resource); + record->call.info.get_query_result_resource.offset = offset; + + /* The query may be deleted by the time we need to print it. */ + record->call.info.get_query_result_resource.query_type = dquery->type; + + dd_before_draw(dctx, record); + pipe->get_query_result_resource(pipe, dquery->query, wait, + result_type, index, resource, offset); + dd_after_draw(dctx, record); +} + +static void +dd_context_flush_resource(struct pipe_context *_pipe, + struct pipe_resource *resource) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_FLUSH_RESOURCE; + record->call.info.flush_resource = NULL; + pipe_resource_reference(&record->call.info.flush_resource, resource); + + dd_before_draw(dctx, record); + pipe->flush_resource(pipe, resource); + dd_after_draw(dctx, record); +} + +static void +dd_context_clear(struct pipe_context *_pipe, unsigned buffers, + const union pipe_color_union *color, double depth, + unsigned stencil) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_CLEAR; + record->call.info.clear.buffers = buffers; + record->call.info.clear.color = *color; + record->call.info.clear.depth = depth; + record->call.info.clear.stencil = stencil; + + dd_before_draw(dctx, record); + pipe->clear(pipe, buffers, color, depth, stencil); + dd_after_draw(dctx, record); +} + +static void +dd_context_clear_render_target(struct pipe_context *_pipe, + struct pipe_surface *dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_CLEAR_RENDER_TARGET; + + dd_before_draw(dctx, record); + pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height, + render_condition_enabled); + dd_after_draw(dctx, record); +} + +static void +dd_context_clear_depth_stencil(struct pipe_context *_pipe, + struct pipe_surface *dst, unsigned clear_flags, + double depth, unsigned stencil, unsigned dstx, + unsigned dsty, unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_CLEAR_DEPTH_STENCIL; + + dd_before_draw(dctx, record); + pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil, + dstx, dsty, width, height, + render_condition_enabled); + dd_after_draw(dctx, record); +} + +static void +dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res, + unsigned offset, unsigned size, + const void *clear_value, int clear_value_size) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_CLEAR_BUFFER; + record->call.info.clear_buffer.res = NULL; + pipe_resource_reference(&record->call.info.clear_buffer.res, res); + record->call.info.clear_buffer.offset = offset; + record->call.info.clear_buffer.size = size; + record->call.info.clear_buffer.clear_value = clear_value; + record->call.info.clear_buffer.clear_value_size = clear_value_size; + + dd_before_draw(dctx, record); + pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size); + dd_after_draw(dctx, record); +} + +static void +dd_context_clear_texture(struct pipe_context *_pipe, + struct pipe_resource *res, + unsigned level, + const struct pipe_box *box, + const void *data) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_CLEAR_TEXTURE; + + dd_before_draw(dctx, record); + pipe->clear_texture(pipe, res, level, box, data); + dd_after_draw(dctx, record); +} + +/******************************************************************** + * transfer + */ + +static void * +dd_context_transfer_map(struct pipe_context *_pipe, + struct pipe_resource *resource, unsigned level, + unsigned usage, const struct pipe_box *box, + struct pipe_transfer **transfer) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = + dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; + + if (record) { + record->call.type = CALL_TRANSFER_MAP; + + dd_before_draw(dctx, record); + } + void *ptr = pipe->transfer_map(pipe, resource, level, usage, box, transfer); + if (record) { + record->call.info.transfer_map.transfer_ptr = *transfer; + record->call.info.transfer_map.ptr = ptr; + if (*transfer) { + record->call.info.transfer_map.transfer = **transfer; + record->call.info.transfer_map.transfer.resource = NULL; + pipe_resource_reference(&record->call.info.transfer_map.transfer.resource, + (*transfer)->resource); + } else { + memset(&record->call.info.transfer_map.transfer, 0, sizeof(struct pipe_transfer)); + } + + dd_after_draw(dctx, record); + } + return ptr; +} + +static void +dd_context_transfer_flush_region(struct pipe_context *_pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = + dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; + + if (record) { + record->call.type = CALL_TRANSFER_FLUSH_REGION; + record->call.info.transfer_flush_region.transfer_ptr = transfer; + record->call.info.transfer_flush_region.box = *box; + record->call.info.transfer_flush_region.transfer = *transfer; + record->call.info.transfer_flush_region.transfer.resource = NULL; + pipe_resource_reference( + &record->call.info.transfer_flush_region.transfer.resource, + transfer->resource); + + dd_before_draw(dctx, record); + } + pipe->transfer_flush_region(pipe, transfer, box); + if (record) + dd_after_draw(dctx, record); +} + +static void +dd_context_transfer_unmap(struct pipe_context *_pipe, + struct pipe_transfer *transfer) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = + dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; + + if (record) { + record->call.type = CALL_TRANSFER_UNMAP; + record->call.info.transfer_unmap.transfer_ptr = transfer; + record->call.info.transfer_unmap.transfer = *transfer; + record->call.info.transfer_unmap.transfer.resource = NULL; + pipe_resource_reference( + &record->call.info.transfer_unmap.transfer.resource, + transfer->resource); + + dd_before_draw(dctx, record); + } + pipe->transfer_unmap(pipe, transfer); + if (record) + dd_after_draw(dctx, record); +} + +static void +dd_context_buffer_subdata(struct pipe_context *_pipe, + struct pipe_resource *resource, + unsigned usage, unsigned offset, + unsigned size, const void *data) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = + dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; + + if (record) { + record->call.type = CALL_BUFFER_SUBDATA; + record->call.info.buffer_subdata.resource = NULL; + pipe_resource_reference(&record->call.info.buffer_subdata.resource, resource); + record->call.info.buffer_subdata.usage = usage; + record->call.info.buffer_subdata.offset = offset; + record->call.info.buffer_subdata.size = size; + record->call.info.buffer_subdata.data = data; + + dd_before_draw(dctx, record); + } + pipe->buffer_subdata(pipe, resource, usage, offset, size, data); + if (record) + dd_after_draw(dctx, record); +} + +static void +dd_context_texture_subdata(struct pipe_context *_pipe, + struct pipe_resource *resource, + unsigned level, unsigned usage, + const struct pipe_box *box, + const void *data, unsigned stride, + unsigned layer_stride) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct dd_draw_record *record = + dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; + + if (record) { + record->call.type = CALL_TEXTURE_SUBDATA; + record->call.info.texture_subdata.resource = NULL; + pipe_resource_reference(&record->call.info.texture_subdata.resource, resource); + record->call.info.texture_subdata.level = level; + record->call.info.texture_subdata.usage = usage; + record->call.info.texture_subdata.box = *box; + record->call.info.texture_subdata.data = data; + record->call.info.texture_subdata.stride = stride; + record->call.info.texture_subdata.layer_stride = layer_stride; + + dd_before_draw(dctx, record); + } + pipe->texture_subdata(pipe, resource, level, usage, box, data, + stride, layer_stride); + if (record) + dd_after_draw(dctx, record); +} + +void +dd_init_draw_functions(struct dd_context *dctx) +{ + CTX_INIT(flush); + CTX_INIT(draw_vbo); + CTX_INIT(launch_grid); + CTX_INIT(resource_copy_region); + CTX_INIT(blit); + CTX_INIT(clear); + CTX_INIT(clear_render_target); + CTX_INIT(clear_depth_stencil); + CTX_INIT(clear_buffer); + CTX_INIT(clear_texture); + CTX_INIT(flush_resource); + CTX_INIT(generate_mipmap); + CTX_INIT(get_query_result_resource); + CTX_INIT(transfer_map); + CTX_INIT(transfer_flush_region); + CTX_INIT(transfer_unmap); + CTX_INIT(buffer_subdata); + CTX_INIT(texture_subdata); +} diff --git a/src/gallium/auxiliary/driver_ddebug/dd_pipe.h b/src/gallium/auxiliary/driver_ddebug/dd_pipe.h new file mode 100644 index 00000000000..07c4d55017f --- /dev/null +++ b/src/gallium/auxiliary/driver_ddebug/dd_pipe.h @@ -0,0 +1,371 @@ +/************************************************************************** + * + * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2008 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 DD_H_ +#define DD_H_ + +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_screen.h" +#include "dd_util.h" +#include "os/os_thread.h" +#include "util/list.h" +#include "util/u_log.h" +#include "util/u_queue.h" + +struct dd_context; + +enum dd_dump_mode { + DD_DUMP_ONLY_HANGS, + DD_DUMP_ALL_CALLS, + DD_DUMP_APITRACE_CALL, +}; + +struct dd_screen +{ + struct pipe_screen base; + struct pipe_screen *screen; + unsigned timeout_ms; + enum dd_dump_mode dump_mode; + bool flush_always; + bool transfers; + bool verbose; + unsigned skip_count; + unsigned apitrace_dump_call; +}; + +enum call_type +{ + CALL_DRAW_VBO, + CALL_LAUNCH_GRID, + CALL_RESOURCE_COPY_REGION, + CALL_BLIT, + CALL_FLUSH_RESOURCE, + CALL_CLEAR, + CALL_CLEAR_BUFFER, + CALL_CLEAR_TEXTURE, + CALL_CLEAR_RENDER_TARGET, + CALL_CLEAR_DEPTH_STENCIL, + CALL_GENERATE_MIPMAP, + CALL_GET_QUERY_RESULT_RESOURCE, + CALL_TRANSFER_MAP, + CALL_TRANSFER_FLUSH_REGION, + CALL_TRANSFER_UNMAP, + CALL_BUFFER_SUBDATA, + CALL_TEXTURE_SUBDATA, +}; + +struct call_resource_copy_region +{ + struct pipe_resource *dst; + unsigned dst_level; + unsigned dstx, dsty, dstz; + struct pipe_resource *src; + unsigned src_level; + struct pipe_box src_box; +}; + +struct call_clear +{ + unsigned buffers; + union pipe_color_union color; + double depth; + unsigned stencil; +}; + +struct call_clear_buffer +{ + struct pipe_resource *res; + unsigned offset; + unsigned size; + const void *clear_value; + int clear_value_size; +}; + +struct call_generate_mipmap { + struct pipe_resource *res; + enum pipe_format format; + unsigned base_level; + unsigned last_level; + unsigned first_layer; + unsigned last_layer; +}; + +struct call_draw_info { + struct pipe_draw_info draw; + struct pipe_draw_indirect_info indirect; +}; + +struct call_get_query_result_resource { + struct pipe_query *query; + enum pipe_query_type query_type; + boolean wait; + enum pipe_query_value_type result_type; + int index; + struct pipe_resource *resource; + unsigned offset; +}; + +struct call_transfer_map { + struct pipe_transfer *transfer_ptr; + struct pipe_transfer transfer; + void *ptr; +}; + +struct call_transfer_flush_region { + struct pipe_transfer *transfer_ptr; + struct pipe_transfer transfer; + struct pipe_box box; +}; + +struct call_transfer_unmap { + struct pipe_transfer *transfer_ptr; + struct pipe_transfer transfer; +}; + +struct call_buffer_subdata { + struct pipe_resource *resource; + unsigned usage; + unsigned offset; + unsigned size; + const void *data; +}; + +struct call_texture_subdata { + struct pipe_resource *resource; + unsigned level; + unsigned usage; + struct pipe_box box; + const void *data; + unsigned stride; + unsigned layer_stride; +}; + +struct dd_call +{ + enum call_type type; + + union { + struct call_draw_info draw_vbo; + struct pipe_grid_info launch_grid; + struct call_resource_copy_region resource_copy_region; + struct pipe_blit_info blit; + struct pipe_resource *flush_resource; + struct call_clear clear; + struct call_clear_buffer clear_buffer; + struct call_generate_mipmap generate_mipmap; + struct call_get_query_result_resource get_query_result_resource; + struct call_transfer_map transfer_map; + struct call_transfer_flush_region transfer_flush_region; + struct call_transfer_unmap transfer_unmap; + struct call_buffer_subdata buffer_subdata; + struct call_texture_subdata texture_subdata; + } info; +}; + +struct dd_query +{ + unsigned type; + struct pipe_query *query; +}; + +struct dd_state +{ + void *cso; + + union { + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state dsa; + struct pipe_rasterizer_state rs; + struct pipe_sampler_state sampler; + struct { + struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS]; + unsigned count; + } velems; + struct pipe_shader_state shader; + } state; +}; + +struct dd_draw_state +{ + struct { + struct dd_query *query; + bool condition; + unsigned mode; + } render_cond; + + struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + + unsigned num_so_targets; + struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; + unsigned so_offsets[PIPE_MAX_SO_BUFFERS]; + + struct dd_state *shaders[PIPE_SHADER_TYPES]; + struct pipe_constant_buffer constant_buffers[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; + struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; + struct dd_state *sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; + struct pipe_image_view shader_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; + struct pipe_shader_buffer shader_buffers[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS]; + + struct dd_state *velems; + struct dd_state *rs; + struct dd_state *dsa; + struct dd_state *blend; + + struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; + unsigned sample_mask; + unsigned min_samples; + struct pipe_clip_state clip_state; + struct pipe_framebuffer_state framebuffer_state; + struct pipe_poly_stipple polygon_stipple; + struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS]; + struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS]; + float tess_default_levels[6]; + + unsigned apitrace_call_number; +}; + +struct dd_draw_state_copy +{ + struct dd_draw_state base; + + /* dd_draw_state_copy does not reference real CSOs. Instead, it points to + * these variables, which serve as storage. + */ + struct dd_query render_cond; + struct dd_state shaders[PIPE_SHADER_TYPES]; + struct dd_state sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; + struct dd_state velems; + struct dd_state rs; + struct dd_state dsa; + struct dd_state blend; +}; + +struct dd_draw_record { + struct list_head list; + struct dd_context *dctx; + + int64_t time_before; + int64_t time_after; + unsigned draw_call; + + struct pipe_fence_handle *prev_bottom_of_pipe; + struct pipe_fence_handle *top_of_pipe; + struct pipe_fence_handle *bottom_of_pipe; + + struct dd_call call; + struct dd_draw_state_copy draw_state; + + struct util_queue_fence driver_finished; + struct u_log_page *log_page; +}; + +struct dd_context +{ + struct pipe_context base; + struct pipe_context *pipe; + + struct dd_draw_state draw_state; + unsigned num_draw_calls; + + struct u_log_context log; + + /* Pipelined hang detection. + * + * This is without unnecessary flushes and waits. There is a memory-based + * fence that is incremented by clear_buffer every draw call. Driver fences + * are not used. + * + * After each draw call, a new dd_draw_record is created that contains + * a copy of all states, the output of pipe_context::dump_debug_state, + * and it has a fence number assigned. That's done without knowing whether + * that draw call is problematic or not. The record is added into the list + * of all records. + * + * An independent, separate thread loops over the list of records and checks + * their fences. Records with signalled fences are freed. On fence timeout, + * the thread dumps the records of in-flight draws. + */ + thrd_t thread; + mtx_t mutex; + cnd_t cond; + struct dd_draw_record *record_pending; /* currently inside the driver */ + struct list_head records; /* oldest record first */ + unsigned num_records; + bool kill_thread; + bool api_stalled; +}; + + +struct pipe_context * +dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe); + +void +dd_init_draw_functions(struct dd_context *dctx); + +void +dd_thread_join(struct dd_context *dctx); +int +dd_thread_main(void *input); + +FILE * +dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number); + +static inline struct dd_context * +dd_context(struct pipe_context *pipe) +{ + return (struct dd_context *)pipe; +} + +static inline struct dd_screen * +dd_screen(struct pipe_screen *screen) +{ + return (struct dd_screen*)screen; +} + +static inline struct dd_query * +dd_query(struct pipe_query *query) +{ + return (struct dd_query *)query; +} + +static inline struct pipe_query * +dd_query_unwrap(struct pipe_query *query) +{ + if (query) { + return dd_query(query)->query; + } else { + return NULL; + } +} + + +#define CTX_INIT(_member) \ + dctx->base._member = dctx->pipe->_member ? dd_context_##_member : NULL + +#endif /* DD_H_ */ diff --git a/src/gallium/auxiliary/driver_ddebug/dd_public.h b/src/gallium/auxiliary/driver_ddebug/dd_public.h new file mode 100644 index 00000000000..e6607655753 --- /dev/null +++ b/src/gallium/auxiliary/driver_ddebug/dd_public.h @@ -0,0 +1,36 @@ +/************************************************************************** + * + * Copyright 2015 Advanced Micro Devices, Inc. + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 DD_PUBLIC_H_ +#define DD_PUBLIC_H_ + +struct pipe_screen; + +struct pipe_screen * +ddebug_screen_create(struct pipe_screen *screen); + +#endif /* DD_PUBLIC_H_ */ diff --git a/src/gallium/auxiliary/driver_ddebug/dd_screen.c b/src/gallium/auxiliary/driver_ddebug/dd_screen.c new file mode 100644 index 00000000000..5b2be28a969 --- /dev/null +++ b/src/gallium/auxiliary/driver_ddebug/dd_screen.c @@ -0,0 +1,593 @@ +/************************************************************************** + * + * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2008 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "dd_pipe.h" +#include "dd_public.h" +#include "util/u_memory.h" +#include +#include + + +static const char * +dd_screen_get_name(struct pipe_screen *_screen) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_name(screen); +} + +static const char * +dd_screen_get_vendor(struct pipe_screen *_screen) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_vendor(screen); +} + +static const char * +dd_screen_get_device_vendor(struct pipe_screen *_screen) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_device_vendor(screen); +} + +static const void * +dd_screen_get_compiler_options(struct pipe_screen *_screen, + enum pipe_shader_ir ir, + enum pipe_shader_type shader) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_compiler_options(screen, ir, shader); +} + +static struct disk_cache * +dd_screen_get_disk_shader_cache(struct pipe_screen *_screen) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_disk_shader_cache(screen); +} + +static int +dd_screen_get_param(struct pipe_screen *_screen, + enum pipe_cap param) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_param(screen, param); +} + +static float +dd_screen_get_paramf(struct pipe_screen *_screen, + enum pipe_capf param) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_paramf(screen, param); +} + +static int +dd_screen_get_compute_param(struct pipe_screen *_screen, + enum pipe_shader_ir ir_type, + enum pipe_compute_cap param, + void *ret) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_compute_param(screen, ir_type, param, ret); +} + +static int +dd_screen_get_shader_param(struct pipe_screen *_screen, + enum pipe_shader_type shader, + enum pipe_shader_cap param) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_shader_param(screen, shader, param); +} + +static uint64_t +dd_screen_get_timestamp(struct pipe_screen *_screen) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_timestamp(screen); +} + +static void dd_screen_query_memory_info(struct pipe_screen *_screen, + struct pipe_memory_info *info) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->query_memory_info(screen, info); +} + +static struct pipe_context * +dd_screen_context_create(struct pipe_screen *_screen, void *priv, + unsigned flags) +{ + struct dd_screen *dscreen = dd_screen(_screen); + struct pipe_screen *screen = dscreen->screen; + + flags |= PIPE_CONTEXT_DEBUG; + + return dd_context_create(dscreen, + screen->context_create(screen, priv, flags)); +} + +static boolean +dd_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned tex_usage) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->is_format_supported(screen, format, target, sample_count, + tex_usage); +} + +static boolean +dd_screen_can_create_resource(struct pipe_screen *_screen, + const struct pipe_resource *templat) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->can_create_resource(screen, templat); +} + +static void +dd_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned level, unsigned layer, + void *context_private, + struct pipe_box *sub_box) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->flush_frontbuffer(screen, resource, level, layer, context_private, + sub_box); +} + +static int +dd_screen_get_driver_query_info(struct pipe_screen *_screen, + unsigned index, + struct pipe_driver_query_info *info) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_driver_query_info(screen, index, info); +} + +static int +dd_screen_get_driver_query_group_info(struct pipe_screen *_screen, + unsigned index, + struct pipe_driver_query_group_info *info) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->get_driver_query_group_info(screen, index, info); +} + + +static void +dd_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->get_driver_uuid(screen, uuid); +} + +static void +dd_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->get_device_uuid(screen, uuid); +} + +/******************************************************************** + * resource + */ + +static struct pipe_resource * +dd_screen_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_resource *res = screen->resource_create(screen, templat); + + if (!res) + return NULL; + res->screen = _screen; + return res; +} + +static struct pipe_resource * +dd_screen_resource_from_handle(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct winsys_handle *handle, + unsigned usage) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_resource *res = + screen->resource_from_handle(screen, templ, handle, usage); + + if (!res) + return NULL; + res->screen = _screen; + return res; +} + +static struct pipe_resource * +dd_screen_resource_from_user_memory(struct pipe_screen *_screen, + const struct pipe_resource *templ, + void *user_memory) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_resource *res = + screen->resource_from_user_memory(screen, templ, user_memory); + + if (!res) + return NULL; + res->screen = _screen; + return res; +} + +static struct pipe_resource * +dd_screen_resource_from_memobj(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_resource *res = + screen->resource_from_memobj(screen, templ, memobj, offset); + + if (!res) + return NULL; + res->screen = _screen; + return res; +} + +static void +dd_screen_resource_changed(struct pipe_screen *_screen, + struct pipe_resource *res) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->resource_changed(screen, res); +} + +static void +dd_screen_resource_destroy(struct pipe_screen *_screen, + struct pipe_resource *res) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->resource_destroy(screen, res); +} + +static boolean +dd_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_context *_pipe, + struct pipe_resource *resource, + struct winsys_handle *handle, + unsigned usage) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL; + + return screen->resource_get_handle(screen, pipe, resource, handle, usage); +} + +static bool +dd_screen_check_resource_capability(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned bind) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->check_resource_capability(screen, resource, bind); +} + + +/******************************************************************** + * fence + */ + +static void +dd_screen_fence_reference(struct pipe_screen *_screen, + struct pipe_fence_handle **pdst, + struct pipe_fence_handle *src) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->fence_reference(screen, pdst, src); +} + +static boolean +dd_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_context *_ctx, + struct pipe_fence_handle *fence, + uint64_t timeout) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_context *ctx = _ctx ? dd_context(_ctx)->pipe : NULL; + + return screen->fence_finish(screen, ctx, fence, timeout); +} + +/******************************************************************** + * memobj + */ + +static struct pipe_memory_object * +dd_screen_memobj_create_from_handle(struct pipe_screen *_screen, + struct winsys_handle *handle, + bool dedicated) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->memobj_create_from_handle(screen, handle, dedicated); +} + +static void +dd_screen_memobj_destroy(struct pipe_screen *_screen, + struct pipe_memory_object *memobj) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->memobj_destroy(screen, memobj); +} +/******************************************************************** + * screen + */ + +static void +dd_screen_destroy(struct pipe_screen *_screen) +{ + struct dd_screen *dscreen = dd_screen(_screen); + struct pipe_screen *screen = dscreen->screen; + + screen->destroy(screen); + FREE(dscreen); +} + +static void +skip_space(const char **p) +{ + while (isspace(**p)) + (*p)++; +} + +static bool +match_word(const char **cur, const char *word) +{ + size_t len = strlen(word); + if (strncmp(*cur, word, len) != 0) + return false; + + const char *p = *cur + len; + if (*p) { + if (!isspace(*p)) + return false; + + *cur = p + 1; + } else { + *cur = p; + } + + return true; +} + +static bool +match_uint(const char **cur, unsigned *value) +{ + char *end; + unsigned v = strtoul(*cur, &end, 0); + if (end == *cur || (*end && !isspace(*end))) + return false; + *cur = end; + *value = v; + return true; +} + +struct pipe_screen * +ddebug_screen_create(struct pipe_screen *screen) +{ + struct dd_screen *dscreen; + const char *option; + bool flush = false; + bool verbose = false; + bool transfers = false; + unsigned timeout = 1000; + unsigned apitrace_dump_call = 0; + enum dd_dump_mode mode = DD_DUMP_ONLY_HANGS; + + option = debug_get_option("GALLIUM_DDEBUG", NULL); + if (!option) + return screen; + + if (!strcmp(option, "help")) { + puts("Gallium driver debugger"); + puts(""); + puts("Usage:"); + puts(""); + puts(" GALLIUM_DDEBUG=\"[] [(always|apitrace "); + puts(" Change the default timeout for GPU hang detection (default=1000ms)."); + puts(" Setting this to 0 will disable GPU hang detection entirely."); + puts(""); + puts("always"); + puts(" Dump information about all draw calls."); + puts(""); + puts("transfers"); + puts(" Also dump and do hang detection on transfers."); + puts(""); + puts("apitrace "); + puts(" Dump information about the draw call corresponding to the given"); + puts(" apitrace call number and exit."); + puts(""); + puts("flush"); + puts(" Flush after every draw call."); + puts(""); + puts("verbose"); + puts(" Write additional information to stderr."); + puts(""); + puts("GALLIUM_DDEBUG_SKIP=count"); + puts(" Skip dumping on the first count draw calls (only relevant with 'always')."); + puts(""); + exit(0); + } + + for (;;) { + skip_space(&option); + if (!*option) + break; + + if (match_word(&option, "always")) { + if (mode == DD_DUMP_APITRACE_CALL) { + printf("ddebug: both 'always' and 'apitrace' specified\n"); + exit(1); + } + + mode = DD_DUMP_ALL_CALLS; + } else if (match_word(&option, "flush")) { + flush = true; + } else if (match_word(&option, "transfers")) { + transfers = true; + } else if (match_word(&option, "verbose")) { + verbose = true; + } else if (match_word(&option, "apitrace")) { + if (mode != DD_DUMP_ONLY_HANGS) { + printf("ddebug: 'apitrace' can only appear once and not mixed with 'always'\n"); + exit(1); + } + + if (!match_uint(&option, &apitrace_dump_call)) { + printf("ddebug: expected call number after 'apitrace'\n"); + exit(1); + } + + mode = DD_DUMP_APITRACE_CALL; + } else if (match_uint(&option, &timeout)) { + /* no-op */ + } else { + printf("ddebug: bad options: %s\n", option); + exit(1); + } + } + + dscreen = CALLOC_STRUCT(dd_screen); + if (!dscreen) + return NULL; + +#define SCR_INIT(_member) \ + dscreen->base._member = screen->_member ? dd_screen_##_member : NULL + + dscreen->base.destroy = dd_screen_destroy; + dscreen->base.get_name = dd_screen_get_name; + dscreen->base.get_vendor = dd_screen_get_vendor; + dscreen->base.get_device_vendor = dd_screen_get_device_vendor; + SCR_INIT(get_disk_shader_cache); + dscreen->base.get_param = dd_screen_get_param; + dscreen->base.get_paramf = dd_screen_get_paramf; + dscreen->base.get_compute_param = dd_screen_get_compute_param; + dscreen->base.get_shader_param = dd_screen_get_shader_param; + dscreen->base.query_memory_info = dd_screen_query_memory_info; + /* get_video_param */ + /* get_compute_param */ + SCR_INIT(get_timestamp); + dscreen->base.context_create = dd_screen_context_create; + dscreen->base.is_format_supported = dd_screen_is_format_supported; + /* is_video_format_supported */ + SCR_INIT(can_create_resource); + dscreen->base.resource_create = dd_screen_resource_create; + dscreen->base.resource_from_handle = dd_screen_resource_from_handle; + SCR_INIT(resource_from_memobj); + SCR_INIT(resource_from_user_memory); + SCR_INIT(check_resource_capability); + dscreen->base.resource_get_handle = dd_screen_resource_get_handle; + SCR_INIT(resource_changed); + dscreen->base.resource_destroy = dd_screen_resource_destroy; + SCR_INIT(flush_frontbuffer); + SCR_INIT(fence_reference); + SCR_INIT(fence_finish); + SCR_INIT(memobj_create_from_handle); + SCR_INIT(memobj_destroy); + SCR_INIT(get_driver_query_info); + SCR_INIT(get_driver_query_group_info); + SCR_INIT(get_compiler_options); + SCR_INIT(get_driver_uuid); + SCR_INIT(get_device_uuid); + +#undef SCR_INIT + + dscreen->screen = screen; + dscreen->timeout_ms = timeout; + dscreen->dump_mode = mode; + dscreen->flush_always = flush; + dscreen->transfers = transfers; + dscreen->verbose = verbose; + dscreen->apitrace_dump_call = apitrace_dump_call; + + switch (dscreen->dump_mode) { + case DD_DUMP_ALL_CALLS: + fprintf(stderr, "Gallium debugger active. Logging all calls.\n"); + break; + case DD_DUMP_APITRACE_CALL: + fprintf(stderr, "Gallium debugger active. Going to dump an apitrace call.\n"); + break; + default: + fprintf(stderr, "Gallium debugger active.\n"); + break; + } + + if (dscreen->timeout_ms > 0) + fprintf(stderr, "Hang detection timeout is %ums.\n", dscreen->timeout_ms); + else + fprintf(stderr, "Hang detection is disabled.\n"); + + dscreen->skip_count = debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0); + if (dscreen->skip_count > 0) { + fprintf(stderr, "Gallium debugger skipping the first %u draw calls.\n", + dscreen->skip_count); + } + + return &dscreen->base; +} diff --git a/src/gallium/auxiliary/driver_ddebug/dd_util.h b/src/gallium/auxiliary/driver_ddebug/dd_util.h new file mode 100644 index 00000000000..bdfb7cc9163 --- /dev/null +++ b/src/gallium/auxiliary/driver_ddebug/dd_util.h @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2015 Advanced Micro Devices, Inc. + * Copyright 2008 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 DD_UTIL_H +#define DD_UTIL_H + +#include +#include +#include +#include + +#include "c99_alloca.h" +#include "os/os_process.h" +#include "util/u_atomic.h" +#include "util/u_debug.h" + +/* name of the directory in home */ +#define DD_DIR "ddebug_dumps" + +static inline void +dd_get_debug_filename_and_mkdir(char *buf, size_t buflen, bool verbose) +{ + static unsigned index; + char proc_name[128], dir[256]; + + if (!os_get_process_name(proc_name, sizeof(proc_name))) { + fprintf(stderr, "dd: can't get the process name\n"); + strcpy(proc_name, "unknown"); + } + + snprintf(dir, sizeof(dir), "%s/"DD_DIR, debug_get_option("HOME", ".")); + + if (mkdir(dir, 0774) && errno != EEXIST) + fprintf(stderr, "dd: can't create a directory (%i)\n", errno); + + snprintf(buf, buflen, "%s/%s_%u_%08u", dir, proc_name, getpid(), + p_atomic_inc_return(&index) - 1); + + if (verbose) + fprintf(stderr, "dd: dumping to file %s\n", buf); +} + +static inline FILE * +dd_get_debug_file(bool verbose) +{ + char name[512]; + FILE *f; + + dd_get_debug_filename_and_mkdir(name, sizeof(name), verbose); + f = fopen(name, "w"); + if (!f) { + fprintf(stderr, "dd: can't open file %s\n", name); + return NULL; + } + + return f; +} + +static inline void +dd_parse_apitrace_marker(const char *string, int len, unsigned *call_number) +{ + unsigned num; + char *s; + + if (len <= 0) + return; + + /* Make it zero-terminated. */ + s = alloca(len + 1); + memcpy(s, string, len); + s[len] = 0; + + /* Parse the number. */ + errno = 0; + num = strtol(s, NULL, 10); + if (errno) + return; + + *call_number = num; +} + +#endif /* DD_UTIL_H */ diff --git a/src/gallium/auxiliary/driver_noop/noop_pipe.c b/src/gallium/auxiliary/driver_noop/noop_pipe.c new file mode 100644 index 00000000000..d1e795dab16 --- /dev/null +++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c @@ -0,0 +1,498 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 +#include +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_upload_mgr.h" +#include "noop_public.h" + +DEBUG_GET_ONCE_BOOL_OPTION(noop, "GALLIUM_NOOP", FALSE) + +void noop_init_state_functions(struct pipe_context *ctx); + +struct noop_pipe_screen { + struct pipe_screen pscreen; + struct pipe_screen *oscreen; +}; + +/* + * query + */ +struct noop_query { + unsigned query; +}; +static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index) +{ + struct noop_query *query = CALLOC_STRUCT(noop_query); + + return (struct pipe_query *)query; +} + +static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query) +{ + FREE(query); +} + +static boolean noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) +{ + return true; +} + +static bool noop_end_query(struct pipe_context *ctx, struct pipe_query *query) +{ + return true; +} + +static boolean noop_get_query_result(struct pipe_context *ctx, + struct pipe_query *query, + boolean wait, + union pipe_query_result *vresult) +{ + uint64_t *result = (uint64_t*)vresult; + + *result = 0; + return TRUE; +} + +static void +noop_set_active_query_state(struct pipe_context *pipe, boolean enable) +{ +} + + +/* + * resource + */ +struct noop_resource { + struct pipe_resource base; + unsigned size; + char *data; + struct sw_displaytarget *dt; +}; + +static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, + const struct pipe_resource *templ) +{ + struct noop_resource *nresource; + unsigned stride; + + nresource = CALLOC_STRUCT(noop_resource); + if (!nresource) + return NULL; + + stride = util_format_get_stride(templ->format, templ->width0); + nresource->base = *templ; + nresource->base.screen = screen; + nresource->size = stride * templ->height0 * templ->depth0; + nresource->data = MALLOC(nresource->size); + pipe_reference_init(&nresource->base.reference, 1); + if (nresource->data == NULL) { + FREE(nresource); + return NULL; + } + return &nresource->base; +} + +static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct winsys_handle *handle, + unsigned usage) +{ + struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; + struct pipe_screen *oscreen = noop_screen->oscreen; + struct pipe_resource *result; + struct pipe_resource *noop_resource; + + result = oscreen->resource_from_handle(oscreen, templ, handle, usage); + noop_resource = noop_resource_create(screen, result); + pipe_resource_reference(&result, NULL); + return noop_resource; +} + +static boolean noop_resource_get_handle(struct pipe_screen *pscreen, + struct pipe_context *ctx, + struct pipe_resource *resource, + struct winsys_handle *handle, + unsigned usage) +{ + struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; + struct pipe_screen *screen = noop_screen->oscreen; + struct pipe_resource *tex; + bool result; + + /* resource_get_handle musn't fail. Just create something and return it. */ + tex = screen->resource_create(screen, resource); + if (!tex) + return false; + + result = screen->resource_get_handle(screen, NULL, tex, handle, usage); + pipe_resource_reference(&tex, NULL); + return result; +} + +static void noop_resource_destroy(struct pipe_screen *screen, + struct pipe_resource *resource) +{ + struct noop_resource *nresource = (struct noop_resource *)resource; + + FREE(nresource->data); + FREE(resource); +} + + +/* + * transfer + */ +static void *noop_transfer_map(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + enum pipe_transfer_usage usage, + const struct pipe_box *box, + struct pipe_transfer **ptransfer) +{ + struct pipe_transfer *transfer; + struct noop_resource *nresource = (struct noop_resource *)resource; + + transfer = CALLOC_STRUCT(pipe_transfer); + if (!transfer) + return NULL; + pipe_resource_reference(&transfer->resource, resource); + transfer->level = level; + transfer->usage = usage; + transfer->box = *box; + transfer->stride = 1; + transfer->layer_stride = 1; + *ptransfer = transfer; + + return nresource->data; +} + +static void noop_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ +} + +static void noop_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + pipe_resource_reference(&transfer->resource, NULL); + FREE(transfer); +} + +static void noop_buffer_subdata(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned usage, unsigned offset, + unsigned size, const void *data) +{ +} + +static void noop_texture_subdata(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride) +{ +} + + +/* + * clear/copy + */ +static void noop_clear(struct pipe_context *ctx, unsigned buffers, + const union pipe_color_union *color, double depth, unsigned stencil) +{ +} + +static void noop_clear_render_target(struct pipe_context *ctx, + struct pipe_surface *dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ +} + +static void noop_clear_depth_stencil(struct pipe_context *ctx, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ +} + +static void noop_resource_copy_region(struct pipe_context *ctx, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + unsigned src_level, + const struct pipe_box *src_box) +{ +} + + +static void noop_blit(struct pipe_context *ctx, + const struct pipe_blit_info *info) +{ +} + + +static void +noop_flush_resource(struct pipe_context *ctx, + struct pipe_resource *resource) +{ +} + + +/* + * context + */ +static void noop_flush(struct pipe_context *ctx, + struct pipe_fence_handle **fence, + unsigned flags) +{ + if (fence) + *fence = NULL; +} + +static void noop_destroy_context(struct pipe_context *ctx) +{ + if (ctx->stream_uploader) + u_upload_destroy(ctx->stream_uploader); + + FREE(ctx); +} + +static boolean noop_generate_mipmap(struct pipe_context *ctx, + struct pipe_resource *resource, + enum pipe_format format, + unsigned base_level, + unsigned last_level, + unsigned first_layer, + unsigned last_layer) +{ + return true; +} + +static struct pipe_context *noop_create_context(struct pipe_screen *screen, + void *priv, unsigned flags) +{ + struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); + + if (!ctx) + return NULL; + + ctx->screen = screen; + ctx->priv = priv; + + ctx->stream_uploader = u_upload_create_default(ctx); + if (!ctx->stream_uploader) { + FREE(ctx); + return NULL; + } + ctx->const_uploader = ctx->stream_uploader; + + ctx->destroy = noop_destroy_context; + ctx->flush = noop_flush; + ctx->clear = noop_clear; + ctx->clear_render_target = noop_clear_render_target; + ctx->clear_depth_stencil = noop_clear_depth_stencil; + ctx->resource_copy_region = noop_resource_copy_region; + ctx->generate_mipmap = noop_generate_mipmap; + ctx->blit = noop_blit; + ctx->flush_resource = noop_flush_resource; + ctx->create_query = noop_create_query; + ctx->destroy_query = noop_destroy_query; + ctx->begin_query = noop_begin_query; + ctx->end_query = noop_end_query; + ctx->get_query_result = noop_get_query_result; + ctx->set_active_query_state = noop_set_active_query_state; + ctx->transfer_map = noop_transfer_map; + ctx->transfer_flush_region = noop_transfer_flush_region; + ctx->transfer_unmap = noop_transfer_unmap; + ctx->buffer_subdata = noop_buffer_subdata; + ctx->texture_subdata = noop_texture_subdata; + noop_init_state_functions(ctx); + + return ctx; +} + + +/* + * pipe_screen + */ +static void noop_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned level, unsigned layer, + void *context_private, struct pipe_box *box) +{ +} + +static const char *noop_get_vendor(struct pipe_screen* pscreen) +{ + return "X.Org"; +} + +static const char *noop_get_device_vendor(struct pipe_screen* pscreen) +{ + return "NONE"; +} + +static const char *noop_get_name(struct pipe_screen* pscreen) +{ + return "NOOP"; +} + +static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) +{ + struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; + + return screen->get_param(screen, param); +} + +static float noop_get_paramf(struct pipe_screen* pscreen, + enum pipe_capf param) +{ + struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; + + return screen->get_paramf(screen, param); +} + +static int noop_get_shader_param(struct pipe_screen* pscreen, + enum pipe_shader_type shader, + enum pipe_shader_cap param) +{ + struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; + + return screen->get_shader_param(screen, shader, param); +} + +static int noop_get_compute_param(struct pipe_screen *pscreen, + enum pipe_shader_ir ir_type, + enum pipe_compute_cap param, + void *ret) +{ + struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; + + return screen->get_compute_param(screen, ir_type, param, ret); +} + +static boolean noop_is_format_supported(struct pipe_screen* pscreen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned usage) +{ + struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; + + return screen->is_format_supported(screen, format, target, sample_count, usage); +} + +static uint64_t noop_get_timestamp(struct pipe_screen *pscreen) +{ + return 0; +} + +static void noop_destroy_screen(struct pipe_screen *screen) +{ + struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; + struct pipe_screen *oscreen = noop_screen->oscreen; + + oscreen->destroy(oscreen); + FREE(screen); +} + +static void noop_fence_reference(struct pipe_screen *screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + +static boolean noop_fence_finish(struct pipe_screen *screen, + struct pipe_context *ctx, + struct pipe_fence_handle *fence, + uint64_t timeout) +{ + return true; +} + +static void noop_query_memory_info(struct pipe_screen *pscreen, + struct pipe_memory_info *info) +{ + struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; + struct pipe_screen *screen = noop_screen->oscreen; + + screen->query_memory_info(screen, info); +} + +struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) +{ + struct noop_pipe_screen *noop_screen; + struct pipe_screen *screen; + + if (!debug_get_option_noop()) { + return oscreen; + } + + noop_screen = CALLOC_STRUCT(noop_pipe_screen); + if (!noop_screen) { + return NULL; + } + noop_screen->oscreen = oscreen; + screen = &noop_screen->pscreen; + + screen->destroy = noop_destroy_screen; + screen->get_name = noop_get_name; + screen->get_vendor = noop_get_vendor; + screen->get_device_vendor = noop_get_device_vendor; + screen->get_param = noop_get_param; + screen->get_shader_param = noop_get_shader_param; + screen->get_compute_param = noop_get_compute_param; + screen->get_paramf = noop_get_paramf; + screen->is_format_supported = noop_is_format_supported; + screen->context_create = noop_create_context; + screen->resource_create = noop_resource_create; + screen->resource_from_handle = noop_resource_from_handle; + screen->resource_get_handle = noop_resource_get_handle; + screen->resource_destroy = noop_resource_destroy; + screen->flush_frontbuffer = noop_flush_frontbuffer; + screen->get_timestamp = noop_get_timestamp; + screen->fence_reference = noop_fence_reference; + screen->fence_finish = noop_fence_finish; + screen->query_memory_info = noop_query_memory_info; + + return screen; +} diff --git a/src/gallium/auxiliary/driver_noop/noop_public.h b/src/gallium/auxiliary/driver_noop/noop_public.h new file mode 100644 index 00000000000..180ea597fab --- /dev/null +++ b/src/gallium/auxiliary/driver_noop/noop_public.h @@ -0,0 +1,29 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 NOOP_PUBLIC_H +#define NOOP_PUBLIC_H + +struct pipe_screen; +struct pipe_screen *noop_screen_create(struct pipe_screen *screen); + +#endif diff --git a/src/gallium/auxiliary/driver_noop/noop_state.c b/src/gallium/auxiliary/driver_noop/noop_state.c new file mode 100644 index 00000000000..80cfae8ad49 --- /dev/null +++ b/src/gallium/auxiliary/driver_noop/noop_state.c @@ -0,0 +1,307 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 +#include +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_transfer.h" + +static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) +{ +} + +static void noop_launch_grid(struct pipe_context *ctx, + const struct pipe_grid_info *info) +{ +} + +static void noop_set_blend_color(struct pipe_context *ctx, + const struct pipe_blend_color *state) +{ +} + +static void *noop_create_blend_state(struct pipe_context *ctx, + const struct pipe_blend_state *state) +{ + return MALLOC(1); +} + +static void *noop_create_dsa_state(struct pipe_context *ctx, + const struct pipe_depth_stencil_alpha_state *state) +{ + return MALLOC(1); +} + +static void *noop_create_rs_state(struct pipe_context *ctx, + const struct pipe_rasterizer_state *state) +{ + return MALLOC(1); +} + +static void *noop_create_sampler_state(struct pipe_context *ctx, + const struct pipe_sampler_state *state) +{ + return MALLOC(1); +} + +static struct pipe_sampler_view *noop_create_sampler_view(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *state) +{ + struct pipe_sampler_view *sampler_view = CALLOC_STRUCT(pipe_sampler_view); + + if (!sampler_view) + return NULL; + + /* initialize base object */ + *sampler_view = *state; + sampler_view->texture = NULL; + pipe_resource_reference(&sampler_view->texture, texture); + pipe_reference_init(&sampler_view->reference, 1); + sampler_view->context = ctx; + return sampler_view; +} + +static struct pipe_surface *noop_create_surface(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_surface *surf_tmpl) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + if (!surface) + return NULL; + pipe_reference_init(&surface->reference, 1); + pipe_resource_reference(&surface->texture, texture); + surface->context = ctx; + surface->format = surf_tmpl->format; + surface->width = texture->width0; + surface->height = texture->height0; + surface->texture = texture; + surface->u.tex.first_layer = surf_tmpl->u.tex.first_layer; + surface->u.tex.last_layer = surf_tmpl->u.tex.last_layer; + surface->u.tex.level = surf_tmpl->u.tex.level; + + return surface; +} + +static void noop_set_sampler_views(struct pipe_context *ctx, + enum pipe_shader_type shader, + unsigned start, unsigned count, + struct pipe_sampler_view **views) +{ +} + +static void noop_bind_sampler_states(struct pipe_context *ctx, + enum pipe_shader_type shader, + unsigned start, unsigned count, + void **states) +{ +} + +static void noop_set_clip_state(struct pipe_context *ctx, + const struct pipe_clip_state *state) +{ +} + +static void noop_set_polygon_stipple(struct pipe_context *ctx, + const struct pipe_poly_stipple *state) +{ +} + +static void noop_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +{ +} + +static void noop_set_scissor_states(struct pipe_context *ctx, + unsigned start_slot, + unsigned num_scissors, + const struct pipe_scissor_state *state) +{ +} + +static void noop_set_stencil_ref(struct pipe_context *ctx, + const struct pipe_stencil_ref *state) +{ +} + +static void noop_set_viewport_states(struct pipe_context *ctx, + unsigned start_slot, + unsigned num_viewports, + const struct pipe_viewport_state *state) +{ +} + +static void noop_set_framebuffer_state(struct pipe_context *ctx, + const struct pipe_framebuffer_state *state) +{ +} + +static void noop_set_constant_buffer(struct pipe_context *ctx, + enum pipe_shader_type shader, uint index, + const struct pipe_constant_buffer *cb) +{ +} + + +static void noop_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *state) +{ + pipe_resource_reference(&state->texture, NULL); + FREE(state); +} + + +static void noop_surface_destroy(struct pipe_context *ctx, + struct pipe_surface *surface) +{ + pipe_resource_reference(&surface->texture, NULL); + FREE(surface); +} + +static void noop_bind_state(struct pipe_context *ctx, void *state) +{ +} + +static void noop_delete_state(struct pipe_context *ctx, void *state) +{ + FREE(state); +} + +static void noop_set_vertex_buffers(struct pipe_context *ctx, + unsigned start_slot, unsigned count, + const struct pipe_vertex_buffer *buffers) +{ +} + +static void *noop_create_vertex_elements(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *state) +{ + return MALLOC(1); +} + +static void *noop_create_shader_state(struct pipe_context *ctx, + const struct pipe_shader_state *state) +{ + return MALLOC(1); +} + +static void *noop_create_compute_state(struct pipe_context *ctx, + const struct pipe_compute_state *state) +{ + return MALLOC(1); +} + +static struct pipe_stream_output_target *noop_create_stream_output_target( + struct pipe_context *ctx, + struct pipe_resource *res, + unsigned buffer_offset, + unsigned buffer_size) +{ + struct pipe_stream_output_target *t = CALLOC_STRUCT(pipe_stream_output_target); + if (!t) + return NULL; + + pipe_reference_init(&t->reference, 1); + pipe_resource_reference(&t->buffer, res); + t->buffer_offset = buffer_offset; + t->buffer_size = buffer_size; + return t; +} + +static void noop_stream_output_target_destroy(struct pipe_context *ctx, + struct pipe_stream_output_target *t) +{ + pipe_resource_reference(&t->buffer, NULL); + FREE(t); +} + +static void noop_set_stream_output_targets(struct pipe_context *ctx, + unsigned num_targets, + struct pipe_stream_output_target **targets, + const unsigned *offsets) +{ +} + +void noop_init_state_functions(struct pipe_context *ctx); + +void noop_init_state_functions(struct pipe_context *ctx) +{ + ctx->create_blend_state = noop_create_blend_state; + ctx->create_depth_stencil_alpha_state = noop_create_dsa_state; + ctx->create_fs_state = noop_create_shader_state; + ctx->create_rasterizer_state = noop_create_rs_state; + ctx->create_sampler_state = noop_create_sampler_state; + ctx->create_sampler_view = noop_create_sampler_view; + ctx->create_surface = noop_create_surface; + ctx->create_vertex_elements_state = noop_create_vertex_elements; + ctx->create_compute_state = noop_create_compute_state; + ctx->create_tcs_state = noop_create_shader_state; + ctx->create_tes_state = noop_create_shader_state; + ctx->create_gs_state = noop_create_shader_state; + ctx->create_vs_state = noop_create_shader_state; + ctx->bind_blend_state = noop_bind_state; + ctx->bind_depth_stencil_alpha_state = noop_bind_state; + ctx->bind_sampler_states = noop_bind_sampler_states; + ctx->bind_fs_state = noop_bind_state; + ctx->bind_rasterizer_state = noop_bind_state; + ctx->bind_vertex_elements_state = noop_bind_state; + ctx->bind_compute_state = noop_bind_state; + ctx->bind_tcs_state = noop_bind_state; + ctx->bind_tes_state = noop_bind_state; + ctx->bind_gs_state = noop_bind_state; + ctx->bind_vs_state = noop_bind_state; + ctx->delete_blend_state = noop_delete_state; + ctx->delete_depth_stencil_alpha_state = noop_delete_state; + ctx->delete_fs_state = noop_delete_state; + ctx->delete_rasterizer_state = noop_delete_state; + ctx->delete_sampler_state = noop_delete_state; + ctx->delete_vertex_elements_state = noop_delete_state; + ctx->delete_compute_state = noop_delete_state; + ctx->delete_tcs_state = noop_delete_state; + ctx->delete_tes_state = noop_delete_state; + ctx->delete_gs_state = noop_delete_state; + ctx->delete_vs_state = noop_delete_state; + ctx->set_blend_color = noop_set_blend_color; + ctx->set_clip_state = noop_set_clip_state; + ctx->set_constant_buffer = noop_set_constant_buffer; + ctx->set_sampler_views = noop_set_sampler_views; + ctx->set_framebuffer_state = noop_set_framebuffer_state; + ctx->set_polygon_stipple = noop_set_polygon_stipple; + ctx->set_sample_mask = noop_set_sample_mask; + ctx->set_scissor_states = noop_set_scissor_states; + ctx->set_stencil_ref = noop_set_stencil_ref; + ctx->set_vertex_buffers = noop_set_vertex_buffers; + ctx->set_viewport_states = noop_set_viewport_states; + ctx->sampler_view_destroy = noop_sampler_view_destroy; + ctx->surface_destroy = noop_surface_destroy; + ctx->draw_vbo = noop_draw_vbo; + ctx->launch_grid = noop_launch_grid; + ctx->create_stream_output_target = noop_create_stream_output_target; + ctx->stream_output_target_destroy = noop_stream_output_target_destroy; + ctx->set_stream_output_targets = noop_set_stream_output_targets; +} diff --git a/src/gallium/auxiliary/driver_rbug/README b/src/gallium/auxiliary/driver_rbug/README new file mode 100644 index 00000000000..0edf0ad89de --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/README @@ -0,0 +1,44 @@ + RBUG PIPE DRIVER + + += About = + +This directory contains a Gallium3D remote debugger pipe driver. +It provides remote debugging functionality. + + += Usage = + +Do + + GALLIUM_RBUG=true progs/trivial/tri + +which should open gallium remote debugging session. While the program is running +you can launch the small remote debugging application from progs/rbug. More +information is in that directory. Also for a gui see: + + http://cgit.freedesktop.org/mesa/rbug-gui + + += Integrating = + +You can integrate the rbug pipe driver either inside the state tracker or the +target. The procedure on both cases is the same. Let's assume you have a +pipe_screen obtained by the usual means (variable and function names are just +for illustration purposes): + + real_screen = real_screen_create(...); + +The rbug screen is then created by doing + + rbug_screen = rbug_screen_create(real_screen); + +You can then simply use rbug_screen instead of real_screen. + +You can create as many contexts you wish from rbug_screen::context_create they +are automatically wrapped by rbug_screen. + + +-- +Jose Fonseca +Jakob Bornecrantz diff --git a/src/gallium/auxiliary/driver_rbug/rbug_context.c b/src/gallium/auxiliary/driver_rbug/rbug_context.c new file mode 100644 index 00000000000..e1f3c4f2844 --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_context.c @@ -0,0 +1,1274 @@ +/************************************************************************** + * + * 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 "util/simple_list.h" + +#include "rbug/rbug_context.h" + +#include "rbug_context.h" +#include "rbug_objects.h" + + +static void +rbug_destroy(struct pipe_context *_pipe) +{ + struct rbug_screen *rb_screen = rbug_screen(_pipe->screen); + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + rbug_screen_remove_from_list(rb_screen, contexts, rb_pipe); + + mtx_lock(&rb_pipe->call_mutex); + pipe->destroy(pipe); + rb_pipe->pipe = NULL; + mtx_unlock(&rb_pipe->call_mutex); + + FREE(rb_pipe); +} + +static void +rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag) +{ + + if (rb_pipe->draw_blocker & flag) { + rb_pipe->draw_blocked |= flag; + } else if ((rb_pipe->draw_rule.blocker & flag) && + (rb_pipe->draw_blocker & RBUG_BLOCK_RULE)) { + unsigned k; + boolean block = FALSE; + unsigned sh; + + debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__, + (void *) rb_pipe->draw_rule.shader[PIPE_SHADER_FRAGMENT], + (void *) rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT], + (void *) rb_pipe->draw_rule.shader[PIPE_SHADER_VERTEX], + (void *) rb_pipe->curr.shader[PIPE_SHADER_VERTEX], + (void *) rb_pipe->draw_rule.surf, 0, + (void *) rb_pipe->draw_rule.texture, 0); + for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { + if (rb_pipe->draw_rule.shader[sh] && + rb_pipe->draw_rule.shader[sh] == rb_pipe->curr.shader[sh]) + block = TRUE; + } + + if (rb_pipe->draw_rule.surf && + rb_pipe->draw_rule.surf == rb_pipe->curr.zsbuf) + block = TRUE; + if (rb_pipe->draw_rule.surf) + for (k = 0; k < rb_pipe->curr.nr_cbufs; k++) + if (rb_pipe->draw_rule.surf == rb_pipe->curr.cbufs[k]) + block = TRUE; + if (rb_pipe->draw_rule.texture) { + for (sh = 0; sh < ARRAY_SIZE(rb_pipe->curr.num_views); sh++) { + for (k = 0; k < rb_pipe->curr.num_views[sh]; k++) { + if (rb_pipe->draw_rule.texture == rb_pipe->curr.texs[sh][k]) { + block = TRUE; + sh = PIPE_SHADER_TYPES; /* to break out of both loops */ + break; + } + } + } + } + + if (block) + rb_pipe->draw_blocked |= (flag | RBUG_BLOCK_RULE); + } + + if (rb_pipe->draw_blocked) + rbug_notify_draw_blocked(rb_pipe); + + /* wait for rbug to clear the blocked flag */ + while (rb_pipe->draw_blocked & flag) { + rb_pipe->draw_blocked |= flag; + cnd_wait(&rb_pipe->draw_cond, &rb_pipe->draw_mutex); + } + +} + +static void +rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->draw_mutex); + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); + + mtx_lock(&rb_pipe->call_mutex); + /* XXX loop over PIPE_SHADER_x here */ + if (!(rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT] && rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT]->disabled) && + !(rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY] && rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY]->disabled) && + !(rb_pipe->curr.shader[PIPE_SHADER_VERTEX] && rb_pipe->curr.shader[PIPE_SHADER_VERTEX]->disabled)) + pipe->draw_vbo(pipe, info); + mtx_unlock(&rb_pipe->call_mutex); + + rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); + mtx_unlock(&rb_pipe->draw_mutex); +} + +static struct pipe_query * +rbug_create_query(struct pipe_context *_pipe, + unsigned query_type, + unsigned index) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_query *query; + + mtx_lock(&rb_pipe->call_mutex); + query = pipe->create_query(pipe, + query_type, + index); + mtx_unlock(&rb_pipe->call_mutex); + return query; +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->destroy_query(pipe, + query); + mtx_unlock(&rb_pipe->call_mutex); +} + +static boolean +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; + boolean ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->begin_query(pipe, query); + mtx_unlock(&rb_pipe->call_mutex); + return ret; +} + +static bool +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; + bool ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->end_query(pipe, + query); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +static boolean +rbug_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + union pipe_query_result *result) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + boolean ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->get_query_result(pipe, + query, + wait, + result); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +static void +rbug_set_active_query_state(struct pipe_context *_pipe, boolean enable) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_active_query_state(pipe, enable); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + void *ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->create_blend_state(pipe, + blend); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->bind_blend_state(pipe, + blend); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->delete_blend_state(pipe, + blend); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + void *ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->create_sampler_state(pipe, + sampler); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +static void +rbug_bind_sampler_states(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, unsigned count, + void **samplers) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->bind_sampler_states(pipe, shader, start, count, samplers); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->delete_sampler_state(pipe, + sampler); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + void *ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->create_rasterizer_state(pipe, + rasterizer); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->bind_rasterizer_state(pipe, + rasterizer); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->delete_rasterizer_state(pipe, + rasterizer); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + void *ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->create_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->bind_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->delete_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void * +rbug_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + mtx_lock(&rb_pipe->call_mutex); + result = pipe->create_fs_state(pipe, state); + mtx_unlock(&rb_pipe->call_mutex); + + if (!result) + return NULL; + + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_FRAGMENT); +} + +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; + void *fs; + + mtx_lock(&rb_pipe->call_mutex); + + fs = rbug_shader_unwrap(_fs); + rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT] = rbug_shader(_fs); + pipe->bind_fs_state(pipe, + fs); + + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_delete_fs_state(struct pipe_context *_pipe, + void *_fs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_fs); + + mtx_lock(&rb_pipe->call_mutex); + rbug_shader_destroy(rb_pipe, rb_shader); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void * +rbug_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + mtx_lock(&rb_pipe->call_mutex); + result = pipe->create_vs_state(pipe, state); + mtx_unlock(&rb_pipe->call_mutex); + + if (!result) + return NULL; + + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_VERTEX); +} + +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; + void *vs; + + mtx_lock(&rb_pipe->call_mutex); + + vs = rbug_shader_unwrap(_vs); + rb_pipe->curr.shader[PIPE_SHADER_VERTEX] = rbug_shader(_vs); + pipe->bind_vs_state(pipe, + vs); + + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_delete_vs_state(struct pipe_context *_pipe, + void *_vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_vs); + + mtx_unlock(&rb_pipe->call_mutex); + rbug_shader_destroy(rb_pipe, rb_shader); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void * +rbug_create_gs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + mtx_lock(&rb_pipe->call_mutex); + result = pipe->create_gs_state(pipe, state); + mtx_unlock(&rb_pipe->call_mutex); + + if (!result) + return NULL; + + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_GEOM); +} + +static void +rbug_bind_gs_state(struct pipe_context *_pipe, + void *_gs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + void *gs; + + mtx_lock(&rb_pipe->call_mutex); + + gs = rbug_shader_unwrap(_gs); + rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY] = rbug_shader(_gs); + pipe->bind_gs_state(pipe, + gs); + + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_delete_gs_state(struct pipe_context *_pipe, + void *_gs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_gs); + + mtx_lock(&rb_pipe->call_mutex); + rbug_shader_destroy(rb_pipe, rb_shader); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + void *ret; + + mtx_lock(&rb_pipe->call_mutex); + ret = pipe->create_vertex_elements_state(pipe, + num_elements, + vertex_elements); + mtx_unlock(&rb_pipe->call_mutex); + + return ret; +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->bind_vertex_elements_state(pipe, + velems); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->delete_vertex_elements_state(pipe, + velems); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_blend_color(pipe, + blend_color); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_stencil_ref(pipe, + stencil_ref); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_clip_state(pipe, + clip); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_constant_buffer(struct pipe_context *_pipe, + enum pipe_shader_type shader, + uint index, + const struct pipe_constant_buffer *_cb) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_constant_buffer cb; + + /* XXX hmm? unwrap the input state */ + if (_cb) { + cb = *_cb; + cb.buffer = rbug_resource_unwrap(_cb->buffer); + } + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_constant_buffer(pipe, + shader, + index, + _cb ? &cb : NULL); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + /* must protect curr status */ + mtx_lock(&rb_pipe->call_mutex); + + rb_pipe->curr.nr_cbufs = 0; + memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs)); + rb_pipe->curr.zsbuf = NULL; + + /* unwrap the input state */ + if (_state) { + memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); + + rb_pipe->curr.nr_cbufs = _state->nr_cbufs; + for(i = 0; i < _state->nr_cbufs; i++) { + unwrapped_state.cbufs[i] = rbug_surface_unwrap(_state->cbufs[i]); + if (_state->cbufs[i]) + rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture); + } + unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf); + if (_state->zsbuf) + rb_pipe->curr.zsbuf = rbug_resource(_state->zsbuf->texture); + state = &unwrapped_state; + } + + pipe->set_framebuffer_state(pipe, + state); + + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_polygon_stipple(pipe, + poly_stipple); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_scissor_states(struct pipe_context *_pipe, + unsigned start_slot, + unsigned num_scissors, + const struct pipe_scissor_state *scissor) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_scissor_states(pipe, start_slot, num_scissors, scissor); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_viewport_states(struct pipe_context *_pipe, + unsigned start_slot, + unsigned num_viewports, + const struct pipe_viewport_state *viewport) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_viewport_states(pipe, start_slot, num_viewports, viewport); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_sampler_views(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, + 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_SHADER_SAMPLER_VIEWS]; + struct pipe_sampler_view **views = NULL; + unsigned i; + + assert(start == 0); /* XXX fix */ + + /* must protect curr status */ + mtx_lock(&rb_pipe->call_mutex); + + rb_pipe->curr.num_views[shader] = 0; + memset(rb_pipe->curr.views[shader], 0, sizeof(rb_pipe->curr.views[shader])); + memset(rb_pipe->curr.texs[shader], 0, sizeof(rb_pipe->curr.texs[shader])); + memset(unwrapped_views, 0, sizeof(unwrapped_views)); + + if (_views) { + rb_pipe->curr.num_views[shader] = num; + for (i = 0; i < num; i++) { + rb_pipe->curr.views[shader][i] = rbug_sampler_view(_views[i]); + rb_pipe->curr.texs[shader][i] = rbug_resource(_views[i] ? _views[i]->texture : NULL); + unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]); + } + views = unwrapped_views; + } + + pipe->set_sampler_views(pipe, shader, start, num, views); + + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_vertex_buffers(struct pipe_context *_pipe, + unsigned start_slot, 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; + + mtx_lock(&rb_pipe->call_mutex); + + if (num_buffers && _buffers) { + memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); + for (i = 0; i < num_buffers; i++) { + if (!_buffers[i].is_user_buffer) + unwrapped_buffers[i].buffer.resource = + rbug_resource_unwrap(_buffers[i].buffer.resource); + } + buffers = unwrapped_buffers; + } + + pipe->set_vertex_buffers(pipe, start_slot, + num_buffers, + buffers); + + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_sample_mask(struct pipe_context *_pipe, + unsigned sample_mask) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_sample_mask(pipe, sample_mask); + mtx_unlock(&rb_pipe->call_mutex); +} + +static struct pipe_stream_output_target * +rbug_create_stream_output_target(struct pipe_context *_pipe, + struct pipe_resource *_res, + unsigned buffer_offset, unsigned buffer_size) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *res = rbug_resource_unwrap(_res); + struct pipe_stream_output_target *target; + + mtx_lock(&rb_pipe->call_mutex); + target = pipe->create_stream_output_target(pipe, res, buffer_offset, + buffer_size); + mtx_unlock(&rb_pipe->call_mutex); + return target; +} + +static void +rbug_stream_output_target_destroy(struct pipe_context *_pipe, + struct pipe_stream_output_target *target) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->stream_output_target_destroy(pipe, target); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_set_stream_output_targets(struct pipe_context *_pipe, + unsigned num_targets, + struct pipe_stream_output_target **targets, + const unsigned *offsets) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->set_stream_output_targets(pipe, num_targets, targets, offsets); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_resource_copy_region(struct pipe_context *_pipe, + struct pipe_resource *_dst, + unsigned dst_level, + unsigned dstx, + unsigned dsty, + unsigned dstz, + struct pipe_resource *_src, + unsigned src_level, + const struct pipe_box *src_box) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource_dst = rbug_resource(_dst); + struct rbug_resource *rb_resource_src = rbug_resource(_src); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *dst = rb_resource_dst->resource; + struct pipe_resource *src = rb_resource_src->resource; + + mtx_lock(&rb_pipe->call_mutex); + pipe->resource_copy_region(pipe, + dst, + dst_level, + dstx, + dsty, + dstz, + src, + src_level, + src_box); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_blit(struct pipe_context *_pipe, const struct pipe_blit_info *_blit_info) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource_dst = rbug_resource(_blit_info->dst.resource); + struct rbug_resource *rb_resource_src = rbug_resource(_blit_info->src.resource); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *dst = rb_resource_dst->resource; + struct pipe_resource *src = rb_resource_src->resource; + struct pipe_blit_info blit_info; + + blit_info = *_blit_info; + blit_info.dst.resource = dst; + blit_info.src.resource = src; + + mtx_lock(&rb_pipe->call_mutex); + pipe->blit(pipe, &blit_info); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_flush_resource(struct pipe_context *_pipe, + struct pipe_resource *_res) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_resource *rb_resource_res = rbug_resource(_res); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_resource *res = rb_resource_res->resource; + + mtx_lock(&rb_pipe->call_mutex); + pipe->flush_resource(pipe, res); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_clear(struct pipe_context *_pipe, + unsigned buffers, + const union pipe_color_union *color, + double depth, + unsigned stencil) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->clear(pipe, + buffers, + color, + depth, + stencil); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_clear_render_target(struct pipe_context *_pipe, + struct pipe_surface *_dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + 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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->clear_render_target(pipe, + dst, + color, + dstx, + dsty, + width, + height, + render_condition_enabled); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_clear_depth_stencil(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + 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; + + mtx_lock(&rb_pipe->call_mutex); + pipe->clear_depth_stencil(pipe, + dst, + clear_flags, + depth, + stencil, + dstx, + dsty, + width, + height, + render_condition_enabled); + mtx_unlock(&rb_pipe->call_mutex); +} + +static void +rbug_flush(struct pipe_context *_pipe, + struct pipe_fence_handle **fence, + unsigned flags) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + + mtx_lock(&rb_pipe->call_mutex); + pipe->flush(pipe, fence, flags); + mtx_unlock(&rb_pipe->call_mutex); +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + result = pipe->create_sampler_view(pipe, + resource, + templ); + mtx_unlock(&rb_pipe->call_mutex); + + 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_surface * +rbug_context_create_surface(struct pipe_context *_pipe, + struct pipe_resource *_resource, + const struct pipe_surface *surf_tmpl) +{ + 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_surface *result; + + mtx_lock(&rb_pipe->call_mutex); + result = pipe->create_surface(pipe, + resource, + surf_tmpl); + mtx_unlock(&rb_pipe->call_mutex); + + if (result) + return rbug_surface_create(rb_pipe, rb_resource, result); + return NULL; +} + +static void +rbug_context_surface_destroy(struct pipe_context *_pipe, + struct pipe_surface *_surface) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_surface *rb_surface = rbug_surface(_surface); + + mtx_lock(&rb_pipe->call_mutex); + rbug_surface_destroy(rb_pipe, + rb_surface); + mtx_unlock(&rb_pipe->call_mutex); +} + + + +static void * +rbug_context_transfer_map(struct pipe_context *_context, + struct pipe_resource *_resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + struct pipe_transfer **transfer) +{ + 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; + void *map; + + mtx_lock(&rb_pipe->call_mutex); + map = context->transfer_map(context, + resource, + level, + usage, + box, &result); + mtx_unlock(&rb_pipe->call_mutex); + + *transfer = rbug_transfer_create(rb_pipe, rb_resource, result); + return *transfer ? map : NULL; +} + +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; + + mtx_lock(&rb_pipe->call_mutex); + context->transfer_flush_region(context, + transfer, + box); + mtx_unlock(&rb_pipe->call_mutex); +} + + +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; + + mtx_lock(&rb_pipe->call_mutex); + context->transfer_unmap(context, + transfer); + rbug_transfer_destroy(rb_pipe, + rb_transfer); + mtx_unlock(&rb_pipe->call_mutex); +} + + +static void +rbug_context_buffer_subdata(struct pipe_context *_context, + struct pipe_resource *_resource, + unsigned usage, unsigned offset, + unsigned size, const void *data) +{ + 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; + + mtx_lock(&rb_pipe->call_mutex); + context->buffer_subdata(context, resource, usage, offset, size, data); + mtx_unlock(&rb_pipe->call_mutex); +} + + +static void +rbug_context_texture_subdata(struct pipe_context *_context, + struct pipe_resource *_resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_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; + + mtx_lock(&rb_pipe->call_mutex); + context->texture_subdata(context, + resource, + level, + usage, + box, + data, + stride, + layer_stride); + mtx_unlock(&rb_pipe->call_mutex); +} + + +struct pipe_context * +rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) +{ + struct rbug_context *rb_pipe; + struct rbug_screen *rb_screen = rbug_screen(_screen); + + if (!rb_screen) + return NULL; + + rb_pipe = CALLOC_STRUCT(rbug_context); + if (!rb_pipe) + return NULL; + + (void) mtx_init(&rb_pipe->draw_mutex, mtx_plain); + cnd_init(&rb_pipe->draw_cond); + (void) mtx_init(&rb_pipe->call_mutex, mtx_plain); + (void) mtx_init(&rb_pipe->list_mutex, mtx_plain); + make_empty_list(&rb_pipe->shaders); + + rb_pipe->base.screen = _screen; + rb_pipe->base.priv = pipe->priv; /* expose wrapped data */ + rb_pipe->base.draw = NULL; + rb_pipe->base.stream_uploader = pipe->stream_uploader; + rb_pipe->base.const_uploader = pipe->const_uploader; + + rb_pipe->base.destroy = rbug_destroy; + rb_pipe->base.draw_vbo = rbug_draw_vbo; + 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.set_active_query_state = rbug_set_active_query_state; + 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_sampler_states = rbug_bind_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_gs_state = rbug_create_gs_state; + rb_pipe->base.bind_gs_state = rbug_bind_gs_state; + rb_pipe->base.delete_gs_state = rbug_delete_gs_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_states = rbug_set_scissor_states; + rb_pipe->base.set_viewport_states = rbug_set_viewport_states; + rb_pipe->base.set_sampler_views = rbug_set_sampler_views; + rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers; + rb_pipe->base.set_sample_mask = rbug_set_sample_mask; + rb_pipe->base.create_stream_output_target = rbug_create_stream_output_target; + rb_pipe->base.stream_output_target_destroy = rbug_stream_output_target_destroy; + rb_pipe->base.set_stream_output_targets = rbug_set_stream_output_targets; + rb_pipe->base.resource_copy_region = rbug_resource_copy_region; + rb_pipe->base.blit = rbug_blit; + rb_pipe->base.flush_resource = rbug_flush_resource; + rb_pipe->base.clear = rbug_clear; + rb_pipe->base.clear_render_target = rbug_clear_render_target; + rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil; + rb_pipe->base.flush = rbug_flush; + 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.create_surface = rbug_context_create_surface; + rb_pipe->base.surface_destroy = rbug_context_surface_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.buffer_subdata = rbug_context_buffer_subdata; + rb_pipe->base.texture_subdata = rbug_context_texture_subdata; + + rb_pipe->pipe = pipe; + + rbug_screen_add_to_list(rb_screen, contexts, rb_pipe); + + if (debug_get_bool_option("GALLIUM_RBUG_START_BLOCKED", FALSE)) { + rb_pipe->draw_blocked = RBUG_BLOCK_BEFORE; + } + + return &rb_pipe->base; +} diff --git a/src/gallium/auxiliary/driver_rbug/rbug_context.h b/src/gallium/auxiliary/driver_rbug/rbug_context.h new file mode 100644 index 00000000000..e89c6eaac01 --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_context.h @@ -0,0 +1,104 @@ +/************************************************************************** + * + * 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 */ + mtx_t call_mutex; + + /* current state */ + struct { + struct rbug_shader *shader[PIPE_SHADER_TYPES]; + + struct rbug_sampler_view *views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; + struct rbug_resource *texs[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; + unsigned num_views[PIPE_SHADER_TYPES]; + + unsigned nr_cbufs; + struct rbug_resource *cbufs[PIPE_MAX_COLOR_BUFS]; + struct rbug_resource *zsbuf; + } curr; + + /* draw locking */ + mtx_t draw_mutex; + cnd_t draw_cond; + unsigned draw_num_rules; + int draw_blocker; + int draw_blocked; + + struct { + struct rbug_shader *shader[PIPE_SHADER_TYPES]; + + struct rbug_resource *texture; + struct rbug_resource *surf; + + int blocker; + } draw_rule; + + /* list of state objects */ + mtx_t 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/auxiliary/driver_rbug/rbug_core.c b/src/gallium/auxiliary/driver_rbug/rbug_core.c new file mode 100644 index 00000000000..76394039b9b --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_core.c @@ -0,0 +1,888 @@ +/************************************************************************** + * + * 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/simple_list.h" +#include "util/u_network.h" +#include "util/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)) + +#define container_of(ptr, type, field) \ + (type*)((char*)ptr - offsetof(type, field)) + +struct rbug_rbug +{ + struct rbug_screen *rb_screen; + struct rbug_connection *con; + thrd_t thread; + boolean running; +}; + +int +rbug_thread(void *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 = container_of(ptr, 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 = container_of(ptr, 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 *rb_shader, + struct tgsi_token *tokens) +{ + void *state = NULL; + struct pipe_shader_state pss; + memset(&pss, 0, sizeof(pss)); + pss.tokens = tokens; + + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + state = pipe->create_fs_state(pipe, &pss); + break; + case RBUG_SHADER_VERTEX: + state = pipe->create_vs_state(pipe, &pss); + break; + case RBUG_SHADER_GEOM: + state = pipe->create_gs_state(pipe, &pss); + break; + default: + assert(0); + break; + } + + return state; +} + +static void +rbug_shader_bind_locked(struct pipe_context *pipe, + struct rbug_shader *rb_shader, + void *state) +{ + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + pipe->bind_fs_state(pipe, state); + break; + case RBUG_SHADER_VERTEX: + pipe->bind_vs_state(pipe, state); + break; + case RBUG_SHADER_GEOM: + pipe->bind_gs_state(pipe, state); + break; + default: + assert(0); + break; + } +} + +static void +rbug_shader_delete_locked(struct pipe_context *pipe, + struct rbug_shader *rb_shader, + void *state) +{ + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + pipe->delete_fs_state(pipe, state); + break; + case RBUG_SHADER_VERTEX: + pipe->delete_vs_state(pipe, state); + break; + case RBUG_SHADER_GEOM: + pipe->delete_gs_state(pipe, state); + break; + default: + assert(0); + break; + } +} + +/************************************************ + * 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; + + mtx_lock(&rb_screen->list_mutex); + texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t)); + foreach(ptr, &rb_screen->resources) { + tr_tex = container_of(ptr, struct rbug_resource, list); + texs[i++] = VOID2U64(tr_tex); + } + mtx_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; + uint16_t num_layers; + + mtx_lock(&rb_screen->list_mutex); + foreach(ptr, &rb_screen->resources) { + tr_tex = container_of(ptr, struct rbug_resource, list); + if (gpti->texture == VOID2U64(tr_tex)) + break; + tr_tex = NULL; + } + + if (!tr_tex) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + t = tr_tex->resource; + num_layers = util_num_layers(t, 0); + + rbug_send_texture_info_reply(tr_rbug->con, serial, + t->target, t->format, + &t->width0, 1, + &t->height0, 1, + &num_layers, 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); + + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + foreach(ptr, &rb_screen->resources) { + tr_tex = container_of(ptr, struct rbug_resource, list); + if (gptr->texture == VOID2U64(tr_tex)) + break; + tr_tex = NULL; + } + + if (!tr_tex) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + tex = tr_tex->resource; + map = pipe_transfer_map(context, tex, + gptr->level, gptr->face + gptr->zslice, + PIPE_TRANSFER_READ, + gptr->x, gptr->y, gptr->w, gptr->h, &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); + + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t)); + foreach(ptr, &rb_screen->contexts) { + rb_context = container_of(ptr, struct rbug_context, list); + ctxs[i++] = VOID2U64(rb_context); + } + mtx_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_SHADER_SAMPLER_VIEWS]; + unsigned i; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, info->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + mtx_lock(&rb_context->draw_mutex); + mtx_lock(&rb_context->call_mutex); + + for (i = 0; i < rb_context->curr.nr_cbufs; i++) + cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]); + + /* XXX what about vertex/geometry shader texture views? */ + for (i = 0; i < rb_context->curr.num_views[PIPE_SHADER_FRAGMENT]; i++) + texs[i] = VOID2U64(rb_context->curr.texs[PIPE_SHADER_FRAGMENT][i]); + + rbug_send_context_info_reply(tr_rbug->con, serial, + VOID2U64(rb_context->curr.shader[PIPE_SHADER_VERTEX]), VOID2U64(rb_context->curr.shader[PIPE_SHADER_FRAGMENT]), + texs, rb_context->curr.num_views[PIPE_SHADER_FRAGMENT], + cbufs, rb_context->curr.nr_cbufs, + VOID2U64(rb_context->curr.zsbuf), + rb_context->draw_blocker, rb_context->draw_blocked, NULL); + + mtx_unlock(&rb_context->call_mutex); + mtx_unlock(&rb_context->draw_mutex); + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, block->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_lock(&rb_context->draw_mutex); + rb_context->draw_blocker |= block->block; + mtx_unlock(&rb_context->draw_mutex); + + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, step->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_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; + } + mtx_unlock(&rb_context->draw_mutex); + + cnd_broadcast(&rb_context->draw_cond); + + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, unblock->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_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; + mtx_unlock(&rb_context->draw_mutex); + + cnd_broadcast(&rb_context->draw_cond); + + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, rule->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_lock(&rb_context->draw_mutex); + rb_context->draw_rule.shader[PIPE_SHADER_VERTEX] = U642VOID(rule->vertex); + rb_context->draw_rule.shader[PIPE_SHADER_FRAGMENT] = U642VOID(rule->fragment); + rb_context->draw_rule.texture = 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; + mtx_unlock(&rb_context->draw_mutex); + + cnd_broadcast(&rb_context->draw_cond); + + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, flush->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + mtx_lock(&rb_context->call_mutex); + + rb_context->pipe->flush(rb_context->pipe, NULL, 0); + + mtx_unlock(&rb_context->call_mutex); + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, list->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_lock(&rb_context->list_mutex); + shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t)); + foreach(ptr, &rb_context->shaders) { + tr_shdr = container_of(ptr, struct rbug_shader, list); + shdrs[i++] = VOID2U64(tr_shdr); + } + + mtx_unlock(&rb_context->list_mutex); + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, info->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_lock(&rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, info->shader); + + if (!tr_shdr) { + mtx_unlock(&rb_context->list_mutex); + mtx_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); + + mtx_unlock(&rb_context->list_mutex); + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, dis->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_lock(&rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, dis->shader); + + if (!tr_shdr) { + mtx_unlock(&rb_context->list_mutex); + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + tr_shdr->disabled = dis->disable; + + mtx_unlock(&rb_context->list_mutex); + mtx_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; + + mtx_lock(&rb_screen->list_mutex); + rb_context = rbug_get_context_locked(rb_screen, rep->context); + + if (!rb_context) { + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + mtx_lock(&rb_context->list_mutex); + + tr_shdr = rbug_get_shader_locked(rb_context, rep->shader); + + if (!tr_shdr) { + mtx_unlock(&rb_context->list_mutex); + mtx_unlock(&rb_screen->list_mutex); + return -ESRCH; + } + + /* protect the pipe context */ + mtx_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.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == 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.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == tr_shdr) + rbug_shader_bind_locked(pipe, tr_shdr, state); + + /* save state */ + tr_shdr->replaced_shader = state; + +out: + mtx_unlock(&rb_context->call_mutex); + mtx_unlock(&rb_context->list_mutex); + mtx_unlock(&rb_screen->list_mutex); + + return 0; + +err: + FREE(tr_shdr->replaced_tokens); + tr_shdr->replaced_shader = NULL; + tr_shdr->replaced_tokens = NULL; + + mtx_unlock(&rb_context->call_mutex); + mtx_unlock(&rb_context->list_mutex); + mtx_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; +} + +int +rbug_thread(void *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 0; + } + + 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 0; +} + +/********************************************************** + * + */ + +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 = u_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; + thrd_join(tr_rbug->thread, NULL); + + 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/auxiliary/driver_rbug/rbug_objects.c b/src/gallium/auxiliary/driver_rbug/rbug_objects.c new file mode 100644 index 00000000000..2aa4e123f87 --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_objects.c @@ -0,0 +1,250 @@ +/************************************************************************** + * + * 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); +} diff --git a/src/gallium/auxiliary/driver_rbug/rbug_objects.h b/src/gallium/auxiliary/driver_rbug/rbug_objects.h new file mode 100644 index 00000000000..02973e07996 --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_objects.h @@ -0,0 +1,228 @@ +/************************************************************************** + * + * 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; +}; + + +enum rbug_shader_type +{ + RBUG_SHADER_GEOM, + RBUG_SHADER_VERTEX, + RBUG_SHADER_FRAGMENT, +}; + +struct rbug_shader +{ + struct rbug_list list; + + void *shader; + void *tokens; + void *replaced_shader; + void *replaced_tokens; + + enum rbug_shader_type type; + 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_context *rb_context, + struct rbug_resource *rb_resource, + struct pipe_surface *surface); + +void +rbug_surface_destroy(struct rbug_context *rb_context, + 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); + +void * +rbug_shader_create(struct rbug_context *rb_context, + const struct pipe_shader_state *state, + void *result, enum rbug_shader_type type); + +void +rbug_shader_destroy(struct rbug_context *rb_context, + struct rbug_shader *rb_shader); + + +#endif /* RBUG_OBJECTS_H */ diff --git a/src/gallium/auxiliary/driver_rbug/rbug_public.h b/src/gallium/auxiliary/driver_rbug/rbug_public.h new file mode 100644 index 00000000000..83f9c94e31f --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_public.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * 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 + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +rbug_screen_create(struct pipe_screen *screen); + +boolean +rbug_enabled(void); + +#ifdef __cplusplus +} +#endif + +#endif /* RBUG_PUBLIC_H */ diff --git a/src/gallium/auxiliary/driver_rbug/rbug_screen.c b/src/gallium/auxiliary/driver_rbug/rbug_screen.c new file mode 100644 index 00000000000..2477edbadf0 --- /dev/null +++ b/src/gallium/auxiliary/driver_rbug/rbug_screen.c @@ -0,0 +1,343 @@ +/************************************************************************** + * + * 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/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 const char * +rbug_screen_get_device_vendor(struct pipe_screen *_screen) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_device_vendor(screen); +} + +static struct disk_cache * +rbug_screen_get_disk_shader_cache(struct pipe_screen *_screen) +{ + struct pipe_screen *screen = rbug_screen(_screen)->screen; + + return screen->get_disk_shader_cache(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 int +rbug_screen_get_shader_param(struct pipe_screen *_screen, + enum pipe_shader_type shader, + enum pipe_shader_cap param) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->get_shader_param(screen, shader, + param); +} + +static float +rbug_screen_get_paramf(struct pipe_screen *_screen, + enum pipe_capf 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 sample_count, + unsigned tex_usage) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->is_format_supported(screen, + format, + target, + sample_count, + tex_usage); +} + +static struct pipe_context * +rbug_screen_context_create(struct pipe_screen *_screen, + void *priv, unsigned flags) +{ + 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, flags); + 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, + unsigned usage) +{ + 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, usage); + + result = rbug_resource_create(rbug_screen(_screen), result); + + return result; +} + +static bool +rbug_screen_check_resource_capability(struct pipe_screen *_screen, + struct pipe_resource *_resource, + unsigned bind) +{ + 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->check_resource_capability(screen, resource, bind); +} + +static boolean +rbug_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_context *_pipe, + struct pipe_resource *_resource, + struct winsys_handle *handle, + unsigned usage) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_context *rb_pipe = rbug_context(_pipe); + 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, rb_pipe ? rb_pipe->pipe : NULL, + resource, handle, usage); +} + +static void +rbug_screen_resource_changed(struct pipe_screen *_screen, + struct pipe_resource *_resource) +{ + 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; + + screen->resource_changed(screen, resource); +} + +static void +rbug_screen_resource_destroy(struct pipe_screen *screen, + struct pipe_resource *_resource) +{ + rbug_resource_destroy(rbug_resource(_resource)); +} + +static void +rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_resource *_resource, + unsigned level, unsigned layer, + void *context_private, struct pipe_box *sub_box) +{ + 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; + + screen->flush_frontbuffer(screen, + resource, + level, layer, + context_private, sub_box); +} + +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 boolean +rbug_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_context *_ctx, + struct pipe_fence_handle *fence, + uint64_t timeout) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_context *ctx = _ctx ? rbug_context(_ctx)->pipe : NULL; + + return screen->fence_finish(screen, ctx, fence, timeout); +} + +boolean +rbug_enabled() +{ + return debug_get_option_rbug(); +} + +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; + + (void) mtx_init(&rb_screen->list_mutex, mtx_plain); + make_empty_list(&rb_screen->contexts); + make_empty_list(&rb_screen->resources); + make_empty_list(&rb_screen->surfaces); + make_empty_list(&rb_screen->transfers); + +#define SCR_INIT(_member) \ + rb_screen->base._member = screen->_member ? rbug_screen_##_member : 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; + SCR_INIT(get_disk_shader_cache); + rb_screen->base.get_device_vendor = rbug_screen_get_device_vendor; + rb_screen->base.get_param = rbug_screen_get_param; + rb_screen->base.get_shader_param = rbug_screen_get_shader_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; + SCR_INIT(check_resource_capability); + rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle; + SCR_INIT(resource_changed); + rb_screen->base.resource_destroy = rbug_screen_resource_destroy; + rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer; + rb_screen->base.fence_reference = rbug_screen_fence_reference; + rb_screen->base.fence_finish = rbug_screen_fence_finish; + + rb_screen->screen = screen; + + rb_screen->private_context = screen->context_create(screen, NULL, 0); + 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/auxiliary/driver_rbug/rbug_screen.h b/src/gallium/auxiliary/driver_rbug/rbug_screen.h new file mode 100644 index 00000000000..1972005753b --- /dev/null +++ b/src/gallium/auxiliary/driver_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; + + mtx_t 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 { \ + mtx_lock(&scr->list_mutex); \ + insert_at_head(&scr->name, &obj->list); \ + scr->num_##name++; \ + mtx_unlock(&scr->list_mutex); \ + } while (0) + +#define rbug_screen_remove_from_list(scr, name, obj) \ + do { \ + mtx_lock(&scr->list_mutex); \ + remove_from_list(&obj->list); \ + scr->num_##name--; \ + mtx_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 */ diff --git a/src/gallium/auxiliary/driver_trace/README b/src/gallium/auxiliary/driver_trace/README new file mode 100644 index 00000000000..fbad26c4498 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/README @@ -0,0 +1,55 @@ + TRACE PIPE DRIVER + + += About = + +This directory contains a Gallium3D trace debugger pipe driver. +It can traces all incoming calls. + + += Usage = + +== Tracing == + +For tracing then do + + GALLIUM_TRACE=tri.trace trivial/tri + +which should create a tri.trace file, which is an XML file. You can view copying +trace.xsl to the same directory, and opening with a XSLT capable browser such as +Firefox or Internet Explorer. + +For long traces you can use the + + src/gallium/tools/trace/dump.py tri.trace | less -R + + +== Remote debugging == + +For remote debugging see: + + src/gallium/auxiliary/driver_rbug/README + + += Integrating = + +You can integrate the trace pipe driver either inside the state tracker or the +target. The procedure on both cases is the same. Let's assume you have a +pipe_screen obtained by the usual means (variable and function names are just +for illustration purposes): + + real_screen = real_screen_create(...); + +The trace screen is then created by doing + + trace_screen = trace_screen_create(real_screen); + +You can then simply use trace_screen instead of real_screen. + +You can create as many contexts you wish from trace_screen::context_create they +are automatically wrapped by trace_screen. + + +-- +Jose Fonseca +Jakob Bornecrantz diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c new file mode 100644 index 00000000000..6d918d42a38 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -0,0 +1,1948 @@ +/************************************************************************** + * + * Copyright 2008 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 "pipe/p_format.h" +#include "pipe/p_screen.h" + +#include "tr_dump.h" +#include "tr_dump_defines.h" +#include "tr_dump_state.h" +#include "tr_public.h" +#include "tr_screen.h" +#include "tr_texture.h" +#include "tr_context.h" + + +struct trace_query +{ + unsigned type; + + struct pipe_query *query; +}; + + +static inline struct trace_query * +trace_query(struct pipe_query *query) +{ + return (struct trace_query *)query; +} + + +static inline struct pipe_query * +trace_query_unwrap(struct pipe_query *query) +{ + if (query) { + return trace_query(query)->query; + } else { + return NULL; + } +} + + +static inline struct pipe_surface * +trace_surface_unwrap(struct trace_context *tr_ctx, + struct pipe_surface *surface) +{ + struct trace_surface *tr_surf; + + if (!surface) + return NULL; + + assert(surface->texture); + if (!surface->texture) + return surface; + + tr_surf = trace_surface(surface); + + assert(tr_surf->surface); + return tr_surf->surface; +} + + +static void +trace_context_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "draw_vbo"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(draw_info, info); + + trace_dump_trace_flush(); + + pipe->draw_vbo(pipe, info); + + trace_dump_call_end(); +} + + +static struct pipe_query * +trace_context_create_query(struct pipe_context *_pipe, + unsigned query_type, + unsigned index) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_query *query; + + trace_dump_call_begin("pipe_context", "create_query"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(query_type, query_type); + trace_dump_arg(int, index); + + query = pipe->create_query(pipe, query_type, index); + + trace_dump_ret(ptr, query); + + trace_dump_call_end(); + + /* Wrap query object. */ + if (query) { + struct trace_query *tr_query = CALLOC_STRUCT(trace_query); + if (tr_query) { + tr_query->type = query_type; + tr_query->query = query; + query = (struct pipe_query *)tr_query; + } else { + pipe->destroy_query(pipe, query); + query = NULL; + } + } + + return query; +} + + +static void +trace_context_destroy_query(struct pipe_context *_pipe, + struct pipe_query *_query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct trace_query *tr_query = trace_query(_query); + struct pipe_query *query = tr_query->query; + + FREE(tr_query); + + trace_dump_call_begin("pipe_context", "destroy_query"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); + + pipe->destroy_query(pipe, query); + + trace_dump_call_end(); +} + + +static boolean +trace_context_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + boolean ret; + + query = trace_query_unwrap(query); + + trace_dump_call_begin("pipe_context", "begin_query"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); + + ret = pipe->begin_query(pipe, query); + + trace_dump_call_end(); + return ret; +} + + +static bool +trace_context_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + bool ret; + + query = trace_query_unwrap(query); + + trace_dump_call_begin("pipe_context", "end_query"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); + + ret = pipe->end_query(pipe, query); + + trace_dump_call_end(); + return ret; +} + + +static boolean +trace_context_get_query_result(struct pipe_context *_pipe, + struct pipe_query *_query, + boolean wait, + union pipe_query_result *result) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct trace_query *tr_query = trace_query(_query); + struct pipe_query *query = tr_query->query; + boolean ret; + + trace_dump_call_begin("pipe_context", "get_query_result"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); + + ret = pipe->get_query_result(pipe, query, wait, result); + + trace_dump_arg_begin("result"); + if (ret) { + trace_dump_query_result(tr_query->type, result); + } else { + trace_dump_null(); + } + trace_dump_arg_end(); + + trace_dump_ret(bool, ret); + + trace_dump_call_end(); + + return ret; +} + + +static void +trace_context_set_active_query_state(struct pipe_context *_pipe, + boolean enable) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_active_query_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(bool, enable); + + pipe->set_active_query_state(pipe, enable); + + trace_dump_call_end(); +} + + +static void * +trace_context_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin("pipe_context", "create_blend_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(blend_state, state); + + result = pipe->create_blend_state(pipe, state); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static void +trace_context_bind_blend_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "bind_blend_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->bind_blend_state(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_delete_blend_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_blend_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->delete_blend_state(pipe, state); + + trace_dump_call_end(); +} + + +static void * +trace_context_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin("pipe_context", "create_sampler_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(sampler_state, state); + + result = pipe->create_sampler_state(pipe, state); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static void +trace_context_bind_sampler_states(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, + unsigned num_states, + void **states) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + /* remove this when we have pipe->bind_sampler_states(..., start, ...) */ + assert(start == 0); + + trace_dump_call_begin("pipe_context", "bind_sampler_states"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, shader); + trace_dump_arg(uint, start); + trace_dump_arg(uint, num_states); + trace_dump_arg_array(ptr, states, num_states); + + pipe->bind_sampler_states(pipe, shader, start, num_states, states); + + trace_dump_call_end(); +} + + +static void +trace_context_delete_sampler_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_sampler_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->delete_sampler_state(pipe, state); + + trace_dump_call_end(); +} + + +static void * +trace_context_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin("pipe_context", "create_rasterizer_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(rasterizer_state, state); + + result = pipe->create_rasterizer_state(pipe, state); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static void +trace_context_bind_rasterizer_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "bind_rasterizer_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->bind_rasterizer_state(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_delete_rasterizer_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_rasterizer_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->delete_rasterizer_state(pipe, state); + + trace_dump_call_end(); +} + + +static void * +trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state"); + + result = pipe->create_depth_stencil_alpha_state(pipe, state); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(depth_stencil_alpha_state, state); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static void +trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "bind_depth_stencil_alpha_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->bind_depth_stencil_alpha_state(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_depth_stencil_alpha_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->delete_depth_stencil_alpha_state(pipe, state); + + trace_dump_call_end(); +} + + +#define TRACE_SHADER_STATE(shader_type) \ + static void * \ + trace_context_create_##shader_type##_state(struct pipe_context *_pipe, \ + const struct pipe_shader_state *state) \ + { \ + struct trace_context *tr_ctx = trace_context(_pipe); \ + struct pipe_context *pipe = tr_ctx->pipe; \ + void * result; \ + trace_dump_call_begin("pipe_context", "create_" #shader_type "_state"); \ + trace_dump_arg(ptr, pipe); \ + trace_dump_arg(shader_state, state); \ + result = pipe->create_##shader_type##_state(pipe, state); \ + trace_dump_ret(ptr, result); \ + trace_dump_call_end(); \ + return result; \ + } \ + \ + static void \ + trace_context_bind_##shader_type##_state(struct pipe_context *_pipe, \ + void *state) \ + { \ + struct trace_context *tr_ctx = trace_context(_pipe); \ + struct pipe_context *pipe = tr_ctx->pipe; \ + trace_dump_call_begin("pipe_context", "bind_" #shader_type "_state"); \ + trace_dump_arg(ptr, pipe); \ + trace_dump_arg(ptr, state); \ + pipe->bind_##shader_type##_state(pipe, state); \ + trace_dump_call_end(); \ + } \ + \ + static void \ + trace_context_delete_##shader_type##_state(struct pipe_context *_pipe, \ + void *state) \ + { \ + struct trace_context *tr_ctx = trace_context(_pipe); \ + struct pipe_context *pipe = tr_ctx->pipe; \ + trace_dump_call_begin("pipe_context", "delete_" #shader_type "_state"); \ + trace_dump_arg(ptr, pipe); \ + trace_dump_arg(ptr, state); \ + pipe->delete_##shader_type##_state(pipe, state); \ + trace_dump_call_end(); \ + } + +TRACE_SHADER_STATE(fs) +TRACE_SHADER_STATE(vs) +TRACE_SHADER_STATE(gs) +TRACE_SHADER_STATE(tcs) +TRACE_SHADER_STATE(tes) + +#undef TRACE_SHADER_STATE + + +static inline void * +trace_context_create_compute_state(struct pipe_context *_pipe, + const struct pipe_compute_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin("pipe_context", "create_compute_state"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(compute_state, state); + result = pipe->create_compute_state(pipe, state); + trace_dump_ret(ptr, result); + trace_dump_call_end(); + return result; +} + +static inline void +trace_context_bind_compute_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "bind_compute_state"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + pipe->bind_compute_state(pipe, state); + trace_dump_call_end(); +} + +static inline void +trace_context_delete_compute_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_compute_state"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + pipe->delete_compute_state(pipe, state); + trace_dump_call_end(); +} + +static void * +trace_context_create_vertex_elements_state(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin("pipe_context", "create_vertex_elements_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_elements); + + trace_dump_arg_begin("elements"); + trace_dump_struct_array(vertex_element, elements, num_elements); + trace_dump_arg_end(); + + result = pipe->create_vertex_elements_state(pipe, num_elements, elements); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static void +trace_context_bind_vertex_elements_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "bind_vertex_elements_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->bind_vertex_elements_state(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_delete_vertex_elements_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_vertex_elements_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); + + pipe->delete_vertex_elements_state(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_blend_color"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(blend_color, state); + + pipe->set_blend_color(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_set_stencil_ref(struct pipe_context *_pipe, + const struct pipe_stencil_ref *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_stencil_ref"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(stencil_ref, state); + + pipe->set_stencil_ref(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_clip_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(clip_state, state); + + pipe->set_clip_state(pipe, state); + + trace_dump_call_end(); +} + +static void +trace_context_set_sample_mask(struct pipe_context *_pipe, + unsigned sample_mask) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_sample_mask"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, sample_mask); + + pipe->set_sample_mask(pipe, sample_mask); + + trace_dump_call_end(); +} + +static void +trace_context_set_constant_buffer(struct pipe_context *_pipe, + enum pipe_shader_type shader, uint index, + const struct pipe_constant_buffer *constant_buffer) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_constant_buffer"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, shader); + trace_dump_arg(uint, index); + trace_dump_arg(constant_buffer, constant_buffer); + + pipe->set_constant_buffer(pipe, shader, index, constant_buffer); + + trace_dump_call_end(); +} + + +static void +trace_context_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_framebuffer_state unwrapped_state; + unsigned i; + + + /* Unwrap the input state */ + memcpy(&unwrapped_state, state, sizeof(unwrapped_state)); + for (i = 0; i < state->nr_cbufs; ++i) + unwrapped_state.cbufs[i] = trace_surface_unwrap(tr_ctx, state->cbufs[i]); + for (i = state->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; ++i) + unwrapped_state.cbufs[i] = NULL; + unwrapped_state.zsbuf = trace_surface_unwrap(tr_ctx, state->zsbuf); + state = &unwrapped_state; + + trace_dump_call_begin("pipe_context", "set_framebuffer_state"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(framebuffer_state, state); + + pipe->set_framebuffer_state(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_polygon_stipple"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(poly_stipple, state); + + pipe->set_polygon_stipple(pipe, state); + + trace_dump_call_end(); +} + + +static void +trace_context_set_scissor_states(struct pipe_context *_pipe, + unsigned start_slot, + unsigned num_scissors, + const struct pipe_scissor_state *states) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_scissor_states"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, start_slot); + trace_dump_arg(uint, num_scissors); + trace_dump_arg(scissor_state, states); + + pipe->set_scissor_states(pipe, start_slot, num_scissors, states); + + trace_dump_call_end(); +} + + +static void +trace_context_set_viewport_states(struct pipe_context *_pipe, + unsigned start_slot, + unsigned num_viewports, + const struct pipe_viewport_state *states) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_viewport_states"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, start_slot); + trace_dump_arg(uint, num_viewports); + trace_dump_arg(viewport_state, states); + + pipe->set_viewport_states(pipe, start_slot, num_viewports, states); + + trace_dump_call_end(); +} + + +static struct pipe_sampler_view * +trace_context_create_sampler_view(struct pipe_context *_pipe, + struct pipe_resource *resource, + const struct pipe_sampler_view *templ) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_sampler_view *result; + struct trace_sampler_view *tr_view; + + trace_dump_call_begin("pipe_context", "create_sampler_view"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, resource); + + trace_dump_arg_begin("templ"); + trace_dump_sampler_view_template(templ, resource->target); + trace_dump_arg_end(); + + result = pipe->create_sampler_view(pipe, resource, templ); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + /* + * Wrap pipe_sampler_view + */ + tr_view = CALLOC_STRUCT(trace_sampler_view); + tr_view->base = *templ; + tr_view->base.reference.count = 1; + tr_view->base.texture = NULL; + pipe_resource_reference(&tr_view->base.texture, resource); + tr_view->base.context = _pipe; + tr_view->sampler_view = result; + result = &tr_view->base; + + return result; +} + + +static void +trace_context_sampler_view_destroy(struct pipe_context *_pipe, + struct pipe_sampler_view *_view) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_sampler_view *tr_view = trace_sampler_view(_view); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_sampler_view *view = tr_view->sampler_view; + + assert(_view->context == _pipe); + + trace_dump_call_begin("pipe_context", "sampler_view_destroy"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, view); + + pipe_sampler_view_reference(&tr_view->sampler_view, NULL); + + trace_dump_call_end(); + + pipe_resource_reference(&_view->texture, NULL); + FREE(_view); +} + +/******************************************************************** + * surface + */ + + +static struct pipe_surface * +trace_context_create_surface(struct pipe_context *_pipe, + struct pipe_resource *resource, + const struct pipe_surface *surf_tmpl) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_surface *result = NULL; + + trace_dump_call_begin("pipe_context", "create_surface"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, resource); + + trace_dump_arg_begin("surf_tmpl"); + trace_dump_surface_template(surf_tmpl, resource->target); + trace_dump_arg_end(); + + + result = pipe->create_surface(pipe, resource, surf_tmpl); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + result = trace_surf_create(tr_ctx, resource, result); + + return result; +} + + +static void +trace_context_surface_destroy(struct pipe_context *_pipe, + struct pipe_surface *_surface) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct trace_surface *tr_surf = trace_surface(_surface); + struct pipe_surface *surface = tr_surf->surface; + + trace_dump_call_begin("pipe_context", "surface_destroy"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, surface); + + trace_dump_call_end(); + + trace_surf_destroy(tr_surf); +} + + +static void +trace_context_set_sampler_views(struct pipe_context *_pipe, + enum pipe_shader_type shader, + unsigned start, + unsigned num, + struct pipe_sampler_view **views) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_sampler_view *tr_view; + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + unsigned i; + + /* remove this when we have pipe->set_sampler_views(..., start, ...) */ + assert(start == 0); + + for (i = 0; i < num; ++i) { + tr_view = trace_sampler_view(views[i]); + unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL; + } + views = unwrapped_views; + + trace_dump_call_begin("pipe_context", "set_sampler_views"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, shader); + trace_dump_arg(uint, start); + trace_dump_arg(uint, num); + trace_dump_arg_array(ptr, views, num); + + pipe->set_sampler_views(pipe, shader, start, num, views); + + trace_dump_call_end(); +} + + +static void +trace_context_set_vertex_buffers(struct pipe_context *_pipe, + unsigned start_slot, unsigned num_buffers, + const struct pipe_vertex_buffer *buffers) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_vertex_buffers"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, start_slot); + trace_dump_arg(uint, num_buffers); + + trace_dump_arg_begin("buffers"); + trace_dump_struct_array(vertex_buffer, buffers, num_buffers); + trace_dump_arg_end(); + + pipe->set_vertex_buffers(pipe, start_slot, num_buffers, buffers); + + trace_dump_call_end(); +} + + +static struct pipe_stream_output_target * +trace_context_create_stream_output_target(struct pipe_context *_pipe, + struct pipe_resource *res, + unsigned buffer_offset, + unsigned buffer_size) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_stream_output_target *result; + + trace_dump_call_begin("pipe_context", "create_stream_output_target"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, res); + trace_dump_arg(uint, buffer_offset); + trace_dump_arg(uint, buffer_size); + + result = pipe->create_stream_output_target(pipe, + res, buffer_offset, buffer_size); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static void +trace_context_stream_output_target_destroy( + struct pipe_context *_pipe, + struct pipe_stream_output_target *target) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "stream_output_target_destroy"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, target); + + pipe->stream_output_target_destroy(pipe, target); + + trace_dump_call_end(); +} + + +static void +trace_context_set_stream_output_targets(struct pipe_context *_pipe, + unsigned num_targets, + struct pipe_stream_output_target **tgs, + const unsigned *offsets) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_stream_output_targets"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_targets); + trace_dump_arg_array(ptr, tgs, num_targets); + trace_dump_arg_array(uint, offsets, num_targets); + + pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets); + + trace_dump_call_end(); +} + + +static void +trace_context_resource_copy_region(struct pipe_context *_pipe, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + unsigned src_level, + const struct pipe_box *src_box) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "resource_copy_region"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, dst); + trace_dump_arg(uint, dst_level); + trace_dump_arg(uint, dstx); + trace_dump_arg(uint, dsty); + trace_dump_arg(uint, dstz); + trace_dump_arg(ptr, src); + trace_dump_arg(uint, src_level); + trace_dump_arg(box, src_box); + + pipe->resource_copy_region(pipe, + dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); + + trace_dump_call_end(); +} + + +static void +trace_context_blit(struct pipe_context *_pipe, + const struct pipe_blit_info *_info) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_blit_info info = *_info; + + trace_dump_call_begin("pipe_context", "blit"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(blit_info, _info); + + pipe->blit(pipe, &info); + + trace_dump_call_end(); +} + + +static void +trace_context_flush_resource(struct pipe_context *_pipe, + struct pipe_resource *resource) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "flush_resource"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, resource); + + pipe->flush_resource(pipe, resource); + + trace_dump_call_end(); +} + + +static void +trace_context_clear(struct pipe_context *_pipe, + unsigned buffers, + const union pipe_color_union *color, + double depth, + unsigned stencil) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "clear"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, buffers); + trace_dump_arg_begin("color"); + if (color) + trace_dump_array(float, color->f, 4); + else + trace_dump_null(); + trace_dump_arg_end(); + trace_dump_arg(float, depth); + trace_dump_arg(uint, stencil); + + pipe->clear(pipe, buffers, color, depth, stencil); + + trace_dump_call_end(); +} + + +static void +trace_context_clear_render_target(struct pipe_context *_pipe, + struct pipe_surface *dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + dst = trace_surface_unwrap(tr_ctx, dst); + + trace_dump_call_begin("pipe_context", "clear_render_target"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, dst); + trace_dump_arg_array(float, color->f, 4); + trace_dump_arg(uint, dstx); + trace_dump_arg(uint, dsty); + trace_dump_arg(uint, width); + trace_dump_arg(uint, height); + trace_dump_arg(bool, render_condition_enabled); + + pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height, + render_condition_enabled); + + trace_dump_call_end(); +} + +static void +trace_context_clear_depth_stencil(struct pipe_context *_pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + dst = trace_surface_unwrap(tr_ctx, dst); + + trace_dump_call_begin("pipe_context", "clear_depth_stencil"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, dst); + trace_dump_arg(uint, clear_flags); + trace_dump_arg(float, depth); + trace_dump_arg(uint, stencil); + trace_dump_arg(uint, dstx); + trace_dump_arg(uint, dsty); + trace_dump_arg(uint, width); + trace_dump_arg(uint, height); + trace_dump_arg(bool, render_condition_enabled); + + pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil, + dstx, dsty, width, height, + render_condition_enabled); + + trace_dump_call_end(); +} + +static inline void +trace_context_clear_texture(struct pipe_context *_pipe, + struct pipe_resource *res, + unsigned level, + const struct pipe_box *box, + const void *data) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + + trace_dump_call_begin("pipe_context", "clear_texture"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, res); + trace_dump_arg(uint, level); + trace_dump_arg_begin("box"); + trace_dump_box(box); + trace_dump_arg_end(); + trace_dump_arg(ptr, data); + + pipe->clear_texture(pipe, res, level, box, data); + + trace_dump_call_end(); +} + +static void +trace_context_flush(struct pipe_context *_pipe, + struct pipe_fence_handle **fence, + unsigned flags) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "flush"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, flags); + + pipe->flush(pipe, fence, flags); + + if (fence) + trace_dump_ret(ptr, *fence); + + trace_dump_call_end(); +} + + +static inline boolean +trace_context_generate_mipmap(struct pipe_context *_pipe, + struct pipe_resource *res, + enum pipe_format format, + unsigned base_level, + unsigned last_level, + unsigned first_layer, + unsigned last_layer) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + boolean ret; + + trace_dump_call_begin("pipe_context", "generate_mipmap"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, res); + + trace_dump_arg(format, format); + trace_dump_arg(uint, base_level); + trace_dump_arg(uint, last_level); + trace_dump_arg(uint, first_layer); + trace_dump_arg(uint, last_layer); + + ret = pipe->generate_mipmap(pipe, res, format, base_level, last_level, + first_layer, last_layer); + + trace_dump_ret(bool, ret); + trace_dump_call_end(); + + return ret; +} + + +static void +trace_context_destroy(struct pipe_context *_pipe) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "destroy"); + trace_dump_arg(ptr, pipe); + trace_dump_call_end(); + + pipe->destroy(pipe); + + FREE(tr_ctx); +} + + +/******************************************************************** + * transfer + */ + + +static void * +trace_context_transfer_map(struct pipe_context *_context, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + struct pipe_transfer **transfer) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + struct pipe_transfer *result = NULL; + void *map; + + /* + * Map and transfers can't be serialized so we convert all write transfers + * to texture/buffer_subdata and ignore read transfers. + */ + + map = context->transfer_map(context, resource, level, usage, box, &result); + if (!map) + return NULL; + + *transfer = trace_transfer_create(tr_context, resource, result); + + if (map) { + if (usage & PIPE_TRANSFER_WRITE) { + trace_transfer(*transfer)->map = map; + } + } + + return *transfer ? map : NULL; +} + +static void +trace_context_transfer_flush_region( struct pipe_context *_context, + struct pipe_transfer *_transfer, + const struct pipe_box *box) +{ + struct trace_context *tr_context = trace_context(_context); + struct trace_transfer *tr_transfer = trace_transfer(_transfer); + struct pipe_context *context = tr_context->pipe; + struct pipe_transfer *transfer = tr_transfer->transfer; + + context->transfer_flush_region(context, transfer, box); +} + +static void +trace_context_transfer_unmap(struct pipe_context *_context, + struct pipe_transfer *_transfer) +{ + struct trace_context *tr_ctx = trace_context(_context); + struct trace_transfer *tr_trans = trace_transfer(_transfer); + struct pipe_context *context = tr_ctx->pipe; + struct pipe_transfer *transfer = tr_trans->transfer; + + if (tr_trans->map) { + /* + * Fake a texture/buffer_subdata + */ + + struct pipe_resource *resource = transfer->resource; + unsigned level = transfer->level; + unsigned usage = transfer->usage; + const struct pipe_box *box = &transfer->box; + unsigned stride = transfer->stride; + unsigned layer_stride = transfer->layer_stride; + + if (resource->target == PIPE_BUFFER) + trace_dump_call_begin("pipe_context", "buffer_subdata"); + else + trace_dump_call_begin("pipe_context", "texture_subdata"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, resource); + trace_dump_arg(uint, level); + trace_dump_arg(uint, usage); + trace_dump_arg(box, box); + + trace_dump_arg_begin("data"); + trace_dump_box_bytes(tr_trans->map, + resource, + box, + stride, + layer_stride); + trace_dump_arg_end(); + + trace_dump_arg(uint, stride); + trace_dump_arg(uint, layer_stride); + + trace_dump_call_end(); + + tr_trans->map = NULL; + } + + context->transfer_unmap(context, transfer); + trace_transfer_destroy(tr_ctx, tr_trans); +} + + +static void +trace_context_buffer_subdata(struct pipe_context *_context, + struct pipe_resource *resource, + unsigned usage, unsigned offset, + unsigned size, const void *data) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + struct pipe_box box; + + trace_dump_call_begin("pipe_context", "buffer_subdata"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, resource); + trace_dump_arg(uint, usage); + trace_dump_arg(uint, offset); + trace_dump_arg(uint, size); + + trace_dump_arg_begin("data"); + u_box_1d(offset, size, &box); + trace_dump_box_bytes(data, resource, &box, 0, 0); + trace_dump_arg_end(); + + trace_dump_call_end(); + + context->buffer_subdata(context, resource, usage, offset, size, data); +} + + +static void +trace_context_texture_subdata(struct pipe_context *_context, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "texture_subdata"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, resource); + trace_dump_arg(uint, level); + trace_dump_arg(uint, usage); + trace_dump_arg(box, box); + + trace_dump_arg_begin("data"); + trace_dump_box_bytes(data, + resource, + box, + stride, + layer_stride); + trace_dump_arg_end(); + + trace_dump_arg(uint, stride); + trace_dump_arg(uint, layer_stride); + + trace_dump_call_end(); + + context->texture_subdata(context, resource, level, usage, box, + data, stride, layer_stride); +} + +static void +trace_context_invalidate_resource(struct pipe_context *_context, + struct pipe_resource *resource) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "invalidate_resource"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, resource); + + trace_dump_call_end(); + + context->invalidate_resource(context, resource); +} + +static void +trace_context_render_condition(struct pipe_context *_context, + struct pipe_query *query, + boolean condition, + enum pipe_render_cond_flag mode) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + query = trace_query_unwrap(query); + + trace_dump_call_begin("pipe_context", "render_condition"); + + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, query); + trace_dump_arg(bool, condition); + trace_dump_arg(uint, mode); + + trace_dump_call_end(); + + context->render_condition(context, query, condition, mode); +} + + +static void +trace_context_texture_barrier(struct pipe_context *_context, unsigned flags) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "texture_barrier"); + + trace_dump_arg(ptr, context); + trace_dump_arg(uint, flags); + + trace_dump_call_end(); + + context->texture_barrier(context, flags); +} + + +static void +trace_context_memory_barrier(struct pipe_context *_context, + unsigned flags) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "memory_barrier"); + trace_dump_arg(ptr, context); + trace_dump_arg(uint, flags); + trace_dump_call_end(); + + context->memory_barrier(context, flags); +} + + +static bool +trace_context_resource_commit(struct pipe_context *_context, + struct pipe_resource *resource, + unsigned level, struct pipe_box *box, bool commit) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "resource_commit"); + trace_dump_arg(ptr, context); + trace_dump_arg(ptr, resource); + trace_dump_arg(uint, level); + trace_dump_arg(box, box); + trace_dump_arg(bool, commit); + trace_dump_call_end(); + + return context->resource_commit(context, resource, level, box, commit); +} + +static void +trace_context_set_tess_state(struct pipe_context *_context, + const float default_outer_level[4], + const float default_inner_level[2]) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "set_tess_state"); + trace_dump_arg(ptr, context); + trace_dump_arg_array(float, default_outer_level, 4); + trace_dump_arg_array(float, default_inner_level, 2); + trace_dump_call_end(); + + context->set_tess_state(context, default_outer_level, default_inner_level); +} + + +static void trace_context_set_shader_buffers(struct pipe_context *_context, + enum pipe_shader_type shader, + unsigned start, unsigned nr, + const struct pipe_shader_buffer *buffers) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "set_shader_buffers"); + trace_dump_arg(ptr, context); + trace_dump_arg(uint, shader); + trace_dump_arg(uint, start); + trace_dump_arg_begin("buffers"); + trace_dump_struct_array(shader_buffer, buffers, nr); + trace_dump_arg_end(); + trace_dump_call_end(); + + context->set_shader_buffers(context, shader, start, nr, buffers); +} + +static void trace_context_set_shader_images(struct pipe_context *_context, + enum pipe_shader_type shader, + unsigned start, unsigned nr, + const struct pipe_image_view *images) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "set_shader_images"); + trace_dump_arg(ptr, context); + trace_dump_arg(uint, shader); + trace_dump_arg(uint, start); + trace_dump_arg_begin("images"); + trace_dump_struct_array(image_view, images, nr); + trace_dump_arg_end(); + trace_dump_call_end(); + + context->set_shader_images(context, shader, start, nr, images); +} + +static void trace_context_launch_grid(struct pipe_context *_pipe, + const struct pipe_grid_info *info) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "launch_grid"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(grid_info, info); + + trace_dump_trace_flush(); + + pipe->launch_grid(pipe, info); + + trace_dump_call_end(); +} + +static uint64_t trace_context_create_texture_handle(struct pipe_context *_pipe, + struct pipe_sampler_view *view, + const struct pipe_sampler_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + uint64_t handle; + + trace_dump_call_begin("pipe_context", "create_texture_handle"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, view); + trace_dump_arg_begin("state"); + trace_dump_arg(sampler_state, state); + trace_dump_arg_end(); + + handle = pipe->create_texture_handle(pipe, view, state); + + trace_dump_ret(uint, handle); + trace_dump_call_end(); + + return handle; +} + +static void trace_context_delete_texture_handle(struct pipe_context *_pipe, + uint64_t handle) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_texture_handle"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, handle); + trace_dump_call_end(); + + pipe->delete_texture_handle(pipe, handle); +} + +static void trace_context_make_texture_handle_resident(struct pipe_context *_pipe, + uint64_t handle, + bool resident) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "make_texture_handle_resident"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, handle); + trace_dump_arg(bool, resident); + trace_dump_call_end(); + + pipe->make_texture_handle_resident(pipe, handle, resident); +} + +static uint64_t trace_context_create_image_handle(struct pipe_context *_pipe, + const struct pipe_image_view *image) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + uint64_t handle; + + trace_dump_call_begin("pipe_context", "create_image_handle"); + trace_dump_arg(ptr, pipe); + trace_dump_arg_begin("image"); + trace_dump_image_view(image); + trace_dump_arg_end(); + + handle = pipe->create_image_handle(pipe, image); + + trace_dump_ret(uint, handle); + trace_dump_call_end(); + + return handle; +} + +static void trace_context_delete_image_handle(struct pipe_context *_pipe, + uint64_t handle) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "delete_image_handle"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, handle); + trace_dump_call_end(); + + pipe->delete_image_handle(pipe, handle); +} + +static void trace_context_make_image_handle_resident(struct pipe_context *_pipe, + uint64_t handle, + unsigned access, + bool resident) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "make_image_handle_resident"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, handle); + trace_dump_arg(uint, access); + trace_dump_arg(bool, resident); + trace_dump_call_end(); + + pipe->make_image_handle_resident(pipe, handle, access, resident); +} + +struct pipe_context * +trace_context_create(struct trace_screen *tr_scr, + struct pipe_context *pipe) +{ + struct trace_context *tr_ctx; + + if (!pipe) + goto error1; + + if (!trace_enabled()) + goto error1; + + tr_ctx = CALLOC_STRUCT(trace_context); + if (!tr_ctx) + goto error1; + + tr_ctx->base.priv = pipe->priv; /* expose wrapped priv data */ + tr_ctx->base.screen = &tr_scr->base; + tr_ctx->base.stream_uploader = pipe->stream_uploader; + tr_ctx->base.const_uploader = pipe->const_uploader; + + tr_ctx->base.destroy = trace_context_destroy; + +#define TR_CTX_INIT(_member) \ + tr_ctx->base . _member = pipe -> _member ? trace_context_ ## _member : NULL + + TR_CTX_INIT(draw_vbo); + TR_CTX_INIT(render_condition); + TR_CTX_INIT(create_query); + TR_CTX_INIT(destroy_query); + TR_CTX_INIT(begin_query); + TR_CTX_INIT(end_query); + TR_CTX_INIT(get_query_result); + TR_CTX_INIT(set_active_query_state); + TR_CTX_INIT(create_blend_state); + TR_CTX_INIT(bind_blend_state); + TR_CTX_INIT(delete_blend_state); + TR_CTX_INIT(create_sampler_state); + TR_CTX_INIT(bind_sampler_states); + TR_CTX_INIT(delete_sampler_state); + TR_CTX_INIT(create_rasterizer_state); + TR_CTX_INIT(bind_rasterizer_state); + TR_CTX_INIT(delete_rasterizer_state); + TR_CTX_INIT(create_depth_stencil_alpha_state); + TR_CTX_INIT(bind_depth_stencil_alpha_state); + TR_CTX_INIT(delete_depth_stencil_alpha_state); + TR_CTX_INIT(create_fs_state); + TR_CTX_INIT(bind_fs_state); + TR_CTX_INIT(delete_fs_state); + TR_CTX_INIT(create_vs_state); + TR_CTX_INIT(bind_vs_state); + TR_CTX_INIT(delete_vs_state); + TR_CTX_INIT(create_gs_state); + TR_CTX_INIT(bind_gs_state); + TR_CTX_INIT(delete_gs_state); + TR_CTX_INIT(create_tcs_state); + TR_CTX_INIT(bind_tcs_state); + TR_CTX_INIT(delete_tcs_state); + TR_CTX_INIT(create_tes_state); + TR_CTX_INIT(bind_tes_state); + TR_CTX_INIT(delete_tes_state); + TR_CTX_INIT(create_compute_state); + TR_CTX_INIT(bind_compute_state); + TR_CTX_INIT(delete_compute_state); + TR_CTX_INIT(create_vertex_elements_state); + TR_CTX_INIT(bind_vertex_elements_state); + TR_CTX_INIT(delete_vertex_elements_state); + TR_CTX_INIT(set_blend_color); + TR_CTX_INIT(set_stencil_ref); + TR_CTX_INIT(set_clip_state); + TR_CTX_INIT(set_sample_mask); + TR_CTX_INIT(set_constant_buffer); + TR_CTX_INIT(set_framebuffer_state); + TR_CTX_INIT(set_polygon_stipple); + TR_CTX_INIT(set_scissor_states); + TR_CTX_INIT(set_viewport_states); + TR_CTX_INIT(set_sampler_views); + TR_CTX_INIT(create_sampler_view); + TR_CTX_INIT(sampler_view_destroy); + TR_CTX_INIT(create_surface); + TR_CTX_INIT(surface_destroy); + TR_CTX_INIT(set_vertex_buffers); + TR_CTX_INIT(create_stream_output_target); + TR_CTX_INIT(stream_output_target_destroy); + TR_CTX_INIT(set_stream_output_targets); + TR_CTX_INIT(resource_copy_region); + TR_CTX_INIT(blit); + TR_CTX_INIT(flush_resource); + TR_CTX_INIT(clear); + TR_CTX_INIT(clear_render_target); + TR_CTX_INIT(clear_depth_stencil); + TR_CTX_INIT(clear_texture); + TR_CTX_INIT(flush); + TR_CTX_INIT(generate_mipmap); + TR_CTX_INIT(texture_barrier); + TR_CTX_INIT(memory_barrier); + TR_CTX_INIT(resource_commit); + TR_CTX_INIT(set_tess_state); + TR_CTX_INIT(set_shader_buffers); + TR_CTX_INIT(launch_grid); + TR_CTX_INIT(set_shader_images); + TR_CTX_INIT(create_texture_handle); + TR_CTX_INIT(delete_texture_handle); + TR_CTX_INIT(make_texture_handle_resident); + TR_CTX_INIT(create_image_handle); + TR_CTX_INIT(delete_image_handle); + TR_CTX_INIT(make_image_handle_resident); + + TR_CTX_INIT(transfer_map); + TR_CTX_INIT(transfer_unmap); + TR_CTX_INIT(transfer_flush_region); + TR_CTX_INIT(buffer_subdata); + TR_CTX_INIT(texture_subdata); + TR_CTX_INIT(invalidate_resource); + +#undef TR_CTX_INIT + + tr_ctx->pipe = pipe; + + return &tr_ctx->base; + +error1: + return pipe; +} + + +/** + * Sanity checker: check that the given context really is a + * trace context (and not the wrapped driver's context). + */ +void +trace_context_check(const struct pipe_context *pipe) +{ + MAYBE_UNUSED struct trace_context *tr_ctx = (struct trace_context *) pipe; + assert(tr_ctx->base.destroy == trace_context_destroy); +} diff --git a/src/gallium/auxiliary/driver_trace/tr_context.h b/src/gallium/auxiliary/driver_trace/tr_context.h new file mode 100644 index 00000000000..ad57d9d5243 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_context.h @@ -0,0 +1,77 @@ +/************************************************************************** + * + * Copyright 2008 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 TR_CONTEXT_H_ +#define TR_CONTEXT_H_ + + +#include "pipe/p_compiler.h" +#include "util/u_debug.h" +#include "pipe/p_context.h" + +#include "tr_screen.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +struct trace_screen; + +struct trace_context +{ + struct pipe_context base; + + struct pipe_context *pipe; +}; + + +void +trace_context_check(const struct pipe_context *pipe); + + +static inline struct trace_context * +trace_context(struct pipe_context *pipe) +{ + assert(pipe); +#ifdef DEBUG + trace_context_check(pipe); +#endif + return (struct trace_context *)pipe; +} + + +struct pipe_context * +trace_context_create(struct trace_screen *tr_scr, + struct pipe_context *pipe); + + +#ifdef __cplusplus +} +#endif + +#endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/auxiliary/driver_trace/tr_dump.c b/src/gallium/auxiliary/driver_trace/tr_dump.c new file mode 100644 index 00000000000..49349496ac6 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_dump.c @@ -0,0 +1,599 @@ +/************************************************************************** + * + * Copyright 2008 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. + * + **************************************************************************/ + + +/** + * @file + * Trace dumping functions. + * + * For now we just use standard XML for dumping the trace calls, as this is + * simple to write, parse, and visually inspect, but the actual representation + * is abstracted out of this file, so that we can switch to a binary + * representation if/when it becomes justified. + * + * @author Jose Fonseca + */ + +#include "pipe/p_config.h" + +#include +#include + +#include "pipe/p_compiler.h" +#include "os/os_thread.h" +#include "util/os_time.h" +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "util/u_string.h" +#include "util/u_math.h" +#include "util/u_format.h" + +#include "tr_dump.h" +#include "tr_screen.h" +#include "tr_texture.h" + + +static boolean close_stream = FALSE; +static FILE *stream = NULL; +static mtx_t call_mutex = _MTX_INITIALIZER_NP; +static long unsigned call_no = 0; +static boolean dumping = FALSE; + + +static inline void +trace_dump_write(const char *buf, size_t size) +{ + if (stream) { + fwrite(buf, size, 1, stream); + } +} + + +static inline void +trace_dump_writes(const char *s) +{ + trace_dump_write(s, strlen(s)); +} + + +static inline void +trace_dump_writef(const char *format, ...) +{ + static char buf[1024]; + unsigned len; + va_list ap; + va_start(ap, format); + len = util_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + trace_dump_write(buf, len); +} + + +static inline void +trace_dump_escape(const char *str) +{ + const unsigned char *p = (const unsigned char *)str; + unsigned char c; + while((c = *p++) != 0) { + if(c == '<') + trace_dump_writes("<"); + else if(c == '>') + trace_dump_writes(">"); + else if(c == '&') + trace_dump_writes("&"); + else if(c == '\'') + trace_dump_writes("'"); + else if(c == '\"') + trace_dump_writes("""); + else if(c >= 0x20 && c <= 0x7e) + trace_dump_writef("%c", c); + else + trace_dump_writef("&#%u;", c); + } +} + + +static inline void +trace_dump_indent(unsigned level) +{ + unsigned i; + for(i = 0; i < level; ++i) + trace_dump_writes("\t"); +} + + +static inline void +trace_dump_newline(void) +{ + trace_dump_writes("\n"); +} + + +static inline void +trace_dump_tag_begin(const char *name) +{ + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes(">"); +} + +static inline void +trace_dump_tag_begin1(const char *name, + const char *attr1, const char *value1) +{ + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes(" "); + trace_dump_writes(attr1); + trace_dump_writes("='"); + trace_dump_escape(value1); + trace_dump_writes("'>"); +} + + +static inline void +trace_dump_tag_end(const char *name) +{ + trace_dump_writes(""); +} + +void +trace_dump_trace_flush(void) +{ + if (stream) { + fflush(stream); + } +} + +static void +trace_dump_trace_close(void) +{ + if (stream) { + trace_dump_writes("\n"); + if (close_stream) { + fclose(stream); + close_stream = FALSE; + stream = NULL; + } + call_no = 0; + } +} + + +static void +trace_dump_call_time(int64_t time) +{ + if (stream) { + trace_dump_indent(2); + trace_dump_tag_begin("time"); + trace_dump_int(time); + trace_dump_tag_end("time"); + trace_dump_newline(); + } +} + + +boolean +trace_dump_trace_begin(void) +{ + const char *filename; + + filename = debug_get_option("GALLIUM_TRACE", NULL); + if (!filename) + return FALSE; + + if (!stream) { + + if (strcmp(filename, "stderr") == 0) { + close_stream = FALSE; + stream = stderr; + } + else if (strcmp(filename, "stdout") == 0) { + close_stream = FALSE; + stream = stdout; + } + else { + close_stream = TRUE; + stream = fopen(filename, "wt"); + if (!stream) + return FALSE; + } + + trace_dump_writes("\n"); + trace_dump_writes("\n"); + trace_dump_writes("\n"); + + /* Many applications don't exit cleanly, others may create and destroy a + * screen multiple times, so we only write tag and close at exit + * time. + */ + atexit(trace_dump_trace_close); + } + + return TRUE; +} + +boolean trace_dump_trace_enabled(void) +{ + return stream ? TRUE : FALSE; +} + +/* + * Call lock + */ + +void trace_dump_call_lock(void) +{ + mtx_lock(&call_mutex); +} + +void trace_dump_call_unlock(void) +{ + mtx_unlock(&call_mutex); +} + +/* + * Dumping control + */ + +void trace_dumping_start_locked(void) +{ + dumping = TRUE; +} + +void trace_dumping_stop_locked(void) +{ + dumping = FALSE; +} + +boolean trace_dumping_enabled_locked(void) +{ + return dumping; +} + +void trace_dumping_start(void) +{ + mtx_lock(&call_mutex); + trace_dumping_start_locked(); + mtx_unlock(&call_mutex); +} + +void trace_dumping_stop(void) +{ + mtx_lock(&call_mutex); + trace_dumping_stop_locked(); + mtx_unlock(&call_mutex); +} + +boolean trace_dumping_enabled(void) +{ + boolean ret; + mtx_lock(&call_mutex); + ret = trace_dumping_enabled_locked(); + mtx_unlock(&call_mutex); + return ret; +} + +/* + * Dump functions + */ + +static int64_t call_start_time = 0; + +void trace_dump_call_begin_locked(const char *klass, const char *method) +{ + if (!dumping) + return; + + ++call_no; + trace_dump_indent(1); + trace_dump_writes(""); + trace_dump_newline(); + + call_start_time = os_time_get(); +} + +void trace_dump_call_end_locked(void) +{ + int64_t call_end_time; + + if (!dumping) + return; + + call_end_time = os_time_get(); + + trace_dump_call_time(call_end_time - call_start_time); + trace_dump_indent(1); + trace_dump_tag_end("call"); + trace_dump_newline(); + fflush(stream); +} + +void trace_dump_call_begin(const char *klass, const char *method) +{ + mtx_lock(&call_mutex); + trace_dump_call_begin_locked(klass, method); +} + +void trace_dump_call_end(void) +{ + trace_dump_call_end_locked(); + mtx_unlock(&call_mutex); +} + +void trace_dump_arg_begin(const char *name) +{ + if (!dumping) + return; + + trace_dump_indent(2); + trace_dump_tag_begin1("arg", "name", name); +} + +void trace_dump_arg_end(void) +{ + if (!dumping) + return; + + trace_dump_tag_end("arg"); + trace_dump_newline(); +} + +void trace_dump_ret_begin(void) +{ + if (!dumping) + return; + + trace_dump_indent(2); + trace_dump_tag_begin("ret"); +} + +void trace_dump_ret_end(void) +{ + if (!dumping) + return; + + trace_dump_tag_end("ret"); + trace_dump_newline(); +} + +void trace_dump_bool(int value) +{ + if (!dumping) + return; + + trace_dump_writef("%c", value ? '1' : '0'); +} + +void trace_dump_int(long long int value) +{ + if (!dumping) + return; + + trace_dump_writef("%lli", value); +} + +void trace_dump_uint(long long unsigned value) +{ + if (!dumping) + return; + + trace_dump_writef("%llu", value); +} + +void trace_dump_float(double value) +{ + if (!dumping) + return; + + trace_dump_writef("%g", value); +} + +void trace_dump_bytes(const void *data, + size_t size) +{ + static const char hex_table[16] = "0123456789ABCDEF"; + const uint8_t *p = data; + size_t i; + + if (!dumping) + return; + + trace_dump_writes(""); + for(i = 0; i < size; ++i) { + uint8_t byte = *p++; + char hex[2]; + hex[0] = hex_table[byte >> 4]; + hex[1] = hex_table[byte & 0xf]; + trace_dump_write(hex, 2); + } + trace_dump_writes(""); +} + +void trace_dump_box_bytes(const void *data, + struct pipe_resource *resource, + const struct pipe_box *box, + unsigned stride, + unsigned slice_stride) +{ + enum pipe_format format = resource->format; + size_t size; + + assert(box->height > 0); + assert(box->depth > 0); + + size = util_format_get_nblocksx(format, box->width ) * util_format_get_blocksize(format) + + (util_format_get_nblocksy(format, box->height) - 1) * stride + + (box->depth - 1) * slice_stride; + + /* + * Only dump buffer transfers to avoid huge files. + * TODO: Make this run-time configurable + */ + if (resource->target != PIPE_BUFFER) { + size = 0; + } + + trace_dump_bytes(data, size); +} + +void trace_dump_string(const char *str) +{ + if (!dumping) + return; + + trace_dump_writes(""); + trace_dump_escape(str); + trace_dump_writes(""); +} + +void trace_dump_enum(const char *value) +{ + if (!dumping) + return; + + trace_dump_writes(""); + trace_dump_escape(value); + trace_dump_writes(""); +} + +void trace_dump_array_begin(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_array_end(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_elem_begin(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_elem_end(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_struct_begin(const char *name) +{ + if (!dumping) + return; + + trace_dump_writef("", name); +} + +void trace_dump_struct_end(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_member_begin(const char *name) +{ + if (!dumping) + return; + + trace_dump_writef("", name); +} + +void trace_dump_member_end(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_null(void) +{ + if (!dumping) + return; + + trace_dump_writes(""); +} + +void trace_dump_ptr(const void *value) +{ + if (!dumping) + return; + + if(value) + trace_dump_writef("0x%08lx", (unsigned long)(uintptr_t)value); + else + trace_dump_null(); +} + +void trace_dump_surface_ptr(struct pipe_surface *_surface) +{ + if (!dumping) + return; + + if (_surface) { + struct trace_surface *tr_surf = trace_surface(_surface); + trace_dump_ptr(tr_surf->surface); + } else { + trace_dump_null(); + } +} + +void trace_dump_transfer_ptr(struct pipe_transfer *_transfer) +{ + if (!dumping) + return; + + if (_transfer) { + struct trace_transfer *tr_tran = trace_transfer(_transfer); + trace_dump_ptr(tr_tran->transfer); + } else { + trace_dump_null(); + } +} diff --git a/src/gallium/auxiliary/driver_trace/tr_dump.h b/src/gallium/auxiliary/driver_trace/tr_dump.h new file mode 100644 index 00000000000..7a268e31c46 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_dump.h @@ -0,0 +1,190 @@ +/************************************************************************** + * + * Copyright 2008 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. + * + **************************************************************************/ + +/** + * @file + * Trace data dumping primitives. + */ + +#ifndef TR_DUMP_H +#define TR_DUMP_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" + +struct pipe_resource; +struct pipe_surface; +struct pipe_transfer; +struct pipe_box; + +/* + * Low level dumping controls. + * + * Opening the trace file and checking if that is opened. + */ +boolean trace_dump_trace_begin(void); +boolean trace_dump_trace_enabled(void); +void trace_dump_trace_flush(void); + +/* + * Lock and unlock the call mutex. + * + * It used by the none locked version of dumping control + * and begin/end call dump functions. + * + * Begin takes the lock while end unlocks it. Use the _locked + * version to avoid locking/unlocking it. + */ +void trace_dump_call_lock(void); +void trace_dump_call_unlock(void); + +/* + * High level dumping control. + */ +void trace_dumping_start_locked(void); +void trace_dumping_stop_locked(void); +boolean trace_dumping_enabled_locked(void); +void trace_dumping_start(void); +void trace_dumping_stop(void); +boolean trace_dumping_enabled(void); + +void trace_dump_call_begin_locked(const char *klass, const char *method); +void trace_dump_call_end_locked(void); +void trace_dump_call_begin(const char *klass, const char *method); +void trace_dump_call_end(void); + +void trace_dump_arg_begin(const char *name); +void trace_dump_arg_end(void); +void trace_dump_ret_begin(void); +void trace_dump_ret_end(void); +void trace_dump_bool(int value); +void trace_dump_int(long long int value); +void trace_dump_uint(long long unsigned value); +void trace_dump_float(double value); +void trace_dump_bytes(const void *data, size_t size); +void trace_dump_box_bytes(const void *data, + struct pipe_resource *resource, + const struct pipe_box *box, + unsigned stride, + unsigned slice_stride); +void trace_dump_string(const char *str); +void trace_dump_enum(const char *value); +void trace_dump_array_begin(void); +void trace_dump_array_end(void); +void trace_dump_elem_begin(void); +void trace_dump_elem_end(void); +void trace_dump_struct_begin(const char *name); +void trace_dump_struct_end(void); +void trace_dump_member_begin(const char *name); +void trace_dump_member_end(void); +void trace_dump_null(void); +void trace_dump_ptr(const void *value); +/* will turn a wrapped object into the real one and dump ptr */ +void trace_dump_surface_ptr(struct pipe_surface *_surface); +void trace_dump_transfer_ptr(struct pipe_transfer *_transfer); + +/* + * Code saving macros. + */ + +#define trace_dump_arg(_type, _arg) \ + do { \ + trace_dump_arg_begin(#_arg); \ + trace_dump_##_type(_arg); \ + trace_dump_arg_end(); \ + } while(0) + +#define trace_dump_arg_struct(_type, _arg) \ + do { \ + trace_dump_arg_begin(#_arg); \ + trace_dump_##_type(&_arg); \ + trace_dump_arg_end(); \ + } while(0) + +#define trace_dump_ret(_type, _arg) \ + do { \ + trace_dump_ret_begin(); \ + trace_dump_##_type(_arg); \ + trace_dump_ret_end(); \ + } while(0) + +#define trace_dump_array(_type, _obj, _size) \ + do { \ + if (_obj) { \ + size_t idx; \ + trace_dump_array_begin(); \ + for(idx = 0; idx < (_size); ++idx) { \ + trace_dump_elem_begin(); \ + trace_dump_##_type((_obj)[idx]); \ + trace_dump_elem_end(); \ + } \ + trace_dump_array_end(); \ + } else { \ + trace_dump_null(); \ + } \ + } while(0) + +#define trace_dump_struct_array(_type, _obj, _size) \ + do { \ + if (_obj) { \ + size_t idx; \ + trace_dump_array_begin(); \ + for(idx = 0; idx < (_size); ++idx) { \ + trace_dump_elem_begin(); \ + trace_dump_##_type(&(_obj)[idx]); \ + trace_dump_elem_end(); \ + } \ + trace_dump_array_end(); \ + } else { \ + trace_dump_null(); \ + } \ + } while(0) + +#define trace_dump_member(_type, _obj, _member) \ + do { \ + trace_dump_member_begin(#_member); \ + trace_dump_##_type((_obj)->_member); \ + trace_dump_member_end(); \ + } while(0) + +#define trace_dump_arg_array(_type, _arg, _size) \ + do { \ + trace_dump_arg_begin(#_arg); \ + trace_dump_array(_type, _arg, _size); \ + trace_dump_arg_end(); \ + } while(0) + +#define trace_dump_member_array(_type, _obj, _member) \ + do { \ + trace_dump_member_begin(#_member); \ + trace_dump_array(_type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ + trace_dump_member_end(); \ + } while(0) + + +#endif /* TR_DUMP_H */ diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_defines.h b/src/gallium/auxiliary/driver_trace/tr_dump_defines.h new file mode 100644 index 00000000000..7f969a30333 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_dump_defines.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2013 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 TR_DUMP_DEFINES_H_ +#define TR_DUMP_DEFINES_H_ + +#include "pipe/p_compiler.h" +#include "util/u_format.h" +#include "util/u_dump.h" +#include "tr_dump.h" + + +static inline void +trace_dump_format(enum pipe_format format) +{ + if (!trace_dumping_enabled_locked()) + return; + + trace_dump_enum(util_format_name(format)); +} + + +static inline void +trace_dump_query_type(unsigned value) +{ + if (!trace_dumping_enabled_locked()) + return; + + trace_dump_enum(util_str_query_type(value, FALSE)); +} + + + +#endif /* TR_DUMP_DEFINES_H_ */ diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.c b/src/gallium/auxiliary/driver_trace/tr_dump_state.c new file mode 100644 index 00000000000..e7e32237c4c --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.c @@ -0,0 +1,961 @@ +/************************************************************************** + * + * Copyright 2008 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_compiler.h" +#include "util/u_memory.h" +#include "util/u_format.h" +#include "tgsi/tgsi_dump.h" + +#include "tr_dump.h" +#include "tr_dump_defines.h" +#include "tr_dump_state.h" + + +void trace_dump_resource_template(const struct pipe_resource *templat) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!templat) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_resource"); + + trace_dump_member(int, templat, target); + trace_dump_member(format, templat, format); + + trace_dump_member_begin("width"); + trace_dump_uint(templat->width0); + trace_dump_member_end(); + + trace_dump_member_begin("height"); + trace_dump_uint(templat->height0); + trace_dump_member_end(); + + trace_dump_member_begin("depth"); + trace_dump_uint(templat->depth0); + trace_dump_member_end(); + + trace_dump_member_begin("array_size"); + trace_dump_uint(templat->array_size); + trace_dump_member_end(); + + trace_dump_member(uint, templat, last_level); + trace_dump_member(uint, templat, nr_samples); + trace_dump_member(uint, templat, usage); + trace_dump_member(uint, templat, bind); + trace_dump_member(uint, templat, flags); + + trace_dump_struct_end(); +} + + +void trace_dump_box(const struct pipe_box *box) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!box) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_box"); + + trace_dump_member(int, box, x); + trace_dump_member(int, box, y); + trace_dump_member(int, box, z); + trace_dump_member(int, box, width); + trace_dump_member(int, box, height); + trace_dump_member(int, box, depth); + + trace_dump_struct_end(); +} + + +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_rasterizer_state"); + + trace_dump_member(bool, state, flatshade); + trace_dump_member(bool, state, light_twoside); + trace_dump_member(bool, state, clamp_vertex_color); + trace_dump_member(bool, state, clamp_fragment_color); + trace_dump_member(uint, state, front_ccw); + trace_dump_member(uint, state, cull_face); + trace_dump_member(uint, state, fill_front); + trace_dump_member(uint, state, fill_back); + trace_dump_member(bool, state, offset_point); + trace_dump_member(bool, state, offset_line); + trace_dump_member(bool, state, offset_tri); + trace_dump_member(bool, state, scissor); + trace_dump_member(bool, state, poly_smooth); + trace_dump_member(bool, state, poly_stipple_enable); + trace_dump_member(bool, state, point_smooth); + trace_dump_member(bool, state, sprite_coord_mode); + trace_dump_member(bool, state, point_quad_rasterization); + trace_dump_member(bool, state, point_size_per_vertex); + trace_dump_member(bool, state, multisample); + trace_dump_member(bool, state, line_smooth); + trace_dump_member(bool, state, line_stipple_enable); + trace_dump_member(bool, state, line_last_pixel); + + trace_dump_member(bool, state, flatshade_first); + + trace_dump_member(bool, state, half_pixel_center); + trace_dump_member(bool, state, bottom_edge_rule); + + trace_dump_member(bool, state, rasterizer_discard); + + trace_dump_member(bool, state, depth_clip); + + trace_dump_member(bool, state, clip_halfz); + + trace_dump_member(uint, state, clip_plane_enable); + + trace_dump_member(uint, state, line_stipple_factor); + trace_dump_member(uint, state, line_stipple_pattern); + + trace_dump_member(uint, state, sprite_coord_enable); + + trace_dump_member(float, state, line_width); + trace_dump_member(float, state, point_size); + trace_dump_member(float, state, offset_units); + trace_dump_member(float, state, offset_scale); + trace_dump_member(float, state, offset_clamp); + + trace_dump_struct_end(); +} + + +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_poly_stipple"); + + trace_dump_member_begin("stipple"); + trace_dump_array(uint, + state->stipple, + ARRAY_SIZE(state->stipple)); + trace_dump_member_end(); + + trace_dump_struct_end(); +} + + +void trace_dump_viewport_state(const struct pipe_viewport_state *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_viewport_state"); + + trace_dump_member_array(float, state, scale); + trace_dump_member_array(float, state, translate); + + trace_dump_struct_end(); +} + + +void trace_dump_scissor_state(const struct pipe_scissor_state *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_scissor_state"); + + trace_dump_member(uint, state, minx); + trace_dump_member(uint, state, miny); + trace_dump_member(uint, state, maxx); + trace_dump_member(uint, state, maxy); + + trace_dump_struct_end(); +} + + +void trace_dump_clip_state(const struct pipe_clip_state *state) +{ + unsigned i; + + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_clip_state"); + + trace_dump_member_begin("ucp"); + trace_dump_array_begin(); + for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { + trace_dump_elem_begin(); + trace_dump_array(float, state->ucp[i], 4); + trace_dump_elem_end(); + } + trace_dump_array_end(); + trace_dump_member_end(); + + trace_dump_struct_end(); +} + + +void trace_dump_shader_state(const struct pipe_shader_state *state) +{ + unsigned i; + + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + + trace_dump_struct_begin("pipe_shader_state"); + + trace_dump_member_begin("tokens"); + if (state->tokens) { + static char str[64 * 1024]; + tgsi_dump_str(state->tokens, 0, str, sizeof(str)); + trace_dump_string(str); + } else { + trace_dump_null(); + } + trace_dump_member_end(); + + trace_dump_member_begin("stream_output"); + trace_dump_struct_begin("pipe_stream_output_info"); + trace_dump_member(uint, &state->stream_output, num_outputs); + trace_dump_member_array(uint, &state->stream_output, stride); + trace_dump_member_begin("output"); + trace_dump_array_begin(); + for(i = 0; i < state->stream_output.num_outputs; ++i) { + trace_dump_elem_begin(); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->stream_output.output[i], register_index); + trace_dump_member(uint, &state->stream_output.output[i], start_component); + trace_dump_member(uint, &state->stream_output.output[i], num_components); + trace_dump_member(uint, &state->stream_output.output[i], output_buffer); + trace_dump_member(uint, &state->stream_output.output[i], dst_offset); + trace_dump_member(uint, &state->stream_output.output[i], stream); + trace_dump_struct_end(); + trace_dump_elem_end(); + } + trace_dump_array_end(); + trace_dump_member_end(); // output + trace_dump_struct_end(); + trace_dump_member_end(); // stream_output + + trace_dump_struct_end(); +} + + +void trace_dump_compute_state(const struct pipe_compute_state *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_compute_state"); + + trace_dump_member(uint, state, ir_type); + + trace_dump_member_begin("prog"); + if (state->prog && state->ir_type == PIPE_SHADER_IR_TGSI) { + static char str[64 * 1024]; + tgsi_dump_str(state->prog, 0, str, sizeof(str)); + trace_dump_string(str); + } else { + trace_dump_null(); + } + trace_dump_member_end(); + + trace_dump_member(uint, state, req_local_mem); + trace_dump_member(uint, state, req_private_mem); + trace_dump_member(uint, state, req_input_mem); + + trace_dump_struct_end(); +} + + +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state) +{ + unsigned i; + + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_depth_stencil_alpha_state"); + + trace_dump_member_begin("depth"); + trace_dump_struct_begin("pipe_depth_state"); + trace_dump_member(bool, &state->depth, enabled); + trace_dump_member(bool, &state->depth, writemask); + trace_dump_member(uint, &state->depth, func); + trace_dump_struct_end(); + trace_dump_member_end(); + + trace_dump_member_begin("stencil"); + trace_dump_array_begin(); + for(i = 0; i < ARRAY_SIZE(state->stencil); ++i) { + trace_dump_elem_begin(); + trace_dump_struct_begin("pipe_stencil_state"); + trace_dump_member(bool, &state->stencil[i], enabled); + trace_dump_member(uint, &state->stencil[i], func); + trace_dump_member(uint, &state->stencil[i], fail_op); + trace_dump_member(uint, &state->stencil[i], zpass_op); + trace_dump_member(uint, &state->stencil[i], zfail_op); + trace_dump_member(uint, &state->stencil[i], valuemask); + trace_dump_member(uint, &state->stencil[i], writemask); + trace_dump_struct_end(); + trace_dump_elem_end(); + } + trace_dump_array_end(); + trace_dump_member_end(); + + trace_dump_member_begin("alpha"); + trace_dump_struct_begin("pipe_alpha_state"); + trace_dump_member(bool, &state->alpha, enabled); + trace_dump_member(uint, &state->alpha, func); + trace_dump_member(float, &state->alpha, ref_value); + trace_dump_struct_end(); + trace_dump_member_end(); + + trace_dump_struct_end(); +} + +static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state) +{ + trace_dump_struct_begin("pipe_rt_blend_state"); + + trace_dump_member(uint, state, blend_enable); + + trace_dump_member(uint, state, rgb_func); + trace_dump_member(uint, state, rgb_src_factor); + trace_dump_member(uint, state, rgb_dst_factor); + + trace_dump_member(uint, state, alpha_func); + trace_dump_member(uint, state, alpha_src_factor); + trace_dump_member(uint, state, alpha_dst_factor); + + trace_dump_member(uint, state, colormask); + + trace_dump_struct_end(); +} + +void trace_dump_blend_state(const struct pipe_blend_state *state) +{ + unsigned valid_entries = 1; + + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_blend_state"); + + trace_dump_member(bool, state, dither); + + trace_dump_member(bool, state, logicop_enable); + trace_dump_member(uint, state, logicop_func); + + trace_dump_member(bool, state, independent_blend_enable); + + trace_dump_member_begin("rt"); + if (state->independent_blend_enable) + valid_entries = PIPE_MAX_COLOR_BUFS; + trace_dump_struct_array(rt_blend_state, state->rt, valid_entries); + trace_dump_member_end(); + + trace_dump_struct_end(); +} + + +void trace_dump_blend_color(const struct pipe_blend_color *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_blend_color"); + + trace_dump_member_array(float, state, color); + + trace_dump_struct_end(); +} + +void trace_dump_stencil_ref(const struct pipe_stencil_ref *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_stencil_ref"); + + trace_dump_member_array(uint, state, ref_value); + + trace_dump_struct_end(); +} + +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + trace_dump_struct_begin("pipe_framebuffer_state"); + + trace_dump_member(uint, state, width); + trace_dump_member(uint, state, height); + trace_dump_member(uint, state, samples); + trace_dump_member(uint, state, layers); + trace_dump_member(uint, state, nr_cbufs); + trace_dump_member_array(ptr, state, cbufs); + trace_dump_member(ptr, state, zsbuf); + + trace_dump_struct_end(); +} + + +void trace_dump_sampler_state(const struct pipe_sampler_state *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_sampler_state"); + + trace_dump_member(uint, state, wrap_s); + trace_dump_member(uint, state, wrap_t); + trace_dump_member(uint, state, wrap_r); + trace_dump_member(uint, state, min_img_filter); + trace_dump_member(uint, state, min_mip_filter); + trace_dump_member(uint, state, mag_img_filter); + trace_dump_member(uint, state, compare_mode); + trace_dump_member(uint, state, compare_func); + trace_dump_member(bool, state, normalized_coords); + trace_dump_member(uint, state, max_anisotropy); + trace_dump_member(bool, state, seamless_cube_map); + trace_dump_member(float, state, lod_bias); + trace_dump_member(float, state, min_lod); + trace_dump_member(float, state, max_lod); + trace_dump_member_array(float, state, border_color.f); + + trace_dump_struct_end(); +} + + +void trace_dump_sampler_view_template(const struct pipe_sampler_view *state, + enum pipe_texture_target target) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_sampler_view"); + + trace_dump_member(format, state, format); + + trace_dump_member_begin("u"); + trace_dump_struct_begin(""); /* anonymous */ + if (target == PIPE_BUFFER) { + trace_dump_member_begin("buf"); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->u.buf, offset); + trace_dump_member(uint, &state->u.buf, size); + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* buf */ + } else { + trace_dump_member_begin("tex"); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->u.tex, first_layer); + trace_dump_member(uint, &state->u.tex, last_layer); + trace_dump_member(uint, &state->u.tex, first_level); + trace_dump_member(uint, &state->u.tex, last_level); + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* tex */ + } + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* u */ + + trace_dump_member(uint, state, swizzle_r); + trace_dump_member(uint, state, swizzle_g); + trace_dump_member(uint, state, swizzle_b); + trace_dump_member(uint, state, swizzle_a); + + trace_dump_struct_end(); +} + + +void trace_dump_surface_template(const struct pipe_surface *state, + enum pipe_texture_target target) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_surface"); + + trace_dump_member(format, state, format); + trace_dump_member(uint, state, width); + trace_dump_member(uint, state, height); + + trace_dump_member_begin("u"); + trace_dump_struct_begin(""); /* anonymous */ + if (target == PIPE_BUFFER) { + trace_dump_member_begin("buf"); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->u.buf, first_element); + trace_dump_member(uint, &state->u.buf, last_element); + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* buf */ + } else { + trace_dump_member_begin("tex"); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->u.tex, level); + trace_dump_member(uint, &state->u.tex, first_layer); + trace_dump_member(uint, &state->u.tex, last_layer); + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* tex */ + } + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* u */ + + trace_dump_struct_end(); +} + + +void trace_dump_transfer(const struct pipe_transfer *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_transfer"); + + trace_dump_member(uint, state, box.x); + trace_dump_member(uint, state, box.y); + trace_dump_member(uint, state, box.z); + trace_dump_member(uint, state, box.width); + trace_dump_member(uint, state, box.height); + trace_dump_member(uint, state, box.depth); + + trace_dump_member(uint, state, stride); + trace_dump_member(uint, state, layer_stride); + trace_dump_member(uint, state, usage); + + trace_dump_member(ptr, state, resource); + + trace_dump_struct_end(); +} + + +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_vertex_buffer"); + + trace_dump_member(uint, state, stride); + trace_dump_member(bool, state, is_user_buffer); + trace_dump_member(uint, state, buffer_offset); + trace_dump_member(ptr, state, buffer.resource); + + trace_dump_struct_end(); +} + + +void trace_dump_vertex_element(const struct pipe_vertex_element *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_vertex_element"); + + trace_dump_member(uint, state, src_offset); + + trace_dump_member(uint, state, vertex_buffer_index); + + trace_dump_member(format, state, src_format); + + trace_dump_struct_end(); +} + + +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_constant_buffer"); + trace_dump_member(ptr, state, buffer); + trace_dump_member(uint, state, buffer_offset); + trace_dump_member(uint, state, buffer_size); + trace_dump_struct_end(); +} + + +void trace_dump_shader_buffer(const struct pipe_shader_buffer *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if(!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_shader_buffer"); + trace_dump_member(ptr, state, buffer); + trace_dump_member(uint, state, buffer_offset); + trace_dump_member(uint, state, buffer_size); + trace_dump_struct_end(); +} + + +void trace_dump_image_view(const struct pipe_image_view *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if(!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_image_view"); + trace_dump_member(ptr, state, resource); + trace_dump_member(uint, state, format); + trace_dump_member(uint, state, access); + + trace_dump_member_begin("u"); + trace_dump_struct_begin(""); /* anonymous */ + if (state->resource->target == PIPE_BUFFER) { + trace_dump_member_begin("buf"); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->u.buf, offset); + trace_dump_member(uint, &state->u.buf, size); + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* buf */ + } else { + trace_dump_member_begin("tex"); + trace_dump_struct_begin(""); /* anonymous */ + trace_dump_member(uint, &state->u.tex, first_layer); + trace_dump_member(uint, &state->u.tex, last_layer); + trace_dump_member(uint, &state->u.tex, level); + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* tex */ + } + trace_dump_struct_end(); /* anonymous */ + trace_dump_member_end(); /* u */ + + trace_dump_struct_end(); +} + + +void trace_dump_draw_info(const struct pipe_draw_info *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_draw_info"); + + trace_dump_member(uint, state, index_size); + trace_dump_member(uint, state, has_user_indices); + + trace_dump_member(uint, state, mode); + trace_dump_member(uint, state, start); + trace_dump_member(uint, state, count); + + trace_dump_member(uint, state, start_instance); + trace_dump_member(uint, state, instance_count); + + trace_dump_member(uint, state, vertices_per_patch); + + trace_dump_member(int, state, index_bias); + trace_dump_member(uint, state, min_index); + trace_dump_member(uint, state, max_index); + + trace_dump_member(bool, state, primitive_restart); + trace_dump_member(uint, state, restart_index); + + trace_dump_member(ptr, state, index.resource); + trace_dump_member(ptr, state, count_from_stream_output); + + if (!state->indirect) { + trace_dump_member(ptr, state, indirect); + } else { + trace_dump_member(uint, state, indirect->offset); + trace_dump_member(uint, state, indirect->stride); + trace_dump_member(uint, state, indirect->draw_count); + trace_dump_member(uint, state, indirect->indirect_draw_count_offset); + trace_dump_member(ptr, state, indirect->buffer); + trace_dump_member(ptr, state, indirect->indirect_draw_count); + } + + trace_dump_struct_end(); +} + +void trace_dump_blit_info(const struct pipe_blit_info *info) +{ + char mask[7]; + + if (!trace_dumping_enabled_locked()) + return; + + if (!info) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_blit_info"); + + trace_dump_member_begin("dst"); + trace_dump_struct_begin("dst"); + trace_dump_member(ptr, &info->dst, resource); + trace_dump_member(uint, &info->dst, level); + trace_dump_member(format, &info->dst, format); + trace_dump_member_begin("box"); + trace_dump_box(&info->dst.box); + trace_dump_member_end(); + trace_dump_struct_end(); + trace_dump_member_end(); + + trace_dump_member_begin("src"); + trace_dump_struct_begin("src"); + trace_dump_member(ptr, &info->src, resource); + trace_dump_member(uint, &info->src, level); + trace_dump_member(format, &info->src, format); + trace_dump_member_begin("box"); + trace_dump_box(&info->src.box); + trace_dump_member_end(); + trace_dump_struct_end(); + trace_dump_member_end(); + + mask[0] = (info->mask & PIPE_MASK_R) ? 'R' : '-'; + mask[1] = (info->mask & PIPE_MASK_G) ? 'G' : '-'; + mask[2] = (info->mask & PIPE_MASK_B) ? 'B' : '-'; + mask[3] = (info->mask & PIPE_MASK_A) ? 'A' : '-'; + mask[4] = (info->mask & PIPE_MASK_Z) ? 'Z' : '-'; + mask[5] = (info->mask & PIPE_MASK_S) ? 'S' : '-'; + mask[6] = 0; + + trace_dump_member_begin("mask"); + trace_dump_string(mask); + trace_dump_member_end(); + trace_dump_member(uint, info, filter); + + trace_dump_member(bool, info, scissor_enable); + trace_dump_member_begin("scissor"); + trace_dump_scissor_state(&info->scissor); + trace_dump_member_end(); + + trace_dump_struct_end(); +} + +void +trace_dump_query_result(unsigned query_type, + const union pipe_query_result *result) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!result) { + trace_dump_null(); + return; + } + + switch (query_type) { + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: + case PIPE_QUERY_GPU_FINISHED: + trace_dump_bool(result->b); + break; + + case PIPE_QUERY_OCCLUSION_COUNTER: + case PIPE_QUERY_TIMESTAMP: + case PIPE_QUERY_TIME_ELAPSED: + case PIPE_QUERY_PRIMITIVES_GENERATED: + case PIPE_QUERY_PRIMITIVES_EMITTED: + trace_dump_uint(result->u64); + break; + + case PIPE_QUERY_SO_STATISTICS: + trace_dump_struct_begin("pipe_query_data_so_statistics"); + trace_dump_member(uint, &result->so_statistics, num_primitives_written); + trace_dump_member(uint, &result->so_statistics, primitives_storage_needed); + trace_dump_struct_end(); + break; + + case PIPE_QUERY_TIMESTAMP_DISJOINT: + trace_dump_struct_begin("pipe_query_data_timestamp_disjoint"); + trace_dump_member(uint, &result->timestamp_disjoint, frequency); + trace_dump_member(bool, &result->timestamp_disjoint, disjoint); + trace_dump_struct_end(); + break; + + case PIPE_QUERY_PIPELINE_STATISTICS: + trace_dump_struct_begin("pipe_query_data_pipeline_statistics"); + trace_dump_member(uint, &result->pipeline_statistics, ia_vertices); + trace_dump_member(uint, &result->pipeline_statistics, ia_primitives); + trace_dump_member(uint, &result->pipeline_statistics, vs_invocations); + trace_dump_member(uint, &result->pipeline_statistics, gs_invocations); + trace_dump_member(uint, &result->pipeline_statistics, gs_primitives); + trace_dump_member(uint, &result->pipeline_statistics, c_invocations); + trace_dump_member(uint, &result->pipeline_statistics, c_primitives); + trace_dump_member(uint, &result->pipeline_statistics, ps_invocations); + trace_dump_member(uint, &result->pipeline_statistics, hs_invocations); + trace_dump_member(uint, &result->pipeline_statistics, ds_invocations); + trace_dump_member(uint, &result->pipeline_statistics, cs_invocations); + trace_dump_struct_end(); + break; + + default: + assert(query_type >= PIPE_QUERY_DRIVER_SPECIFIC); + trace_dump_uint(result->u64); + break; + } +} + +void trace_dump_grid_info(const struct pipe_grid_info *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_grid_info"); + + trace_dump_member(uint, state, pc); + trace_dump_member(ptr, state, input); + + trace_dump_member_begin("block"); + trace_dump_array(uint, state->block, ARRAY_SIZE(state->block)); + trace_dump_member_end(); + + trace_dump_member_begin("grid"); + trace_dump_array(uint, state->grid, ARRAY_SIZE(state->grid)); + trace_dump_member_end(); + + trace_dump_member(ptr, state, indirect); + trace_dump_member(uint, state, indirect_offset); + + trace_dump_struct_end(); +} + diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.h b/src/gallium/auxiliary/driver_trace/tr_dump_state.h new file mode 100644 index 00000000000..baff0252f9b --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.h @@ -0,0 +1,94 @@ +/************************************************************************** + * + * Copyright 2008 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 TR_DUMP_STATE_H_ +#define TR_DUMP_STATE_H_ + +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" + + +void trace_dump_resource_template(const struct pipe_resource *templat); + +void trace_dump_box(const struct pipe_box *box); + +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); + +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state); + +void trace_dump_viewport_state(const struct pipe_viewport_state *state); + +void trace_dump_scissor_state(const struct pipe_scissor_state *state); + +void trace_dump_clip_state(const struct pipe_clip_state *state); + +void trace_dump_token(const struct tgsi_token *token); + +void trace_dump_shader_state(const struct pipe_shader_state *state); + +void trace_dump_compute_state(const struct pipe_compute_state *state); + +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state); + +void trace_dump_blend_state(const struct pipe_blend_state *state); + +void trace_dump_blend_color(const struct pipe_blend_color *state); + +void trace_dump_stencil_ref(const struct pipe_stencil_ref *state); + +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); + +void trace_dump_sampler_state(const struct pipe_sampler_state *state); + +void trace_dump_sampler_view_template(const struct pipe_sampler_view *view, + enum pipe_texture_target target); + +void trace_dump_surface_template(const struct pipe_surface *state, + enum pipe_texture_target target); + +void trace_dump_transfer(const struct pipe_transfer *state); + +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); + +void trace_dump_vertex_element(const struct pipe_vertex_element *state); + +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); + +void trace_dump_shader_buffer(const struct pipe_shader_buffer *buffer); + +void trace_dump_draw_info(const struct pipe_draw_info *state); + +void trace_dump_blit_info(const struct pipe_blit_info *); + +void trace_dump_query_result(unsigned query_type, + const union pipe_query_result *result); + +void trace_dump_grid_info(const struct pipe_grid_info *state); + +void trace_dump_image_view(const struct pipe_image_view *view); + +#endif /* TR_STATE_H */ diff --git a/src/gallium/auxiliary/driver_trace/tr_public.h b/src/gallium/auxiliary/driver_trace/tr_public.h new file mode 100644 index 00000000000..b03133f8d97 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_public.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +#ifndef TR_PUBLIC_H +#define TR_PUBLIC_H + +#include "pipe/p_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen); + +boolean +trace_enabled(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TR_PUBLIC_H */ diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c new file mode 100644 index 00000000000..d5a81249b51 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_screen.c @@ -0,0 +1,684 @@ +/************************************************************************** + * + * Copyright 2008 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_format.h" +#include "util/u_memory.h" +#include "util/simple_list.h" + +#include "tr_dump.h" +#include "tr_dump_defines.h" +#include "tr_dump_state.h" +#include "tr_texture.h" +#include "tr_context.h" +#include "tr_screen.h" +#include "tr_public.h" + + +static boolean trace = FALSE; + +static const char * +trace_screen_get_name(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin("pipe_screen", "get_name"); + + trace_dump_arg(ptr, screen); + + result = screen->get_name(screen); + + trace_dump_ret(string, result); + + trace_dump_call_end(); + + return result; +} + + +static const char * +trace_screen_get_vendor(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin("pipe_screen", "get_vendor"); + + trace_dump_arg(ptr, screen); + + result = screen->get_vendor(screen); + + trace_dump_ret(string, result); + + trace_dump_call_end(); + + return result; +} + + +static const char * +trace_screen_get_device_vendor(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin("pipe_screen", "get_device_vendor"); + + trace_dump_arg(ptr, screen); + + result = screen->get_device_vendor(screen); + + trace_dump_ret(string, result); + + trace_dump_call_end(); + + return result; +} + + +static struct disk_cache * +trace_screen_get_disk_shader_cache(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin("pipe_screen", "get_disk_shader_cache"); + + trace_dump_arg(ptr, screen); + + struct disk_cache *result = screen->get_disk_shader_cache(screen); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + return result; +} + + +static int +trace_screen_get_param(struct pipe_screen *_screen, + enum pipe_cap param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + int result; + + trace_dump_call_begin("pipe_screen", "get_param"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(int, param); + + result = screen->get_param(screen, param); + + trace_dump_ret(int, result); + + trace_dump_call_end(); + + return result; +} + + +static int +trace_screen_get_shader_param(struct pipe_screen *_screen, + enum pipe_shader_type shader, + enum pipe_shader_cap param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + int result; + + trace_dump_call_begin("pipe_screen", "get_shader_param"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(uint, shader); + trace_dump_arg(int, param); + + result = screen->get_shader_param(screen, shader, param); + + trace_dump_ret(int, result); + + trace_dump_call_end(); + + return result; +} + + +static float +trace_screen_get_paramf(struct pipe_screen *_screen, + enum pipe_capf param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + float result; + + trace_dump_call_begin("pipe_screen", "get_paramf"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(int, param); + + result = screen->get_paramf(screen, param); + + trace_dump_ret(float, result); + + trace_dump_call_end(); + + return result; +} + + +static int +trace_screen_get_compute_param(struct pipe_screen *_screen, + enum pipe_shader_ir ir_type, + enum pipe_compute_cap param, void *data) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + int result; + + trace_dump_call_begin("pipe_screen", "get_compute_param"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(int, ir_type); + trace_dump_arg(int, param); + trace_dump_arg(ptr, data); + + result = screen->get_compute_param(screen, ir_type, param, data); + + trace_dump_ret(int, result); + + trace_dump_call_end(); + + return result; +} + + +static boolean +trace_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned tex_usage) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + boolean result; + + trace_dump_call_begin("pipe_screen", "is_format_supported"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(format, format); + trace_dump_arg(int, target); + trace_dump_arg(uint, sample_count); + trace_dump_arg(uint, tex_usage); + + result = screen->is_format_supported(screen, format, target, sample_count, + tex_usage); + + trace_dump_ret(bool, result); + + trace_dump_call_end(); + + return result; +} + + +static struct pipe_context * +trace_screen_context_create(struct pipe_screen *_screen, void *priv, + unsigned flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + struct pipe_context *result; + + trace_dump_call_begin("pipe_screen", "context_create"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, priv); + trace_dump_arg(uint, flags); + + result = screen->context_create(screen, priv, flags); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + result = trace_context_create(tr_scr, result); + + return result; +} + + +static void +trace_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned level, unsigned layer, + void *context_private, + struct pipe_box *sub_box) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin("pipe_screen", "flush_frontbuffer"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, resource); + trace_dump_arg(uint, level); + trace_dump_arg(uint, layer); + /* XXX: hide, as there is nothing we can do with this + trace_dump_arg(ptr, context_private); + */ + + screen->flush_frontbuffer(screen, resource, level, layer, context_private, sub_box); + + trace_dump_call_end(); +} + + +static void +trace_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "get_driver_uuid"); + trace_dump_arg(ptr, screen); + + screen->get_driver_uuid(screen, uuid); + + trace_dump_ret(string, uuid); + trace_dump_call_end(); +} + +static void +trace_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "get_device_uuid"); + trace_dump_arg(ptr, screen); + + screen->get_device_uuid(screen, uuid); + + trace_dump_ret(string, uuid); + trace_dump_call_end(); +} + + +/******************************************************************** + * texture + */ + + +static struct pipe_resource * +trace_screen_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + struct pipe_resource *result; + + trace_dump_call_begin("pipe_screen", "resource_create"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(resource_template, templat); + + result = screen->resource_create(screen, templat); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + if (result) + result->screen = _screen; + return result; +} + +static struct pipe_resource * +trace_screen_resource_from_handle(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct winsys_handle *handle, + unsigned usage) +{ + struct trace_screen *tr_screen = trace_screen(_screen); + struct pipe_screen *screen = tr_screen->screen; + struct pipe_resource *result; + + /* TODO trace call */ + + result = screen->resource_from_handle(screen, templ, handle, usage); + + if (result) + result->screen = _screen; + return result; +} + +static bool +trace_screen_check_resource_capability(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned bind) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + return screen->check_resource_capability(screen, resource, bind); +} + +static boolean +trace_screen_resource_get_handle(struct pipe_screen *_screen, + struct pipe_context *_pipe, + struct pipe_resource *resource, + struct winsys_handle *handle, + unsigned usage) +{ + struct trace_screen *tr_screen = trace_screen(_screen); + struct trace_context *tr_pipe = _pipe ? trace_context(_pipe) : NULL; + struct pipe_screen *screen = tr_screen->screen; + + /* TODO trace call */ + + return screen->resource_get_handle(screen, tr_pipe ? tr_pipe->pipe : NULL, + resource, handle, usage); +} + +static struct pipe_resource * +trace_screen_resource_from_memobj(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "resource_from_memobj"); + trace_dump_arg(ptr, screen); + trace_dump_arg(resource_template, templ); + trace_dump_arg(ptr, memobj); + trace_dump_arg(uint, offset); + + struct pipe_resource *res = + screen->resource_from_memobj(screen, templ, memobj, offset); + + if (!res) + return NULL; + res->screen = _screen; + + trace_dump_ret(ptr, res); + trace_dump_call_end(); + return res; +} + +static void +trace_screen_resource_changed(struct pipe_screen *_screen, + struct pipe_resource *resource) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin("pipe_screen", "resource_changed"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, resource); + + screen->resource_changed(screen, resource); + + trace_dump_call_end(); +} + +static void +trace_screen_resource_destroy(struct pipe_screen *_screen, + struct pipe_resource *resource) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + + /* Don't trace this, because due to the lack of pipe_resource wrapping, + * we can get this call from inside of driver calls, which would try + * to lock an already-locked mutex. + */ + screen->resource_destroy(screen, resource); +} + + +/******************************************************************** + * fence + */ + + +static void +trace_screen_fence_reference(struct pipe_screen *_screen, + struct pipe_fence_handle **pdst, + struct pipe_fence_handle *src) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + struct pipe_fence_handle *dst; + + assert(pdst); + dst = *pdst; + + trace_dump_call_begin("pipe_screen", "fence_reference"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, dst); + trace_dump_arg(ptr, src); + + screen->fence_reference(screen, pdst, src); + + trace_dump_call_end(); +} + + +static boolean +trace_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_context *_ctx, + struct pipe_fence_handle *fence, + uint64_t timeout) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + struct pipe_context *ctx = _ctx ? trace_context(_ctx)->pipe : NULL; + int result; + + trace_dump_call_begin("pipe_screen", "fence_finish"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, ctx); + trace_dump_arg(ptr, fence); + trace_dump_arg(uint, timeout); + + result = screen->fence_finish(screen, ctx, fence, timeout); + + trace_dump_ret(bool, result); + + trace_dump_call_end(); + + return result; +} + + +/******************************************************************** + * memobj + */ + +static struct pipe_memory_object * +trace_screen_memobj_create_from_handle(struct pipe_screen *_screen, + struct winsys_handle *handle, + bool dedicated) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "memobj_create_from_handle"); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, handle); + trace_dump_arg(bool, dedicated); + + struct pipe_memory_object *res = + screen->memobj_create_from_handle(screen, handle, dedicated); + + trace_dump_ret(ptr, res); + trace_dump_call_end(); + + return res; +} + +static void +trace_screen_memobj_destroy(struct pipe_screen *_screen, + struct pipe_memory_object *memobj) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "memobj_destroy"); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, memobj); + trace_dump_call_end(); + + screen->memobj_destroy(screen, memobj); +} + + +/******************************************************************** + * screen + */ + +static uint64_t +trace_screen_get_timestamp(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + uint64_t result; + + trace_dump_call_begin("pipe_screen", "get_timestamp"); + trace_dump_arg(ptr, screen); + + result = screen->get_timestamp(screen); + + trace_dump_ret(uint, result); + trace_dump_call_end(); + + return result; +} + +static void +trace_screen_destroy(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin("pipe_screen", "destroy"); + trace_dump_arg(ptr, screen); + trace_dump_call_end(); + + screen->destroy(screen); + + FREE(tr_scr); +} + +boolean +trace_enabled(void) +{ + static boolean firstrun = TRUE; + + if (!firstrun) + return trace; + firstrun = FALSE; + + if(trace_dump_trace_begin()) { + trace_dumping_start(); + trace = TRUE; + } + + return trace; +} + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen) +{ + struct trace_screen *tr_scr; + + if (!trace_enabled()) + goto error1; + + trace_dump_call_begin("", "pipe_screen_create"); + + tr_scr = CALLOC_STRUCT(trace_screen); + if (!tr_scr) + goto error2; + +#define SCR_INIT(_member) \ + tr_scr->base._member = screen->_member ? trace_screen_##_member : NULL + + tr_scr->base.destroy = trace_screen_destroy; + tr_scr->base.get_name = trace_screen_get_name; + tr_scr->base.get_vendor = trace_screen_get_vendor; + tr_scr->base.get_device_vendor = trace_screen_get_device_vendor; + SCR_INIT(get_disk_shader_cache); + tr_scr->base.get_param = trace_screen_get_param; + tr_scr->base.get_shader_param = trace_screen_get_shader_param; + tr_scr->base.get_paramf = trace_screen_get_paramf; + tr_scr->base.get_compute_param = trace_screen_get_compute_param; + tr_scr->base.is_format_supported = trace_screen_is_format_supported; + assert(screen->context_create); + tr_scr->base.context_create = trace_screen_context_create; + tr_scr->base.resource_create = trace_screen_resource_create; + tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; + SCR_INIT(check_resource_capability); + tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; + SCR_INIT(resource_from_memobj); + SCR_INIT(resource_changed); + tr_scr->base.resource_destroy = trace_screen_resource_destroy; + tr_scr->base.fence_reference = trace_screen_fence_reference; + tr_scr->base.fence_finish = trace_screen_fence_finish; + SCR_INIT(memobj_create_from_handle); + SCR_INIT(memobj_destroy); + tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; + tr_scr->base.get_timestamp = trace_screen_get_timestamp; + SCR_INIT(get_driver_uuid); + SCR_INIT(get_device_uuid); + + tr_scr->screen = screen; + + trace_dump_ret(ptr, screen); + trace_dump_call_end(); + + return &tr_scr->base; + +error2: + trace_dump_ret(ptr, screen); + trace_dump_call_end(); +error1: + return screen; +} + + +struct trace_screen * +trace_screen(struct pipe_screen *screen) +{ + assert(screen); + assert(screen->destroy == trace_screen_destroy); + return (struct trace_screen *)screen; +} diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.h b/src/gallium/auxiliary/driver_trace/tr_screen.h new file mode 100644 index 00000000000..65ea4fb6a43 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_screen.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2008 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 TR_SCREEN_H_ +#define TR_SCREEN_H_ + + +#include "pipe/p_screen.h" +#include "os/os_thread.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * It often happens that new data is written directly to the user buffers + * without mapping/unmapping. This flag marks user buffers, so that their + * contents can be dumped before being used by the pipe context. + */ +#define TRACE_FLAG_USER_BUFFER (1 << 31) + + +struct trace_screen +{ + struct pipe_screen base; + + struct pipe_screen *screen; +}; + + +struct trace_screen * +trace_screen(struct pipe_screen *screen); + + +#ifdef __cplusplus +} +#endif + +#endif /* TR_SCREEN_H_ */ diff --git a/src/gallium/auxiliary/driver_trace/tr_texture.c b/src/gallium/auxiliary/driver_trace/tr_texture.c new file mode 100644 index 00000000000..fe0c7b52c9b --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_texture.c @@ -0,0 +1,119 @@ +/************************************************************************** + * + * Copyright 2008 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_hash_table.h" +#include "util/u_memory.h" +#include "util/simple_list.h" + +#include "tr_screen.h" +#include "tr_context.h" +#include "tr_texture.h" + + +struct pipe_surface * +trace_surf_create(struct trace_context *tr_ctx, + struct pipe_resource *res, + struct pipe_surface *surface) +{ + struct trace_surface *tr_surf; + + if (!surface) + goto error; + + assert(surface->texture == res); + + tr_surf = CALLOC_STRUCT(trace_surface); + if (!tr_surf) + goto error; + + memcpy(&tr_surf->base, surface, sizeof(struct pipe_surface)); + tr_surf->base.context = &tr_ctx->base; + + pipe_reference_init(&tr_surf->base.reference, 1); + tr_surf->base.texture = NULL; + pipe_resource_reference(&tr_surf->base.texture, res); + tr_surf->surface = surface; + + return &tr_surf->base; + +error: + pipe_surface_reference(&surface, NULL); + return NULL; +} + + +void +trace_surf_destroy(struct trace_surface *tr_surf) +{ + trace_context_check(tr_surf->base.context); + pipe_resource_reference(&tr_surf->base.texture, NULL); + pipe_surface_reference(&tr_surf->surface, NULL); + FREE(tr_surf); +} + + +struct pipe_transfer * +trace_transfer_create(struct trace_context *tr_ctx, + struct pipe_resource *res, + struct pipe_transfer *transfer) +{ + struct trace_transfer *tr_trans; + + if (!transfer) + goto error; + + assert(transfer->resource == res); + + tr_trans = CALLOC_STRUCT(trace_transfer); + if (!tr_trans) + goto error; + + memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer)); + + tr_trans->base.resource = NULL; + tr_trans->transfer = transfer; + + pipe_resource_reference(&tr_trans->base.resource, res); + assert(tr_trans->base.resource == res); + + return &tr_trans->base; + +error: + tr_ctx->pipe->transfer_unmap(tr_ctx->pipe, transfer); + return NULL; +} + + +void +trace_transfer_destroy(struct trace_context *tr_context, + struct trace_transfer *tr_trans) +{ + pipe_resource_reference(&tr_trans->base.resource, NULL); + FREE(tr_trans); +} + diff --git a/src/gallium/auxiliary/driver_trace/tr_texture.h b/src/gallium/auxiliary/driver_trace/tr_texture.h new file mode 100644 index 00000000000..e5dfc53fdb0 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/tr_texture.h @@ -0,0 +1,122 @@ +/************************************************************************** + * + * Copyright 2008 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 TR_TEXTURE_H_ +#define TR_TEXTURE_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "tr_screen.h" + +struct trace_context; + + +struct tr_list +{ + struct tr_list *next; + struct tr_list *prev; +}; + +struct trace_surface +{ + struct pipe_surface base; + + struct pipe_surface *surface; + + struct tr_list list; +}; + + +struct trace_sampler_view +{ + struct pipe_sampler_view base; + + struct pipe_sampler_view *sampler_view; +}; + + +struct trace_transfer +{ + struct pipe_transfer base; + + struct pipe_transfer *transfer; + struct pipe_context *pipe; + + struct tr_list list; + + void *map; +}; + + +static inline struct trace_surface * +trace_surface(struct pipe_surface *surface) +{ + if (!surface) + return NULL; + return (struct trace_surface *)surface; +} + + +static inline struct trace_sampler_view * +trace_sampler_view(struct pipe_sampler_view *sampler_view) +{ + if (!sampler_view) + return NULL; + return (struct trace_sampler_view *)sampler_view; +} + + +static inline struct trace_transfer * +trace_transfer(struct pipe_transfer *transfer) +{ + if (!transfer) + return NULL; + return (struct trace_transfer *)transfer; +} + + +struct pipe_surface * +trace_surf_create(struct trace_context *tr_ctx, + struct pipe_resource *tr_res, + struct pipe_surface *surface); + +void +trace_surf_destroy(struct trace_surface *tr_surf); + +struct pipe_transfer * +trace_transfer_create(struct trace_context *tr_ctx, + struct pipe_resource *tr_res, + struct pipe_transfer *transfer); + +void +trace_transfer_destroy(struct trace_context *tr_ctx, + struct trace_transfer *tr_trans); + + +#endif /* TR_TEXTURE_H_ */ diff --git a/src/gallium/auxiliary/driver_trace/trace.xsl b/src/gallium/auxiliary/driver_trace/trace.xsl new file mode 100644 index 00000000000..12458ae3287 --- /dev/null +++ b/src/gallium/auxiliary/driver_trace/trace.xsl @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + Gallium Trace + + + +
    + +
+ + +
+ + +
  • + + + + + + :: + + + ( + + ) + +
  • +
    + + + + = + + + , + + + + + = + + + + + + + + + + + + ... + + + + + + " + + + + " + + + + + { + + } + + + + + + , + + + + + + NULL + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + +
    diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 53c85046ed4..92cfb8f7af5 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -77,6 +77,35 @@ files_libgallium = files( 'draw/draw_vs_exec.c', 'draw/draw_vs.h', 'draw/draw_vs_variant.c', + 'driver_ddebug/dd_context.c', + 'driver_ddebug/dd_draw.c', + 'driver_ddebug/dd_pipe.h', + 'driver_ddebug/dd_public.h', + 'driver_ddebug/dd_screen.c', + 'driver_ddebug/dd_util.h', + 'driver_noop/noop_pipe.c', + 'driver_noop/noop_public.h', + 'driver_noop/noop_state.c', + 'driver_rbug/rbug_context.c', + 'driver_rbug/rbug_context.h', + 'driver_rbug/rbug_core.c', + 'driver_rbug/rbug_objects.c', + 'driver_rbug/rbug_objects.h', + 'driver_rbug/rbug_public.h', + 'driver_rbug/rbug_screen.c', + 'driver_rbug/rbug_screen.h', + 'driver_trace/tr_context.c', + 'driver_trace/tr_context.h', + 'driver_trace/tr_dump.c', + 'driver_trace/tr_dump_defines.h', + 'driver_trace/tr_dump.h', + 'driver_trace/tr_dump_state.c', + 'driver_trace/tr_dump_state.h', + 'driver_trace/tr_public.h', + 'driver_trace/tr_screen.c', + 'driver_trace/tr_screen.h', + 'driver_trace/tr_texture.c', + 'driver_trace/tr_texture.h', 'hud/font.c', 'hud/font.h', 'hud/hud_context.c', diff --git a/src/gallium/auxiliary/rbug/README b/src/gallium/auxiliary/rbug/README index c5156438a1b..0c41c8c3fa1 100644 --- a/src/gallium/auxiliary/rbug/README +++ b/src/gallium/auxiliary/rbug/README @@ -10,7 +10,7 @@ The code currently uses tcp and ip4v for connections. Information about driver integration can be found in: -src/gallium/drivers/rbug/README +src/gallium/auxiliary/driver_rbug/README for information about applications look in: diff --git a/src/gallium/auxiliary/target-helpers/inline_debug_helper.h b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h index 2443bf21468..66d46de888b 100644 --- a/src/gallium/auxiliary/target-helpers/inline_debug_helper.h +++ b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h @@ -8,24 +8,13 @@ /* Helper function to wrap a screen with - * one or more debug driver: rbug, trace. + * one or more debug drivers. */ -#ifdef GALLIUM_DDEBUG -#include "ddebug/dd_public.h" -#endif - -#ifdef GALLIUM_TRACE -#include "trace/tr_public.h" -#endif - -#ifdef GALLIUM_RBUG -#include "rbug/rbug_public.h" -#endif - -#ifdef GALLIUM_NOOP -#include "noop/noop_public.h" -#endif +#include "driver_ddebug/dd_public.h" +#include "driver_trace/tr_public.h" +#include "driver_rbug/rbug_public.h" +#include "driver_noop/noop_public.h" /* * TODO: Audit the following *screen_create() - all of @@ -34,21 +23,10 @@ static inline struct pipe_screen * debug_screen_wrap(struct pipe_screen *screen) { -#if defined(GALLIUM_DDEBUG) screen = ddebug_screen_create(screen); -#endif - -#if defined(GALLIUM_RBUG) screen = rbug_screen_create(screen); -#endif - -#if defined(GALLIUM_TRACE) screen = trace_screen_create(screen); -#endif - -#if defined(GALLIUM_NOOP) screen = noop_screen_create(screen); -#endif if (debug_get_bool_option("GALLIUM_TESTS", FALSE)) util_run_tests(screen); diff --git a/src/gallium/drivers/ddebug/Makefile.am b/src/gallium/drivers/ddebug/Makefile.am deleted file mode 100644 index b36ea239afc..00000000000 --- a/src/gallium/drivers/ddebug/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -include Makefile.sources -include $(top_srcdir)/src/gallium/Automake.inc - -AM_CFLAGS = \ - $(GALLIUM_DRIVER_CFLAGS) - -noinst_LTLIBRARIES = libddebug.la - -libddebug_la_SOURCES = $(C_SOURCES) - -EXTRA_DIST = meson.build diff --git a/src/gallium/drivers/ddebug/Makefile.sources b/src/gallium/drivers/ddebug/Makefile.sources deleted file mode 100644 index 1bd38274df8..00000000000 --- a/src/gallium/drivers/ddebug/Makefile.sources +++ /dev/null @@ -1,7 +0,0 @@ -C_SOURCES := \ - dd_context.c \ - dd_draw.c \ - dd_pipe.h \ - dd_public.h \ - dd_screen.c \ - dd_util.h diff --git a/src/gallium/drivers/ddebug/dd_context.c b/src/gallium/drivers/ddebug/dd_context.c deleted file mode 100644 index dd7b3e086cd..00000000000 --- a/src/gallium/drivers/ddebug/dd_context.c +++ /dev/null @@ -1,877 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * Copyright 2008 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 "dd_pipe.h" -#include "tgsi/tgsi_parse.h" -#include "util/u_inlines.h" -#include "util/u_memory.h" - - -static void -safe_memcpy(void *dst, const void *src, size_t size) -{ - if (src) - memcpy(dst, src, size); - else - memset(dst, 0, size); -} - - -/******************************************************************** - * queries - */ - -static struct pipe_query * -dd_context_create_query(struct pipe_context *_pipe, unsigned query_type, - unsigned index) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct pipe_query *query; - - query = pipe->create_query(pipe, query_type, index); - - /* Wrap query object. */ - if (query) { - struct dd_query *dd_query = CALLOC_STRUCT(dd_query); - if (dd_query) { - dd_query->type = query_type; - dd_query->query = query; - query = (struct pipe_query *)dd_query; - } else { - pipe->destroy_query(pipe, query); - query = NULL; - } - } - - return query; -} - -static struct pipe_query * -dd_context_create_batch_query(struct pipe_context *_pipe, unsigned num_queries, - unsigned *query_types) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct pipe_query *query; - - query = pipe->create_batch_query(pipe, num_queries, query_types); - - /* Wrap query object. */ - if (query) { - struct dd_query *dd_query = CALLOC_STRUCT(dd_query); - if (dd_query) { - /* no special handling for batch queries yet */ - dd_query->type = query_types[0]; - dd_query->query = query; - query = (struct pipe_query *)dd_query; - } else { - pipe->destroy_query(pipe, query); - query = NULL; - } - } - - return query; -} - -static void -dd_context_destroy_query(struct pipe_context *_pipe, - struct pipe_query *query) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->destroy_query(pipe, dd_query_unwrap(query)); - FREE(query); -} - -static boolean -dd_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - return pipe->begin_query(pipe, dd_query_unwrap(query)); -} - -static bool -dd_context_end_query(struct pipe_context *_pipe, struct pipe_query *query) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - return pipe->end_query(pipe, dd_query_unwrap(query)); -} - -static boolean -dd_context_get_query_result(struct pipe_context *_pipe, - struct pipe_query *query, boolean wait, - union pipe_query_result *result) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, result); -} - -static void -dd_context_set_active_query_state(struct pipe_context *_pipe, boolean enable) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->set_active_query_state(pipe, enable); -} - -static void -dd_context_render_condition(struct pipe_context *_pipe, - struct pipe_query *query, boolean condition, - enum pipe_render_cond_flag mode) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_state *dstate = &dctx->draw_state; - - pipe->render_condition(pipe, dd_query_unwrap(query), condition, mode); - dstate->render_cond.query = dd_query(query); - dstate->render_cond.condition = condition; - dstate->render_cond.mode = mode; -} - - -/******************************************************************** - * constant (immutable) non-shader states - */ - -#define DD_CSO_CREATE(name, shortname) \ - static void * \ - dd_context_create_##name##_state(struct pipe_context *_pipe, \ - const struct pipe_##name##_state *state) \ - { \ - struct pipe_context *pipe = dd_context(_pipe)->pipe; \ - struct dd_state *hstate = CALLOC_STRUCT(dd_state); \ - \ - if (!hstate) \ - return NULL; \ - hstate->cso = pipe->create_##name##_state(pipe, state); \ - hstate->state.shortname = *state; \ - return hstate; \ - } - -#define DD_CSO_BIND(name, shortname) \ - static void \ - dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \ - { \ - struct dd_context *dctx = dd_context(_pipe); \ - struct pipe_context *pipe = dctx->pipe; \ - struct dd_state *hstate = state; \ - \ - dctx->draw_state.shortname = hstate; \ - pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \ - } - -#define DD_CSO_DELETE(name) \ - static void \ - dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \ - { \ - struct dd_context *dctx = dd_context(_pipe); \ - struct pipe_context *pipe = dctx->pipe; \ - struct dd_state *hstate = state; \ - \ - pipe->delete_##name##_state(pipe, hstate->cso); \ - FREE(hstate); \ - } - -#define DD_CSO_WHOLE(name, shortname) \ - DD_CSO_CREATE(name, shortname) \ - DD_CSO_BIND(name, shortname) \ - DD_CSO_DELETE(name) - -DD_CSO_WHOLE(blend, blend) -DD_CSO_WHOLE(rasterizer, rs) -DD_CSO_WHOLE(depth_stencil_alpha, dsa) - -DD_CSO_CREATE(sampler, sampler) -DD_CSO_DELETE(sampler) - -static void -dd_context_bind_sampler_states(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, unsigned count, void **states) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - memcpy(&dctx->draw_state.sampler_states[shader][start], states, - sizeof(void*) * count); - - if (states) { - void *samp[PIPE_MAX_SAMPLERS]; - int i; - - for (i = 0; i < count; i++) { - struct dd_state *s = states[i]; - samp[i] = s ? s->cso : NULL; - } - - pipe->bind_sampler_states(pipe, shader, start, count, samp); - } - else - pipe->bind_sampler_states(pipe, shader, start, count, NULL); -} - -static void * -dd_context_create_vertex_elements_state(struct pipe_context *_pipe, - unsigned num_elems, - const struct pipe_vertex_element *elems) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct dd_state *hstate = CALLOC_STRUCT(dd_state); - - if (!hstate) - return NULL; - hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems); - memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems); - hstate->state.velems.count = num_elems; - return hstate; -} - -DD_CSO_BIND(vertex_elements, velems) -DD_CSO_DELETE(vertex_elements) - - -/******************************************************************** - * shaders - */ - -#define DD_SHADER_NOCREATE(NAME, name) \ - static void \ - dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \ - { \ - struct dd_context *dctx = dd_context(_pipe); \ - struct pipe_context *pipe = dctx->pipe; \ - struct dd_state *hstate = state; \ - \ - dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \ - pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \ - } \ - \ - static void \ - dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \ - { \ - struct dd_context *dctx = dd_context(_pipe); \ - struct pipe_context *pipe = dctx->pipe; \ - struct dd_state *hstate = state; \ - \ - pipe->delete_##name##_state(pipe, hstate->cso); \ - if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \ - tgsi_free_tokens(hstate->state.shader.tokens); \ - FREE(hstate); \ - } - -#define DD_SHADER(NAME, name) \ - static void * \ - dd_context_create_##name##_state(struct pipe_context *_pipe, \ - const struct pipe_shader_state *state) \ - { \ - struct pipe_context *pipe = dd_context(_pipe)->pipe; \ - struct dd_state *hstate = CALLOC_STRUCT(dd_state); \ - \ - if (!hstate) \ - return NULL; \ - hstate->cso = pipe->create_##name##_state(pipe, state); \ - hstate->state.shader = *state; \ - if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \ - hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \ - return hstate; \ - } \ - \ - DD_SHADER_NOCREATE(NAME, name) - -DD_SHADER(FRAGMENT, fs) -DD_SHADER(VERTEX, vs) -DD_SHADER(GEOMETRY, gs) -DD_SHADER(TESS_CTRL, tcs) -DD_SHADER(TESS_EVAL, tes) - -static void * \ -dd_context_create_compute_state(struct pipe_context *_pipe, - const struct pipe_compute_state *state) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct dd_state *hstate = CALLOC_STRUCT(dd_state); - - if (!hstate) - return NULL; - hstate->cso = pipe->create_compute_state(pipe, state); - - hstate->state.shader.type = state->ir_type; - - if (state->ir_type == PIPE_SHADER_IR_TGSI) - hstate->state.shader.tokens = tgsi_dup_tokens(state->prog); - - return hstate; -} - -DD_SHADER_NOCREATE(COMPUTE, compute) - -/******************************************************************** - * immediate states - */ - -#define DD_IMM_STATE(name, type, deref, ref) \ - static void \ - dd_context_set_##name(struct pipe_context *_pipe, type deref) \ - { \ - struct dd_context *dctx = dd_context(_pipe); \ - struct pipe_context *pipe = dctx->pipe; \ - \ - dctx->draw_state.name = deref; \ - pipe->set_##name(pipe, ref); \ - } - -DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state) -DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state) -DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state) -DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask) -DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples) -DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state) -DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state) - -static void -dd_context_set_constant_buffer(struct pipe_context *_pipe, - enum pipe_shader_type shader, uint index, - const struct pipe_constant_buffer *constant_buffer) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.constant_buffers[shader][index], - constant_buffer, sizeof(*constant_buffer)); - pipe->set_constant_buffer(pipe, shader, index, constant_buffer); -} - -static void -dd_context_set_scissor_states(struct pipe_context *_pipe, - unsigned start_slot, unsigned num_scissors, - const struct pipe_scissor_state *states) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.scissors[start_slot], states, - sizeof(*states) * num_scissors); - pipe->set_scissor_states(pipe, start_slot, num_scissors, states); -} - -static void -dd_context_set_viewport_states(struct pipe_context *_pipe, - unsigned start_slot, unsigned num_viewports, - const struct pipe_viewport_state *states) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.viewports[start_slot], states, - sizeof(*states) * num_viewports); - pipe->set_viewport_states(pipe, start_slot, num_viewports, states); -} - -static void dd_context_set_tess_state(struct pipe_context *_pipe, - const float default_outer_level[4], - const float default_inner_level[2]) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - memcpy(dctx->draw_state.tess_default_levels, default_outer_level, - sizeof(float) * 4); - memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level, - sizeof(float) * 2); - pipe->set_tess_state(pipe, default_outer_level, default_inner_level); -} - - -/******************************************************************** - * views - */ - -static struct pipe_surface * -dd_context_create_surface(struct pipe_context *_pipe, - struct pipe_resource *resource, - const struct pipe_surface *surf_tmpl) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct pipe_surface *view = - pipe->create_surface(pipe, resource, surf_tmpl); - - if (!view) - return NULL; - view->context = _pipe; - return view; -} - -static void -dd_context_surface_destroy(struct pipe_context *_pipe, - struct pipe_surface *surf) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->surface_destroy(pipe, surf); -} - -static struct pipe_sampler_view * -dd_context_create_sampler_view(struct pipe_context *_pipe, - struct pipe_resource *resource, - const struct pipe_sampler_view *templ) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct pipe_sampler_view *view = - pipe->create_sampler_view(pipe, resource, templ); - - if (!view) - return NULL; - view->context = _pipe; - return view; -} - -static void -dd_context_sampler_view_destroy(struct pipe_context *_pipe, - struct pipe_sampler_view *view) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->sampler_view_destroy(pipe, view); -} - -static struct pipe_stream_output_target * -dd_context_create_stream_output_target(struct pipe_context *_pipe, - struct pipe_resource *res, - unsigned buffer_offset, - unsigned buffer_size) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - struct pipe_stream_output_target *view = - pipe->create_stream_output_target(pipe, res, buffer_offset, - buffer_size); - - if (!view) - return NULL; - view->context = _pipe; - return view; -} - -static void -dd_context_stream_output_target_destroy(struct pipe_context *_pipe, - struct pipe_stream_output_target *target) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->stream_output_target_destroy(pipe, target); -} - - -/******************************************************************** - * set states - */ - -static void -dd_context_set_sampler_views(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, unsigned num, - struct pipe_sampler_view **views) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views, - sizeof(views[0]) * num); - pipe->set_sampler_views(pipe, shader, start, num, views); -} - -static void -dd_context_set_shader_images(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, unsigned num, - const struct pipe_image_view *views) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.shader_images[shader][start], views, - sizeof(views[0]) * num); - pipe->set_shader_images(pipe, shader, start, num, views); -} - -static void -dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader, - unsigned start, unsigned num_buffers, - const struct pipe_shader_buffer *buffers) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers, - sizeof(buffers[0]) * num_buffers); - pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers); -} - -static void -dd_context_set_vertex_buffers(struct pipe_context *_pipe, - unsigned start, unsigned num_buffers, - const struct pipe_vertex_buffer *buffers) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers, - sizeof(buffers[0]) * num_buffers); - pipe->set_vertex_buffers(pipe, start, num_buffers, buffers); -} - -static void -dd_context_set_stream_output_targets(struct pipe_context *_pipe, - unsigned num_targets, - struct pipe_stream_output_target **tgs, - const unsigned *offsets) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_state *dstate = &dctx->draw_state; - - dstate->num_so_targets = num_targets; - safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets); - safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets); - pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets); -} - -void -dd_thread_join(struct dd_context *dctx) -{ - mtx_lock(&dctx->mutex); - dctx->kill_thread = true; - cnd_signal(&dctx->cond); - mtx_unlock(&dctx->mutex); - thrd_join(dctx->thread, NULL); -} - -static void -dd_context_destroy(struct pipe_context *_pipe) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - dd_thread_join(dctx); - mtx_destroy(&dctx->mutex); - cnd_destroy(&dctx->cond); - - assert(list_empty(&dctx->records)); - assert(!dctx->record_pending); - - if (pipe->set_log_context) { - pipe->set_log_context(pipe, NULL); - - if (dd_screen(dctx->base.screen)->dump_mode == DD_DUMP_ALL_CALLS) { - FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen), 0); - if (f) { - fprintf(f, "Remainder of driver log:\n\n"); - } - - u_log_new_page_print(&dctx->log, f); - fclose(f); - } - } - u_log_context_destroy(&dctx->log); - - pipe->destroy(pipe); - FREE(dctx); -} - - -/******************************************************************** - * miscellaneous - */ - -static void -dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->texture_barrier(pipe, flags); -} - -static void -dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->memory_barrier(pipe, flags); -} - -static bool -dd_context_resource_commit(struct pipe_context *_pipe, - struct pipe_resource *resource, - unsigned level, struct pipe_box *box, bool commit) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->resource_commit(pipe, resource, level, box, commit); -} - -static void -dd_context_get_sample_position(struct pipe_context *_pipe, - unsigned sample_count, unsigned sample_index, - float *out_value) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->get_sample_position(pipe, sample_count, sample_index, - out_value); -} - -static void -dd_context_invalidate_resource(struct pipe_context *_pipe, - struct pipe_resource *resource) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->invalidate_resource(pipe, resource); -} - -static enum pipe_reset_status -dd_context_get_device_reset_status(struct pipe_context *_pipe) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->get_device_reset_status(pipe); -} - -static void -dd_context_set_device_reset_callback(struct pipe_context *_pipe, - const struct pipe_device_reset_callback *cb) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->set_device_reset_callback(pipe, cb); -} - -static void -dd_context_emit_string_marker(struct pipe_context *_pipe, - const char *string, int len) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - pipe->emit_string_marker(pipe, string, len); - dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number); -} - -static void -dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream, - unsigned flags) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->dump_debug_state(pipe, stream, flags); -} - -static uint64_t -dd_context_create_texture_handle(struct pipe_context *_pipe, - struct pipe_sampler_view *view, - const struct pipe_sampler_state *state) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->create_texture_handle(pipe, view, state); -} - -static void -dd_context_delete_texture_handle(struct pipe_context *_pipe, uint64_t handle) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->delete_texture_handle(pipe, handle); -} - -static void -dd_context_make_texture_handle_resident(struct pipe_context *_pipe, - uint64_t handle, bool resident) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->make_texture_handle_resident(pipe, handle, resident); -} - -static uint64_t -dd_context_create_image_handle(struct pipe_context *_pipe, - const struct pipe_image_view *image) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - return pipe->create_image_handle(pipe, image); -} - -static void -dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->delete_image_handle(pipe, handle); -} - -static void -dd_context_make_image_handle_resident(struct pipe_context *_pipe, - uint64_t handle, unsigned access, - bool resident) -{ - struct pipe_context *pipe = dd_context(_pipe)->pipe; - - pipe->make_image_handle_resident(pipe, handle, access, resident); -} - -struct pipe_context * -dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe) -{ - struct dd_context *dctx; - - if (!pipe) - return NULL; - - dctx = CALLOC_STRUCT(dd_context); - if (!dctx) - goto fail; - - dctx->pipe = pipe; - dctx->base.priv = pipe->priv; /* expose wrapped priv data */ - dctx->base.screen = &dscreen->base; - dctx->base.stream_uploader = pipe->stream_uploader; - dctx->base.const_uploader = pipe->const_uploader; - - dctx->base.destroy = dd_context_destroy; - - CTX_INIT(render_condition); - CTX_INIT(create_query); - CTX_INIT(create_batch_query); - CTX_INIT(destroy_query); - CTX_INIT(begin_query); - CTX_INIT(end_query); - CTX_INIT(get_query_result); - CTX_INIT(set_active_query_state); - CTX_INIT(create_blend_state); - CTX_INIT(bind_blend_state); - CTX_INIT(delete_blend_state); - CTX_INIT(create_sampler_state); - CTX_INIT(bind_sampler_states); - CTX_INIT(delete_sampler_state); - CTX_INIT(create_rasterizer_state); - CTX_INIT(bind_rasterizer_state); - CTX_INIT(delete_rasterizer_state); - CTX_INIT(create_depth_stencil_alpha_state); - CTX_INIT(bind_depth_stencil_alpha_state); - CTX_INIT(delete_depth_stencil_alpha_state); - CTX_INIT(create_fs_state); - CTX_INIT(bind_fs_state); - CTX_INIT(delete_fs_state); - CTX_INIT(create_vs_state); - CTX_INIT(bind_vs_state); - CTX_INIT(delete_vs_state); - CTX_INIT(create_gs_state); - CTX_INIT(bind_gs_state); - CTX_INIT(delete_gs_state); - CTX_INIT(create_tcs_state); - CTX_INIT(bind_tcs_state); - CTX_INIT(delete_tcs_state); - CTX_INIT(create_tes_state); - CTX_INIT(bind_tes_state); - CTX_INIT(delete_tes_state); - CTX_INIT(create_compute_state); - CTX_INIT(bind_compute_state); - CTX_INIT(delete_compute_state); - CTX_INIT(create_vertex_elements_state); - CTX_INIT(bind_vertex_elements_state); - CTX_INIT(delete_vertex_elements_state); - CTX_INIT(set_blend_color); - CTX_INIT(set_stencil_ref); - CTX_INIT(set_sample_mask); - CTX_INIT(set_min_samples); - CTX_INIT(set_clip_state); - CTX_INIT(set_constant_buffer); - CTX_INIT(set_framebuffer_state); - CTX_INIT(set_polygon_stipple); - CTX_INIT(set_scissor_states); - CTX_INIT(set_viewport_states); - CTX_INIT(set_sampler_views); - CTX_INIT(set_tess_state); - CTX_INIT(set_shader_buffers); - CTX_INIT(set_shader_images); - CTX_INIT(set_vertex_buffers); - CTX_INIT(create_stream_output_target); - CTX_INIT(stream_output_target_destroy); - CTX_INIT(set_stream_output_targets); - CTX_INIT(create_sampler_view); - CTX_INIT(sampler_view_destroy); - CTX_INIT(create_surface); - CTX_INIT(surface_destroy); - CTX_INIT(texture_barrier); - CTX_INIT(memory_barrier); - CTX_INIT(resource_commit); - /* create_video_codec */ - /* create_video_buffer */ - /* set_compute_resources */ - /* set_global_binding */ - CTX_INIT(get_sample_position); - CTX_INIT(invalidate_resource); - CTX_INIT(get_device_reset_status); - CTX_INIT(set_device_reset_callback); - CTX_INIT(dump_debug_state); - CTX_INIT(emit_string_marker); - CTX_INIT(create_texture_handle); - CTX_INIT(delete_texture_handle); - CTX_INIT(make_texture_handle_resident); - CTX_INIT(create_image_handle); - CTX_INIT(delete_image_handle); - CTX_INIT(make_image_handle_resident); - - dd_init_draw_functions(dctx); - - u_log_context_init(&dctx->log); - if (pipe->set_log_context) - pipe->set_log_context(pipe, &dctx->log); - - dctx->draw_state.sample_mask = ~0; - - list_inithead(&dctx->records); - (void) mtx_init(&dctx->mutex, mtx_plain); - (void) cnd_init(&dctx->cond); - dctx->thread = u_thread_create(dd_thread_main, dctx); - if (!dctx->thread) { - mtx_destroy(&dctx->mutex); - goto fail; - } - - return &dctx->base; - -fail: - FREE(dctx); - pipe->destroy(pipe); - return NULL; -} diff --git a/src/gallium/drivers/ddebug/dd_draw.c b/src/gallium/drivers/ddebug/dd_draw.c deleted file mode 100644 index c404ea0607f..00000000000 --- a/src/gallium/drivers/ddebug/dd_draw.c +++ /dev/null @@ -1,1645 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * Copyright 2008 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 "dd_pipe.h" - -#include "util/u_dump.h" -#include "util/u_format.h" -#include "util/u_framebuffer.h" -#include "util/u_helpers.h" -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_scan.h" -#include "util/os_time.h" -#include - - -static void -dd_write_header(FILE *f, struct pipe_screen *screen, unsigned apitrace_call_number) -{ - char cmd_line[4096]; - if (os_get_command_line(cmd_line, sizeof(cmd_line))) - fprintf(f, "Command: %s\n", cmd_line); - fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen)); - fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen)); - fprintf(f, "Device name: %s\n\n", screen->get_name(screen)); - - if (apitrace_call_number) - fprintf(f, "Last apitrace call: %u\n\n", apitrace_call_number); -} - -FILE * -dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number) -{ - struct pipe_screen *screen = dscreen->screen; - - FILE *f = dd_get_debug_file(dscreen->verbose); - if (!f) - return NULL; - - dd_write_header(f, screen, apitrace_call_number); - return f; -} - -static void -dd_dump_dmesg(FILE *f) -{ - char line[2000]; - FILE *p = popen("dmesg | tail -n60", "r"); - - if (!p) - return; - - fprintf(f, "\nLast 60 lines of dmesg:\n\n"); - while (fgets(line, sizeof(line), p)) - fputs(line, f); - - pclose(p); -} - -static unsigned -dd_num_active_viewports(struct dd_draw_state *dstate) -{ - struct tgsi_shader_info info; - const struct tgsi_token *tokens; - - if (dstate->shaders[PIPE_SHADER_GEOMETRY]) - tokens = dstate->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens; - else if (dstate->shaders[PIPE_SHADER_TESS_EVAL]) - tokens = dstate->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens; - else if (dstate->shaders[PIPE_SHADER_VERTEX]) - tokens = dstate->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens; - else - return 1; - - if (tokens) { - tgsi_scan_shader(tokens, &info); - if (info.writes_viewport_index) - return PIPE_MAX_VIEWPORTS; - } - - return 1; -} - -#define COLOR_RESET "\033[0m" -#define COLOR_SHADER "\033[1;32m" -#define COLOR_STATE "\033[1;33m" - -#define DUMP(name, var) do { \ - fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \ - util_dump_##name(f, var); \ - fprintf(f, "\n"); \ -} while(0) - -#define DUMP_I(name, var, i) do { \ - fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \ - util_dump_##name(f, var); \ - fprintf(f, "\n"); \ -} while(0) - -#define DUMP_M(name, var, member) do { \ - fprintf(f, " " #member ": "); \ - util_dump_##name(f, (var)->member); \ - fprintf(f, "\n"); \ -} while(0) - -#define DUMP_M_ADDR(name, var, member) do { \ - fprintf(f, " " #member ": "); \ - util_dump_##name(f, &(var)->member); \ - fprintf(f, "\n"); \ -} while(0) - -#define PRINT_NAMED(type, name, value) \ -do { \ - fprintf(f, COLOR_STATE "%s" COLOR_RESET " = ", name); \ - util_dump_##type(f, value); \ - fprintf(f, "\n"); \ -} while (0) - -static void -util_dump_uint(FILE *f, unsigned i) -{ - fprintf(f, "%u", i); -} - -static void -util_dump_int(FILE *f, int i) -{ - fprintf(f, "%d", i); -} - -static void -util_dump_hex(FILE *f, unsigned i) -{ - fprintf(f, "0x%x", i); -} - -static void -util_dump_double(FILE *f, double d) -{ - fprintf(f, "%f", d); -} - -static void -util_dump_format(FILE *f, enum pipe_format format) -{ - fprintf(f, "%s", util_format_name(format)); -} - -static void -util_dump_color_union(FILE *f, const union pipe_color_union *color) -{ - fprintf(f, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}", - color->f[0], color->f[1], color->f[2], color->f[3], - color->ui[0], color->ui[1], color->ui[2], color->ui[3]); -} - -static void -dd_dump_render_condition(struct dd_draw_state *dstate, FILE *f) -{ - if (dstate->render_cond.query) { - fprintf(f, "render condition:\n"); - DUMP_M(query_type, &dstate->render_cond, query->type); - DUMP_M(uint, &dstate->render_cond, condition); - DUMP_M(uint, &dstate->render_cond, mode); - fprintf(f, "\n"); - } -} - -static void -dd_dump_shader(struct dd_draw_state *dstate, enum pipe_shader_type sh, FILE *f) -{ - int i; - const char *shader_str[PIPE_SHADER_TYPES]; - - shader_str[PIPE_SHADER_VERTEX] = "VERTEX"; - shader_str[PIPE_SHADER_TESS_CTRL] = "TESS_CTRL"; - shader_str[PIPE_SHADER_TESS_EVAL] = "TESS_EVAL"; - shader_str[PIPE_SHADER_GEOMETRY] = "GEOMETRY"; - shader_str[PIPE_SHADER_FRAGMENT] = "FRAGMENT"; - shader_str[PIPE_SHADER_COMPUTE] = "COMPUTE"; - - if (sh == PIPE_SHADER_TESS_CTRL && - !dstate->shaders[PIPE_SHADER_TESS_CTRL] && - dstate->shaders[PIPE_SHADER_TESS_EVAL]) - fprintf(f, "tess_state: {default_outer_level = {%f, %f, %f, %f}, " - "default_inner_level = {%f, %f}}\n", - dstate->tess_default_levels[0], - dstate->tess_default_levels[1], - dstate->tess_default_levels[2], - dstate->tess_default_levels[3], - dstate->tess_default_levels[4], - dstate->tess_default_levels[5]); - - if (sh == PIPE_SHADER_FRAGMENT) - if (dstate->rs) { - unsigned num_viewports = dd_num_active_viewports(dstate); - - if (dstate->rs->state.rs.clip_plane_enable) - DUMP(clip_state, &dstate->clip_state); - - for (i = 0; i < num_viewports; i++) - DUMP_I(viewport_state, &dstate->viewports[i], i); - - if (dstate->rs->state.rs.scissor) - for (i = 0; i < num_viewports; i++) - DUMP_I(scissor_state, &dstate->scissors[i], i); - - DUMP(rasterizer_state, &dstate->rs->state.rs); - - if (dstate->rs->state.rs.poly_stipple_enable) - DUMP(poly_stipple, &dstate->polygon_stipple); - fprintf(f, "\n"); - } - - if (!dstate->shaders[sh]) - return; - - fprintf(f, COLOR_SHADER "begin shader: %s" COLOR_RESET "\n", shader_str[sh]); - DUMP(shader_state, &dstate->shaders[sh]->state.shader); - - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) - if (dstate->constant_buffers[sh][i].buffer || - dstate->constant_buffers[sh][i].user_buffer) { - DUMP_I(constant_buffer, &dstate->constant_buffers[sh][i], i); - if (dstate->constant_buffers[sh][i].buffer) - DUMP_M(resource, &dstate->constant_buffers[sh][i], buffer); - } - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - if (dstate->sampler_states[sh][i]) - DUMP_I(sampler_state, &dstate->sampler_states[sh][i]->state.sampler, i); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - if (dstate->sampler_views[sh][i]) { - DUMP_I(sampler_view, dstate->sampler_views[sh][i], i); - DUMP_M(resource, dstate->sampler_views[sh][i], texture); - } - - for (i = 0; i < PIPE_MAX_SHADER_IMAGES; i++) - if (dstate->shader_images[sh][i].resource) { - DUMP_I(image_view, &dstate->shader_images[sh][i], i); - if (dstate->shader_images[sh][i].resource) - DUMP_M(resource, &dstate->shader_images[sh][i], resource); - } - - for (i = 0; i < PIPE_MAX_SHADER_BUFFERS; i++) - if (dstate->shader_buffers[sh][i].buffer) { - DUMP_I(shader_buffer, &dstate->shader_buffers[sh][i], i); - if (dstate->shader_buffers[sh][i].buffer) - DUMP_M(resource, &dstate->shader_buffers[sh][i], buffer); - } - - fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]); -} - -static void -dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f) -{ - int sh, i; - - DUMP(draw_info, info); - if (info->count_from_stream_output) - DUMP_M(stream_output_target, info, - count_from_stream_output); - if (info->indirect) { - DUMP_M(resource, info, indirect->buffer); - if (info->indirect->indirect_draw_count) - DUMP_M(resource, info, indirect->indirect_draw_count); - } - - fprintf(f, "\n"); - - /* TODO: dump active queries */ - - dd_dump_render_condition(dstate, f); - - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) - if (dstate->vertex_buffers[i].buffer.resource) { - DUMP_I(vertex_buffer, &dstate->vertex_buffers[i], i); - if (!dstate->vertex_buffers[i].is_user_buffer) - DUMP_M(resource, &dstate->vertex_buffers[i], buffer.resource); - } - - if (dstate->velems) { - PRINT_NAMED(uint, "num vertex elements", - dstate->velems->state.velems.count); - for (i = 0; i < dstate->velems->state.velems.count; i++) { - fprintf(f, " "); - DUMP_I(vertex_element, &dstate->velems->state.velems.velems[i], i); - } - } - - PRINT_NAMED(uint, "num stream output targets", dstate->num_so_targets); - for (i = 0; i < dstate->num_so_targets; i++) - if (dstate->so_targets[i]) { - DUMP_I(stream_output_target, dstate->so_targets[i], i); - DUMP_M(resource, dstate->so_targets[i], buffer); - fprintf(f, " offset = %i\n", dstate->so_offsets[i]); - } - - fprintf(f, "\n"); - for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { - if (sh == PIPE_SHADER_COMPUTE) - continue; - - dd_dump_shader(dstate, sh, f); - } - - if (dstate->dsa) - DUMP(depth_stencil_alpha_state, &dstate->dsa->state.dsa); - DUMP(stencil_ref, &dstate->stencil_ref); - - if (dstate->blend) - DUMP(blend_state, &dstate->blend->state.blend); - DUMP(blend_color, &dstate->blend_color); - - PRINT_NAMED(uint, "min_samples", dstate->min_samples); - PRINT_NAMED(hex, "sample_mask", dstate->sample_mask); - fprintf(f, "\n"); - - DUMP(framebuffer_state, &dstate->framebuffer_state); - for (i = 0; i < dstate->framebuffer_state.nr_cbufs; i++) - if (dstate->framebuffer_state.cbufs[i]) { - fprintf(f, " " COLOR_STATE "cbufs[%i]:" COLOR_RESET "\n ", i); - DUMP(surface, dstate->framebuffer_state.cbufs[i]); - fprintf(f, " "); - DUMP(resource, dstate->framebuffer_state.cbufs[i]->texture); - } - if (dstate->framebuffer_state.zsbuf) { - fprintf(f, " " COLOR_STATE "zsbuf:" COLOR_RESET "\n "); - DUMP(surface, dstate->framebuffer_state.zsbuf); - fprintf(f, " "); - DUMP(resource, dstate->framebuffer_state.zsbuf->texture); - } - fprintf(f, "\n"); -} - -static void -dd_dump_launch_grid(struct dd_draw_state *dstate, struct pipe_grid_info *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP(grid_info, info); - fprintf(f, "\n"); - - dd_dump_shader(dstate, PIPE_SHADER_COMPUTE, f); - fprintf(f, "\n"); -} - -static void -dd_dump_resource_copy_region(struct dd_draw_state *dstate, - struct call_resource_copy_region *info, - FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M(resource, info, dst); - DUMP_M(uint, info, dst_level); - DUMP_M(uint, info, dstx); - DUMP_M(uint, info, dsty); - DUMP_M(uint, info, dstz); - DUMP_M(resource, info, src); - DUMP_M(uint, info, src_level); - DUMP_M_ADDR(box, info, src_box); -} - -static void -dd_dump_blit(struct dd_draw_state *dstate, struct pipe_blit_info *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M(resource, info, dst.resource); - DUMP_M(uint, info, dst.level); - DUMP_M_ADDR(box, info, dst.box); - DUMP_M(format, info, dst.format); - - DUMP_M(resource, info, src.resource); - DUMP_M(uint, info, src.level); - DUMP_M_ADDR(box, info, src.box); - DUMP_M(format, info, src.format); - - DUMP_M(hex, info, mask); - DUMP_M(uint, info, filter); - DUMP_M(uint, info, scissor_enable); - DUMP_M_ADDR(scissor_state, info, scissor); - DUMP_M(uint, info, render_condition_enable); - - if (info->render_condition_enable) - dd_dump_render_condition(dstate, f); -} - -static void -dd_dump_generate_mipmap(struct dd_draw_state *dstate, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - /* TODO */ -} - -static void -dd_dump_get_query_result_resource(struct call_get_query_result_resource *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__ + 8); - DUMP_M(query_type, info, query_type); - DUMP_M(uint, info, wait); - DUMP_M(query_value_type, info, result_type); - DUMP_M(int, info, index); - DUMP_M(resource, info, resource); - DUMP_M(uint, info, offset); -} - -static void -dd_dump_flush_resource(struct dd_draw_state *dstate, struct pipe_resource *res, - FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP(resource, res); -} - -static void -dd_dump_clear(struct dd_draw_state *dstate, struct call_clear *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M(uint, info, buffers); - DUMP_M_ADDR(color_union, info, color); - DUMP_M(double, info, depth); - DUMP_M(hex, info, stencil); -} - -static void -dd_dump_clear_buffer(struct dd_draw_state *dstate, struct call_clear_buffer *info, - FILE *f) -{ - int i; - const char *value = (const char*)info->clear_value; - - fprintf(f, "%s:\n", __func__+8); - DUMP_M(resource, info, res); - DUMP_M(uint, info, offset); - DUMP_M(uint, info, size); - DUMP_M(uint, info, clear_value_size); - - fprintf(f, " clear_value:"); - for (i = 0; i < info->clear_value_size; i++) - fprintf(f, " %02x", value[i]); - fprintf(f, "\n"); -} - -static void -dd_dump_transfer_map(struct call_transfer_map *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M_ADDR(transfer, info, transfer); - DUMP_M(ptr, info, transfer_ptr); - DUMP_M(ptr, info, ptr); -} - -static void -dd_dump_transfer_flush_region(struct call_transfer_flush_region *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M_ADDR(transfer, info, transfer); - DUMP_M(ptr, info, transfer_ptr); - DUMP_M_ADDR(box, info, box); -} - -static void -dd_dump_transfer_unmap(struct call_transfer_unmap *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M_ADDR(transfer, info, transfer); - DUMP_M(ptr, info, transfer_ptr); -} - -static void -dd_dump_buffer_subdata(struct call_buffer_subdata *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M(resource, info, resource); - DUMP_M(transfer_usage, info, usage); - DUMP_M(uint, info, offset); - DUMP_M(uint, info, size); - DUMP_M(ptr, info, data); -} - -static void -dd_dump_texture_subdata(struct call_texture_subdata *info, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - DUMP_M(resource, info, resource); - DUMP_M(uint, info, level); - DUMP_M(transfer_usage, info, usage); - DUMP_M_ADDR(box, info, box); - DUMP_M(ptr, info, data); - DUMP_M(uint, info, stride); - DUMP_M(uint, info, layer_stride); -} - -static void -dd_dump_clear_texture(struct dd_draw_state *dstate, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - /* TODO */ -} - -static void -dd_dump_clear_render_target(struct dd_draw_state *dstate, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - /* TODO */ -} - -static void -dd_dump_clear_depth_stencil(struct dd_draw_state *dstate, FILE *f) -{ - fprintf(f, "%s:\n", __func__+8); - /* TODO */ -} - -static void -dd_dump_driver_state(struct dd_context *dctx, FILE *f, unsigned flags) -{ - if (dctx->pipe->dump_debug_state) { - fprintf(f,"\n\n**************************************************" - "***************************\n"); - fprintf(f, "Driver-specific state:\n\n"); - dctx->pipe->dump_debug_state(dctx->pipe, f, flags); - } -} - -static void -dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call) -{ - switch (call->type) { - case CALL_DRAW_VBO: - dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f); - break; - case CALL_LAUNCH_GRID: - dd_dump_launch_grid(state, &call->info.launch_grid, f); - break; - case CALL_RESOURCE_COPY_REGION: - dd_dump_resource_copy_region(state, - &call->info.resource_copy_region, f); - break; - case CALL_BLIT: - dd_dump_blit(state, &call->info.blit, f); - break; - case CALL_FLUSH_RESOURCE: - dd_dump_flush_resource(state, call->info.flush_resource, f); - break; - case CALL_CLEAR: - dd_dump_clear(state, &call->info.clear, f); - break; - case CALL_CLEAR_BUFFER: - dd_dump_clear_buffer(state, &call->info.clear_buffer, f); - break; - case CALL_CLEAR_TEXTURE: - dd_dump_clear_texture(state, f); - break; - case CALL_CLEAR_RENDER_TARGET: - dd_dump_clear_render_target(state, f); - break; - case CALL_CLEAR_DEPTH_STENCIL: - dd_dump_clear_depth_stencil(state, f); - break; - case CALL_GENERATE_MIPMAP: - dd_dump_generate_mipmap(state, f); - break; - case CALL_GET_QUERY_RESULT_RESOURCE: - dd_dump_get_query_result_resource(&call->info.get_query_result_resource, f); - break; - case CALL_TRANSFER_MAP: - dd_dump_transfer_map(&call->info.transfer_map, f); - break; - case CALL_TRANSFER_FLUSH_REGION: - dd_dump_transfer_flush_region(&call->info.transfer_flush_region, f); - break; - case CALL_TRANSFER_UNMAP: - dd_dump_transfer_unmap(&call->info.transfer_unmap, f); - break; - case CALL_BUFFER_SUBDATA: - dd_dump_buffer_subdata(&call->info.buffer_subdata, f); - break; - case CALL_TEXTURE_SUBDATA: - dd_dump_texture_subdata(&call->info.texture_subdata, f); - break; - } -} - -static void -dd_kill_process(void) -{ - sync(); - fprintf(stderr, "dd: Aborting the process...\n"); - fflush(stdout); - fflush(stderr); - exit(1); -} - -static void -dd_unreference_copy_of_call(struct dd_call *dst) -{ - switch (dst->type) { - case CALL_DRAW_VBO: - pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL); - pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL); - pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL); - if (dst->info.draw_vbo.draw.index_size && - !dst->info.draw_vbo.draw.has_user_indices) - pipe_resource_reference(&dst->info.draw_vbo.draw.index.resource, NULL); - else - dst->info.draw_vbo.draw.index.user = NULL; - break; - case CALL_LAUNCH_GRID: - pipe_resource_reference(&dst->info.launch_grid.indirect, NULL); - break; - case CALL_RESOURCE_COPY_REGION: - pipe_resource_reference(&dst->info.resource_copy_region.dst, NULL); - pipe_resource_reference(&dst->info.resource_copy_region.src, NULL); - break; - case CALL_BLIT: - pipe_resource_reference(&dst->info.blit.dst.resource, NULL); - pipe_resource_reference(&dst->info.blit.src.resource, NULL); - break; - case CALL_FLUSH_RESOURCE: - pipe_resource_reference(&dst->info.flush_resource, NULL); - break; - case CALL_CLEAR: - break; - case CALL_CLEAR_BUFFER: - pipe_resource_reference(&dst->info.clear_buffer.res, NULL); - break; - case CALL_CLEAR_TEXTURE: - break; - case CALL_CLEAR_RENDER_TARGET: - break; - case CALL_CLEAR_DEPTH_STENCIL: - break; - case CALL_GENERATE_MIPMAP: - pipe_resource_reference(&dst->info.generate_mipmap.res, NULL); - break; - case CALL_GET_QUERY_RESULT_RESOURCE: - pipe_resource_reference(&dst->info.get_query_result_resource.resource, NULL); - break; - case CALL_TRANSFER_MAP: - pipe_resource_reference(&dst->info.transfer_map.transfer.resource, NULL); - break; - case CALL_TRANSFER_FLUSH_REGION: - pipe_resource_reference(&dst->info.transfer_flush_region.transfer.resource, NULL); - break; - case CALL_TRANSFER_UNMAP: - pipe_resource_reference(&dst->info.transfer_unmap.transfer.resource, NULL); - break; - case CALL_BUFFER_SUBDATA: - pipe_resource_reference(&dst->info.buffer_subdata.resource, NULL); - break; - case CALL_TEXTURE_SUBDATA: - pipe_resource_reference(&dst->info.texture_subdata.resource, NULL); - break; - } -} - -static void -dd_init_copy_of_draw_state(struct dd_draw_state_copy *state) -{ - unsigned i,j; - - /* Just clear pointers to gallium objects. Don't clear the whole structure, - * because it would kill performance with its size of 130 KB. - */ - memset(state->base.vertex_buffers, 0, - sizeof(state->base.vertex_buffers)); - memset(state->base.so_targets, 0, - sizeof(state->base.so_targets)); - memset(state->base.constant_buffers, 0, - sizeof(state->base.constant_buffers)); - memset(state->base.sampler_views, 0, - sizeof(state->base.sampler_views)); - memset(state->base.shader_images, 0, - sizeof(state->base.shader_images)); - memset(state->base.shader_buffers, 0, - sizeof(state->base.shader_buffers)); - memset(&state->base.framebuffer_state, 0, - sizeof(state->base.framebuffer_state)); - - memset(state->shaders, 0, sizeof(state->shaders)); - - state->base.render_cond.query = &state->render_cond; - - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - state->base.shaders[i] = &state->shaders[i]; - for (j = 0; j < PIPE_MAX_SAMPLERS; j++) - state->base.sampler_states[i][j] = &state->sampler_states[i][j]; - } - - state->base.velems = &state->velems; - state->base.rs = &state->rs; - state->base.dsa = &state->dsa; - state->base.blend = &state->blend; -} - -static void -dd_unreference_copy_of_draw_state(struct dd_draw_state_copy *state) -{ - struct dd_draw_state *dst = &state->base; - unsigned i,j; - - for (i = 0; i < ARRAY_SIZE(dst->vertex_buffers); i++) - pipe_vertex_buffer_unreference(&dst->vertex_buffers[i]); - for (i = 0; i < ARRAY_SIZE(dst->so_targets); i++) - pipe_so_target_reference(&dst->so_targets[i], NULL); - - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - if (dst->shaders[i]) - tgsi_free_tokens(dst->shaders[i]->state.shader.tokens); - - for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) - pipe_resource_reference(&dst->constant_buffers[i][j].buffer, NULL); - for (j = 0; j < PIPE_MAX_SAMPLERS; j++) - pipe_sampler_view_reference(&dst->sampler_views[i][j], NULL); - for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++) - pipe_resource_reference(&dst->shader_images[i][j].resource, NULL); - for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++) - pipe_resource_reference(&dst->shader_buffers[i][j].buffer, NULL); - } - - util_unreference_framebuffer_state(&dst->framebuffer_state); -} - -static void -dd_copy_draw_state(struct dd_draw_state *dst, struct dd_draw_state *src) -{ - unsigned i,j; - - if (src->render_cond.query) { - *dst->render_cond.query = *src->render_cond.query; - dst->render_cond.condition = src->render_cond.condition; - dst->render_cond.mode = src->render_cond.mode; - } else { - dst->render_cond.query = NULL; - } - - for (i = 0; i < ARRAY_SIZE(src->vertex_buffers); i++) { - pipe_vertex_buffer_reference(&dst->vertex_buffers[i], - &src->vertex_buffers[i]); - } - - dst->num_so_targets = src->num_so_targets; - for (i = 0; i < src->num_so_targets; i++) - pipe_so_target_reference(&dst->so_targets[i], src->so_targets[i]); - memcpy(dst->so_offsets, src->so_offsets, sizeof(src->so_offsets)); - - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - if (!src->shaders[i]) { - dst->shaders[i] = NULL; - continue; - } - - if (src->shaders[i]) { - dst->shaders[i]->state.shader = src->shaders[i]->state.shader; - if (src->shaders[i]->state.shader.tokens) { - dst->shaders[i]->state.shader.tokens = - tgsi_dup_tokens(src->shaders[i]->state.shader.tokens); - } else { - dst->shaders[i]->state.shader.ir.nir = NULL; - } - } else { - dst->shaders[i] = NULL; - } - - for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { - pipe_resource_reference(&dst->constant_buffers[i][j].buffer, - src->constant_buffers[i][j].buffer); - memcpy(&dst->constant_buffers[i][j], &src->constant_buffers[i][j], - sizeof(src->constant_buffers[i][j])); - } - - for (j = 0; j < PIPE_MAX_SAMPLERS; j++) { - pipe_sampler_view_reference(&dst->sampler_views[i][j], - src->sampler_views[i][j]); - if (src->sampler_states[i][j]) - dst->sampler_states[i][j]->state.sampler = - src->sampler_states[i][j]->state.sampler; - else - dst->sampler_states[i][j] = NULL; - } - - for (j = 0; j < PIPE_MAX_SHADER_IMAGES; j++) { - pipe_resource_reference(&dst->shader_images[i][j].resource, - src->shader_images[i][j].resource); - memcpy(&dst->shader_images[i][j], &src->shader_images[i][j], - sizeof(src->shader_images[i][j])); - } - - for (j = 0; j < PIPE_MAX_SHADER_BUFFERS; j++) { - pipe_resource_reference(&dst->shader_buffers[i][j].buffer, - src->shader_buffers[i][j].buffer); - memcpy(&dst->shader_buffers[i][j], &src->shader_buffers[i][j], - sizeof(src->shader_buffers[i][j])); - } - } - - if (src->velems) - dst->velems->state.velems = src->velems->state.velems; - else - dst->velems = NULL; - - if (src->rs) - dst->rs->state.rs = src->rs->state.rs; - else - dst->rs = NULL; - - if (src->dsa) - dst->dsa->state.dsa = src->dsa->state.dsa; - else - dst->dsa = NULL; - - if (src->blend) - dst->blend->state.blend = src->blend->state.blend; - else - dst->blend = NULL; - - dst->blend_color = src->blend_color; - dst->stencil_ref = src->stencil_ref; - dst->sample_mask = src->sample_mask; - dst->min_samples = src->min_samples; - dst->clip_state = src->clip_state; - util_copy_framebuffer_state(&dst->framebuffer_state, &src->framebuffer_state); - memcpy(dst->scissors, src->scissors, sizeof(src->scissors)); - memcpy(dst->viewports, src->viewports, sizeof(src->viewports)); - memcpy(dst->tess_default_levels, src->tess_default_levels, - sizeof(src->tess_default_levels)); - dst->apitrace_call_number = src->apitrace_call_number; -} - -static void -dd_free_record(struct pipe_screen *screen, struct dd_draw_record *record) -{ - u_log_page_destroy(record->log_page); - dd_unreference_copy_of_call(&record->call); - dd_unreference_copy_of_draw_state(&record->draw_state); - screen->fence_reference(screen, &record->prev_bottom_of_pipe, NULL); - screen->fence_reference(screen, &record->top_of_pipe, NULL); - screen->fence_reference(screen, &record->bottom_of_pipe, NULL); - util_queue_fence_destroy(&record->driver_finished); - FREE(record); -} - -static void -dd_write_record(FILE *f, struct dd_draw_record *record) -{ - PRINT_NAMED(ptr, "pipe", record->dctx->pipe); - PRINT_NAMED(ns, "time before (API call)", record->time_before); - PRINT_NAMED(ns, "time after (driver done)", record->time_after); - fprintf(f, "\n"); - - dd_dump_call(f, &record->draw_state.base, &record->call); - - if (record->log_page) { - fprintf(f,"\n\n**************************************************" - "***************************\n"); - fprintf(f, "Context Log:\n\n"); - u_log_page_print(record->log_page, f); - } -} - -static void -dd_maybe_dump_record(struct dd_screen *dscreen, struct dd_draw_record *record) -{ - if (dscreen->dump_mode == DD_DUMP_ONLY_HANGS || - (dscreen->dump_mode == DD_DUMP_APITRACE_CALL && - dscreen->apitrace_dump_call != record->draw_state.base.apitrace_call_number)) - return; - - char name[512]; - dd_get_debug_filename_and_mkdir(name, sizeof(name), dscreen->verbose); - FILE *f = fopen(name, "w"); - if (!f) { - fprintf(stderr, "dd: failed to open %s\n", name); - return; - } - - dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number); - dd_write_record(f, record); - - fclose(f); -} - -static const char * -dd_fence_state(struct pipe_screen *screen, struct pipe_fence_handle *fence, - bool *not_reached) -{ - if (!fence) - return "---"; - - bool ok = screen->fence_finish(screen, NULL, fence, 0); - - if (not_reached && !ok) - *not_reached = true; - - return ok ? "YES" : "NO "; -} - -static void -dd_report_hang(struct dd_context *dctx) -{ - struct dd_screen *dscreen = dd_screen(dctx->base.screen); - struct pipe_screen *screen = dscreen->screen; - bool encountered_hang = false; - bool stop_output = false; - unsigned num_later = 0; - - fprintf(stderr, "GPU hang detected, collecting information...\n\n"); - - fprintf(stderr, "Draw # driver prev BOP TOP BOP dump file\n" - "-------------------------------------------------------------\n"); - - list_for_each_entry(struct dd_draw_record, record, &dctx->records, list) { - if (!encountered_hang && - screen->fence_finish(screen, NULL, record->bottom_of_pipe, 0)) { - dd_maybe_dump_record(dscreen, record); - continue; - } - - if (stop_output) { - dd_maybe_dump_record(dscreen, record); - num_later++; - continue; - } - - bool driver = util_queue_fence_is_signalled(&record->driver_finished); - bool top_not_reached = false; - const char *prev_bop = dd_fence_state(screen, record->prev_bottom_of_pipe, NULL); - const char *top = dd_fence_state(screen, record->top_of_pipe, &top_not_reached); - const char *bop = dd_fence_state(screen, record->bottom_of_pipe, NULL); - - fprintf(stderr, "%-9u %s %s %s %s ", - record->draw_call, driver ? "YES" : "NO ", prev_bop, top, bop); - - char name[512]; - dd_get_debug_filename_and_mkdir(name, sizeof(name), false); - - FILE *f = fopen(name, "w"); - if (!f) { - fprintf(stderr, "fopen failed\n"); - } else { - fprintf(stderr, "%s\n", name); - - dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number); - dd_write_record(f, record); - - if (!encountered_hang) { - dd_dump_driver_state(dctx, f, PIPE_DUMP_DEVICE_STATUS_REGISTERS); - dd_dump_dmesg(f); - } - - fclose(f); - } - - if (top_not_reached) - stop_output = true; - encountered_hang = true; - } - - if (num_later || dctx->record_pending) { - fprintf(stderr, "... and %u%s additional draws.\n", num_later, - dctx->record_pending ? "+1 (pending)" : ""); - } - - fprintf(stderr, "\nDone.\n"); - dd_kill_process(); -} - -int -dd_thread_main(void *input) -{ - struct dd_context *dctx = (struct dd_context *)input; - struct dd_screen *dscreen = dd_screen(dctx->base.screen); - struct pipe_screen *screen = dscreen->screen; - - mtx_lock(&dctx->mutex); - - for (;;) { - struct list_head records; - struct pipe_fence_handle *fence; - struct pipe_fence_handle *fence2 = NULL; - - list_replace(&dctx->records, &records); - list_inithead(&dctx->records); - dctx->num_records = 0; - - if (dctx->api_stalled) - cnd_signal(&dctx->cond); - - if (!list_empty(&records)) { - /* Wait for the youngest draw. This means hangs can take a bit longer - * to detect, but it's more efficient this way. */ - struct dd_draw_record *youngest = - LIST_ENTRY(struct dd_draw_record, records.prev, list); - fence = youngest->bottom_of_pipe; - } else if (dctx->record_pending) { - /* Wait for pending fences, in case the driver ends up hanging internally. */ - fence = dctx->record_pending->prev_bottom_of_pipe; - fence2 = dctx->record_pending->top_of_pipe; - } else if (dctx->kill_thread) { - break; - } else { - cnd_wait(&dctx->cond, &dctx->mutex); - continue; - } - mtx_unlock(&dctx->mutex); - - /* Fences can be NULL legitimately when timeout detection is disabled. */ - if ((fence && - !screen->fence_finish(screen, NULL, fence, - (uint64_t)dscreen->timeout_ms * 1000*1000)) || - (fence2 && - !screen->fence_finish(screen, NULL, fence2, - (uint64_t)dscreen->timeout_ms * 1000*1000))) { - mtx_lock(&dctx->mutex); - list_splice(&records, &dctx->records); - dd_report_hang(dctx); - /* we won't actually get here */ - mtx_unlock(&dctx->mutex); - } - - list_for_each_entry_safe(struct dd_draw_record, record, &records, list) { - dd_maybe_dump_record(dscreen, record); - list_del(&record->list); - dd_free_record(screen, record); - } - - mtx_lock(&dctx->mutex); - } - mtx_unlock(&dctx->mutex); - return 0; -} - -static struct dd_draw_record * -dd_create_record(struct dd_context *dctx) -{ - struct dd_draw_record *record; - - record = MALLOC_STRUCT(dd_draw_record); - if (!record) - return NULL; - - record->dctx = dctx; - record->draw_call = dctx->num_draw_calls; - - record->prev_bottom_of_pipe = NULL; - record->top_of_pipe = NULL; - record->bottom_of_pipe = NULL; - record->log_page = NULL; - util_queue_fence_init(&record->driver_finished); - - dd_init_copy_of_draw_state(&record->draw_state); - dd_copy_draw_state(&record->draw_state.base, &dctx->draw_state); - - return record; -} - -static void -dd_context_flush(struct pipe_context *_pipe, - struct pipe_fence_handle **fence, unsigned flags) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - - pipe->flush(pipe, fence, flags); -} - -static void -dd_before_draw(struct dd_context *dctx, struct dd_draw_record *record) -{ - struct dd_screen *dscreen = dd_screen(dctx->base.screen); - struct pipe_context *pipe = dctx->pipe; - struct pipe_screen *screen = dscreen->screen; - - record->time_before = os_time_get_nano(); - - if (dscreen->timeout_ms > 0) { - if (dscreen->flush_always && dctx->num_draw_calls >= dscreen->skip_count) { - pipe->flush(pipe, &record->prev_bottom_of_pipe, 0); - screen->fence_reference(screen, &record->top_of_pipe, record->prev_bottom_of_pipe); - } else { - pipe->flush(pipe, &record->prev_bottom_of_pipe, - PIPE_FLUSH_DEFERRED | PIPE_FLUSH_BOTTOM_OF_PIPE); - pipe->flush(pipe, &record->top_of_pipe, - PIPE_FLUSH_DEFERRED | PIPE_FLUSH_TOP_OF_PIPE); - } - - mtx_lock(&dctx->mutex); - dctx->record_pending = record; - if (list_empty(&dctx->records)) - cnd_signal(&dctx->cond); - mtx_unlock(&dctx->mutex); - } -} - -static void -dd_after_draw_async(void *data) -{ - struct dd_draw_record *record = (struct dd_draw_record *)data; - struct dd_context *dctx = record->dctx; - struct dd_screen *dscreen = dd_screen(dctx->base.screen); - - record->log_page = u_log_new_page(&dctx->log); - record->time_after = os_time_get_nano(); - - if (!util_queue_fence_is_signalled(&record->driver_finished)) - util_queue_fence_signal(&record->driver_finished); - - if (dscreen->dump_mode == DD_DUMP_APITRACE_CALL && - dscreen->apitrace_dump_call > dctx->draw_state.apitrace_call_number) { - dd_thread_join(dctx); - /* No need to continue. */ - exit(0); - } -} - -static void -dd_after_draw(struct dd_context *dctx, struct dd_draw_record *record) -{ - struct dd_screen *dscreen = dd_screen(dctx->base.screen); - struct pipe_context *pipe = dctx->pipe; - - if (dscreen->timeout_ms > 0) { - unsigned flush_flags; - if (dscreen->flush_always && dctx->num_draw_calls >= dscreen->skip_count) - flush_flags = 0; - else - flush_flags = PIPE_FLUSH_DEFERRED | PIPE_FLUSH_BOTTOM_OF_PIPE; - pipe->flush(pipe, &record->bottom_of_pipe, flush_flags); - - assert(record == dctx->record_pending); - } - - if (pipe->callback) { - util_queue_fence_reset(&record->driver_finished); - pipe->callback(pipe, dd_after_draw_async, record, true); - } else { - dd_after_draw_async(record); - } - - mtx_lock(&dctx->mutex); - if (unlikely(dctx->num_records > 10000)) { - dctx->api_stalled = true; - /* Since this is only a heuristic to prevent the API thread from getting - * too far ahead, we don't need a loop here. */ - cnd_wait(&dctx->cond, &dctx->mutex); - dctx->api_stalled = false; - } - - if (list_empty(&dctx->records)) - cnd_signal(&dctx->cond); - - list_addtail(&record->list, &dctx->records); - dctx->record_pending = NULL; - dctx->num_records++; - mtx_unlock(&dctx->mutex); - - ++dctx->num_draw_calls; - if (dscreen->skip_count && dctx->num_draw_calls % 10000 == 0) - fprintf(stderr, "Gallium debugger reached %u draw calls.\n", - dctx->num_draw_calls); -} - -static void -dd_context_draw_vbo(struct pipe_context *_pipe, - const struct pipe_draw_info *info) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_DRAW_VBO; - record->call.info.draw_vbo.draw = *info; - record->call.info.draw_vbo.draw.count_from_stream_output = NULL; - pipe_so_target_reference(&record->call.info.draw_vbo.draw.count_from_stream_output, - info->count_from_stream_output); - if (info->index_size && !info->has_user_indices) { - record->call.info.draw_vbo.draw.index.resource = NULL; - pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource, - info->index.resource); - } - - if (info->indirect) { - record->call.info.draw_vbo.indirect = *info->indirect; - record->call.info.draw_vbo.draw.indirect = &record->call.info.draw_vbo.indirect; - - record->call.info.draw_vbo.indirect.buffer = NULL; - pipe_resource_reference(&record->call.info.draw_vbo.indirect.buffer, - info->indirect->buffer); - record->call.info.draw_vbo.indirect.indirect_draw_count = NULL; - pipe_resource_reference(&record->call.info.draw_vbo.indirect.indirect_draw_count, - info->indirect->indirect_draw_count); - } else { - memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*info->indirect)); - } - - dd_before_draw(dctx, record); - pipe->draw_vbo(pipe, info); - dd_after_draw(dctx, record); -} - -static void -dd_context_launch_grid(struct pipe_context *_pipe, - const struct pipe_grid_info *info) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_LAUNCH_GRID; - record->call.info.launch_grid = *info; - record->call.info.launch_grid.indirect = NULL; - pipe_resource_reference(&record->call.info.launch_grid.indirect, info->indirect); - - dd_before_draw(dctx, record); - pipe->launch_grid(pipe, info); - dd_after_draw(dctx, record); -} - -static void -dd_context_resource_copy_region(struct pipe_context *_pipe, - struct pipe_resource *dst, unsigned dst_level, - unsigned dstx, unsigned dsty, unsigned dstz, - struct pipe_resource *src, unsigned src_level, - const struct pipe_box *src_box) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_RESOURCE_COPY_REGION; - record->call.info.resource_copy_region.dst = NULL; - pipe_resource_reference(&record->call.info.resource_copy_region.dst, dst); - record->call.info.resource_copy_region.dst_level = dst_level; - record->call.info.resource_copy_region.dstx = dstx; - record->call.info.resource_copy_region.dsty = dsty; - record->call.info.resource_copy_region.dstz = dstz; - record->call.info.resource_copy_region.src = NULL; - pipe_resource_reference(&record->call.info.resource_copy_region.src, src); - record->call.info.resource_copy_region.src_level = src_level; - record->call.info.resource_copy_region.src_box = *src_box; - - dd_before_draw(dctx, record); - pipe->resource_copy_region(pipe, - dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); - dd_after_draw(dctx, record); -} - -static void -dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_BLIT; - record->call.info.blit = *info; - record->call.info.blit.dst.resource = NULL; - pipe_resource_reference(&record->call.info.blit.dst.resource, info->dst.resource); - record->call.info.blit.src.resource = NULL; - pipe_resource_reference(&record->call.info.blit.src.resource, info->src.resource); - - dd_before_draw(dctx, record); - pipe->blit(pipe, info); - dd_after_draw(dctx, record); -} - -static boolean -dd_context_generate_mipmap(struct pipe_context *_pipe, - struct pipe_resource *res, - enum pipe_format format, - unsigned base_level, - unsigned last_level, - unsigned first_layer, - unsigned last_layer) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - boolean result; - - record->call.type = CALL_GENERATE_MIPMAP; - record->call.info.generate_mipmap.res = NULL; - pipe_resource_reference(&record->call.info.generate_mipmap.res, res); - record->call.info.generate_mipmap.format = format; - record->call.info.generate_mipmap.base_level = base_level; - record->call.info.generate_mipmap.last_level = last_level; - record->call.info.generate_mipmap.first_layer = first_layer; - record->call.info.generate_mipmap.last_layer = last_layer; - - dd_before_draw(dctx, record); - result = pipe->generate_mipmap(pipe, res, format, base_level, last_level, - first_layer, last_layer); - dd_after_draw(dctx, record); - return result; -} - -static void -dd_context_get_query_result_resource(struct pipe_context *_pipe, - struct pipe_query *query, - boolean wait, - enum pipe_query_value_type result_type, - int index, - struct pipe_resource *resource, - unsigned offset) -{ - struct dd_context *dctx = dd_context(_pipe); - struct dd_query *dquery = dd_query(query); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_GET_QUERY_RESULT_RESOURCE; - record->call.info.get_query_result_resource.query = query; - record->call.info.get_query_result_resource.wait = wait; - record->call.info.get_query_result_resource.result_type = result_type; - record->call.info.get_query_result_resource.index = index; - record->call.info.get_query_result_resource.resource = NULL; - pipe_resource_reference(&record->call.info.get_query_result_resource.resource, - resource); - record->call.info.get_query_result_resource.offset = offset; - - /* The query may be deleted by the time we need to print it. */ - record->call.info.get_query_result_resource.query_type = dquery->type; - - dd_before_draw(dctx, record); - pipe->get_query_result_resource(pipe, dquery->query, wait, - result_type, index, resource, offset); - dd_after_draw(dctx, record); -} - -static void -dd_context_flush_resource(struct pipe_context *_pipe, - struct pipe_resource *resource) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_FLUSH_RESOURCE; - record->call.info.flush_resource = NULL; - pipe_resource_reference(&record->call.info.flush_resource, resource); - - dd_before_draw(dctx, record); - pipe->flush_resource(pipe, resource); - dd_after_draw(dctx, record); -} - -static void -dd_context_clear(struct pipe_context *_pipe, unsigned buffers, - const union pipe_color_union *color, double depth, - unsigned stencil) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_CLEAR; - record->call.info.clear.buffers = buffers; - record->call.info.clear.color = *color; - record->call.info.clear.depth = depth; - record->call.info.clear.stencil = stencil; - - dd_before_draw(dctx, record); - pipe->clear(pipe, buffers, color, depth, stencil); - dd_after_draw(dctx, record); -} - -static void -dd_context_clear_render_target(struct pipe_context *_pipe, - struct pipe_surface *dst, - const union pipe_color_union *color, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_CLEAR_RENDER_TARGET; - - dd_before_draw(dctx, record); - pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height, - render_condition_enabled); - dd_after_draw(dctx, record); -} - -static void -dd_context_clear_depth_stencil(struct pipe_context *_pipe, - struct pipe_surface *dst, unsigned clear_flags, - double depth, unsigned stencil, unsigned dstx, - unsigned dsty, unsigned width, unsigned height, - bool render_condition_enabled) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_CLEAR_DEPTH_STENCIL; - - dd_before_draw(dctx, record); - pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil, - dstx, dsty, width, height, - render_condition_enabled); - dd_after_draw(dctx, record); -} - -static void -dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res, - unsigned offset, unsigned size, - const void *clear_value, int clear_value_size) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_CLEAR_BUFFER; - record->call.info.clear_buffer.res = NULL; - pipe_resource_reference(&record->call.info.clear_buffer.res, res); - record->call.info.clear_buffer.offset = offset; - record->call.info.clear_buffer.size = size; - record->call.info.clear_buffer.clear_value = clear_value; - record->call.info.clear_buffer.clear_value_size = clear_value_size; - - dd_before_draw(dctx, record); - pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size); - dd_after_draw(dctx, record); -} - -static void -dd_context_clear_texture(struct pipe_context *_pipe, - struct pipe_resource *res, - unsigned level, - const struct pipe_box *box, - const void *data) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = dd_create_record(dctx); - - record->call.type = CALL_CLEAR_TEXTURE; - - dd_before_draw(dctx, record); - pipe->clear_texture(pipe, res, level, box, data); - dd_after_draw(dctx, record); -} - -/******************************************************************** - * transfer - */ - -static void * -dd_context_transfer_map(struct pipe_context *_pipe, - struct pipe_resource *resource, unsigned level, - unsigned usage, const struct pipe_box *box, - struct pipe_transfer **transfer) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = - dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; - - if (record) { - record->call.type = CALL_TRANSFER_MAP; - - dd_before_draw(dctx, record); - } - void *ptr = pipe->transfer_map(pipe, resource, level, usage, box, transfer); - if (record) { - record->call.info.transfer_map.transfer_ptr = *transfer; - record->call.info.transfer_map.ptr = ptr; - if (*transfer) { - record->call.info.transfer_map.transfer = **transfer; - record->call.info.transfer_map.transfer.resource = NULL; - pipe_resource_reference(&record->call.info.transfer_map.transfer.resource, - (*transfer)->resource); - } else { - memset(&record->call.info.transfer_map.transfer, 0, sizeof(struct pipe_transfer)); - } - - dd_after_draw(dctx, record); - } - return ptr; -} - -static void -dd_context_transfer_flush_region(struct pipe_context *_pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = - dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; - - if (record) { - record->call.type = CALL_TRANSFER_FLUSH_REGION; - record->call.info.transfer_flush_region.transfer_ptr = transfer; - record->call.info.transfer_flush_region.box = *box; - record->call.info.transfer_flush_region.transfer = *transfer; - record->call.info.transfer_flush_region.transfer.resource = NULL; - pipe_resource_reference( - &record->call.info.transfer_flush_region.transfer.resource, - transfer->resource); - - dd_before_draw(dctx, record); - } - pipe->transfer_flush_region(pipe, transfer, box); - if (record) - dd_after_draw(dctx, record); -} - -static void -dd_context_transfer_unmap(struct pipe_context *_pipe, - struct pipe_transfer *transfer) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = - dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; - - if (record) { - record->call.type = CALL_TRANSFER_UNMAP; - record->call.info.transfer_unmap.transfer_ptr = transfer; - record->call.info.transfer_unmap.transfer = *transfer; - record->call.info.transfer_unmap.transfer.resource = NULL; - pipe_resource_reference( - &record->call.info.transfer_unmap.transfer.resource, - transfer->resource); - - dd_before_draw(dctx, record); - } - pipe->transfer_unmap(pipe, transfer); - if (record) - dd_after_draw(dctx, record); -} - -static void -dd_context_buffer_subdata(struct pipe_context *_pipe, - struct pipe_resource *resource, - unsigned usage, unsigned offset, - unsigned size, const void *data) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = - dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; - - if (record) { - record->call.type = CALL_BUFFER_SUBDATA; - record->call.info.buffer_subdata.resource = NULL; - pipe_resource_reference(&record->call.info.buffer_subdata.resource, resource); - record->call.info.buffer_subdata.usage = usage; - record->call.info.buffer_subdata.offset = offset; - record->call.info.buffer_subdata.size = size; - record->call.info.buffer_subdata.data = data; - - dd_before_draw(dctx, record); - } - pipe->buffer_subdata(pipe, resource, usage, offset, size, data); - if (record) - dd_after_draw(dctx, record); -} - -static void -dd_context_texture_subdata(struct pipe_context *_pipe, - struct pipe_resource *resource, - unsigned level, unsigned usage, - const struct pipe_box *box, - const void *data, unsigned stride, - unsigned layer_stride) -{ - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; - struct dd_draw_record *record = - dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL; - - if (record) { - record->call.type = CALL_TEXTURE_SUBDATA; - record->call.info.texture_subdata.resource = NULL; - pipe_resource_reference(&record->call.info.texture_subdata.resource, resource); - record->call.info.texture_subdata.level = level; - record->call.info.texture_subdata.usage = usage; - record->call.info.texture_subdata.box = *box; - record->call.info.texture_subdata.data = data; - record->call.info.texture_subdata.stride = stride; - record->call.info.texture_subdata.layer_stride = layer_stride; - - dd_before_draw(dctx, record); - } - pipe->texture_subdata(pipe, resource, level, usage, box, data, - stride, layer_stride); - if (record) - dd_after_draw(dctx, record); -} - -void -dd_init_draw_functions(struct dd_context *dctx) -{ - CTX_INIT(flush); - CTX_INIT(draw_vbo); - CTX_INIT(launch_grid); - CTX_INIT(resource_copy_region); - CTX_INIT(blit); - CTX_INIT(clear); - CTX_INIT(clear_render_target); - CTX_INIT(clear_depth_stencil); - CTX_INIT(clear_buffer); - CTX_INIT(clear_texture); - CTX_INIT(flush_resource); - CTX_INIT(generate_mipmap); - CTX_INIT(get_query_result_resource); - CTX_INIT(transfer_map); - CTX_INIT(transfer_flush_region); - CTX_INIT(transfer_unmap); - CTX_INIT(buffer_subdata); - CTX_INIT(texture_subdata); -} diff --git a/src/gallium/drivers/ddebug/dd_pipe.h b/src/gallium/drivers/ddebug/dd_pipe.h deleted file mode 100644 index 07c4d55017f..00000000000 --- a/src/gallium/drivers/ddebug/dd_pipe.h +++ /dev/null @@ -1,371 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * Copyright 2008 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 DD_H_ -#define DD_H_ - -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "pipe/p_screen.h" -#include "dd_util.h" -#include "os/os_thread.h" -#include "util/list.h" -#include "util/u_log.h" -#include "util/u_queue.h" - -struct dd_context; - -enum dd_dump_mode { - DD_DUMP_ONLY_HANGS, - DD_DUMP_ALL_CALLS, - DD_DUMP_APITRACE_CALL, -}; - -struct dd_screen -{ - struct pipe_screen base; - struct pipe_screen *screen; - unsigned timeout_ms; - enum dd_dump_mode dump_mode; - bool flush_always; - bool transfers; - bool verbose; - unsigned skip_count; - unsigned apitrace_dump_call; -}; - -enum call_type -{ - CALL_DRAW_VBO, - CALL_LAUNCH_GRID, - CALL_RESOURCE_COPY_REGION, - CALL_BLIT, - CALL_FLUSH_RESOURCE, - CALL_CLEAR, - CALL_CLEAR_BUFFER, - CALL_CLEAR_TEXTURE, - CALL_CLEAR_RENDER_TARGET, - CALL_CLEAR_DEPTH_STENCIL, - CALL_GENERATE_MIPMAP, - CALL_GET_QUERY_RESULT_RESOURCE, - CALL_TRANSFER_MAP, - CALL_TRANSFER_FLUSH_REGION, - CALL_TRANSFER_UNMAP, - CALL_BUFFER_SUBDATA, - CALL_TEXTURE_SUBDATA, -}; - -struct call_resource_copy_region -{ - struct pipe_resource *dst; - unsigned dst_level; - unsigned dstx, dsty, dstz; - struct pipe_resource *src; - unsigned src_level; - struct pipe_box src_box; -}; - -struct call_clear -{ - unsigned buffers; - union pipe_color_union color; - double depth; - unsigned stencil; -}; - -struct call_clear_buffer -{ - struct pipe_resource *res; - unsigned offset; - unsigned size; - const void *clear_value; - int clear_value_size; -}; - -struct call_generate_mipmap { - struct pipe_resource *res; - enum pipe_format format; - unsigned base_level; - unsigned last_level; - unsigned first_layer; - unsigned last_layer; -}; - -struct call_draw_info { - struct pipe_draw_info draw; - struct pipe_draw_indirect_info indirect; -}; - -struct call_get_query_result_resource { - struct pipe_query *query; - enum pipe_query_type query_type; - boolean wait; - enum pipe_query_value_type result_type; - int index; - struct pipe_resource *resource; - unsigned offset; -}; - -struct call_transfer_map { - struct pipe_transfer *transfer_ptr; - struct pipe_transfer transfer; - void *ptr; -}; - -struct call_transfer_flush_region { - struct pipe_transfer *transfer_ptr; - struct pipe_transfer transfer; - struct pipe_box box; -}; - -struct call_transfer_unmap { - struct pipe_transfer *transfer_ptr; - struct pipe_transfer transfer; -}; - -struct call_buffer_subdata { - struct pipe_resource *resource; - unsigned usage; - unsigned offset; - unsigned size; - const void *data; -}; - -struct call_texture_subdata { - struct pipe_resource *resource; - unsigned level; - unsigned usage; - struct pipe_box box; - const void *data; - unsigned stride; - unsigned layer_stride; -}; - -struct dd_call -{ - enum call_type type; - - union { - struct call_draw_info draw_vbo; - struct pipe_grid_info launch_grid; - struct call_resource_copy_region resource_copy_region; - struct pipe_blit_info blit; - struct pipe_resource *flush_resource; - struct call_clear clear; - struct call_clear_buffer clear_buffer; - struct call_generate_mipmap generate_mipmap; - struct call_get_query_result_resource get_query_result_resource; - struct call_transfer_map transfer_map; - struct call_transfer_flush_region transfer_flush_region; - struct call_transfer_unmap transfer_unmap; - struct call_buffer_subdata buffer_subdata; - struct call_texture_subdata texture_subdata; - } info; -}; - -struct dd_query -{ - unsigned type; - struct pipe_query *query; -}; - -struct dd_state -{ - void *cso; - - union { - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state dsa; - struct pipe_rasterizer_state rs; - struct pipe_sampler_state sampler; - struct { - struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS]; - unsigned count; - } velems; - struct pipe_shader_state shader; - } state; -}; - -struct dd_draw_state -{ - struct { - struct dd_query *query; - bool condition; - unsigned mode; - } render_cond; - - struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; - - unsigned num_so_targets; - struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; - unsigned so_offsets[PIPE_MAX_SO_BUFFERS]; - - struct dd_state *shaders[PIPE_SHADER_TYPES]; - struct pipe_constant_buffer constant_buffers[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; - struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; - struct dd_state *sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; - struct pipe_image_view shader_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; - struct pipe_shader_buffer shader_buffers[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS]; - - struct dd_state *velems; - struct dd_state *rs; - struct dd_state *dsa; - struct dd_state *blend; - - struct pipe_blend_color blend_color; - struct pipe_stencil_ref stencil_ref; - unsigned sample_mask; - unsigned min_samples; - struct pipe_clip_state clip_state; - struct pipe_framebuffer_state framebuffer_state; - struct pipe_poly_stipple polygon_stipple; - struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS]; - struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS]; - float tess_default_levels[6]; - - unsigned apitrace_call_number; -}; - -struct dd_draw_state_copy -{ - struct dd_draw_state base; - - /* dd_draw_state_copy does not reference real CSOs. Instead, it points to - * these variables, which serve as storage. - */ - struct dd_query render_cond; - struct dd_state shaders[PIPE_SHADER_TYPES]; - struct dd_state sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; - struct dd_state velems; - struct dd_state rs; - struct dd_state dsa; - struct dd_state blend; -}; - -struct dd_draw_record { - struct list_head list; - struct dd_context *dctx; - - int64_t time_before; - int64_t time_after; - unsigned draw_call; - - struct pipe_fence_handle *prev_bottom_of_pipe; - struct pipe_fence_handle *top_of_pipe; - struct pipe_fence_handle *bottom_of_pipe; - - struct dd_call call; - struct dd_draw_state_copy draw_state; - - struct util_queue_fence driver_finished; - struct u_log_page *log_page; -}; - -struct dd_context -{ - struct pipe_context base; - struct pipe_context *pipe; - - struct dd_draw_state draw_state; - unsigned num_draw_calls; - - struct u_log_context log; - - /* Pipelined hang detection. - * - * This is without unnecessary flushes and waits. There is a memory-based - * fence that is incremented by clear_buffer every draw call. Driver fences - * are not used. - * - * After each draw call, a new dd_draw_record is created that contains - * a copy of all states, the output of pipe_context::dump_debug_state, - * and it has a fence number assigned. That's done without knowing whether - * that draw call is problematic or not. The record is added into the list - * of all records. - * - * An independent, separate thread loops over the list of records and checks - * their fences. Records with signalled fences are freed. On fence timeout, - * the thread dumps the records of in-flight draws. - */ - thrd_t thread; - mtx_t mutex; - cnd_t cond; - struct dd_draw_record *record_pending; /* currently inside the driver */ - struct list_head records; /* oldest record first */ - unsigned num_records; - bool kill_thread; - bool api_stalled; -}; - - -struct pipe_context * -dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe); - -void -dd_init_draw_functions(struct dd_context *dctx); - -void -dd_thread_join(struct dd_context *dctx); -int -dd_thread_main(void *input); - -FILE * -dd_get_file_stream(struct dd_screen *dscreen, unsigned apitrace_call_number); - -static inline struct dd_context * -dd_context(struct pipe_context *pipe) -{ - return (struct dd_context *)pipe; -} - -static inline struct dd_screen * -dd_screen(struct pipe_screen *screen) -{ - return (struct dd_screen*)screen; -} - -static inline struct dd_query * -dd_query(struct pipe_query *query) -{ - return (struct dd_query *)query; -} - -static inline struct pipe_query * -dd_query_unwrap(struct pipe_query *query) -{ - if (query) { - return dd_query(query)->query; - } else { - return NULL; - } -} - - -#define CTX_INIT(_member) \ - dctx->base._member = dctx->pipe->_member ? dd_context_##_member : NULL - -#endif /* DD_H_ */ diff --git a/src/gallium/drivers/ddebug/dd_public.h b/src/gallium/drivers/ddebug/dd_public.h deleted file mode 100644 index e6607655753..00000000000 --- a/src/gallium/drivers/ddebug/dd_public.h +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 DD_PUBLIC_H_ -#define DD_PUBLIC_H_ - -struct pipe_screen; - -struct pipe_screen * -ddebug_screen_create(struct pipe_screen *screen); - -#endif /* DD_PUBLIC_H_ */ diff --git a/src/gallium/drivers/ddebug/dd_screen.c b/src/gallium/drivers/ddebug/dd_screen.c deleted file mode 100644 index 5b2be28a969..00000000000 --- a/src/gallium/drivers/ddebug/dd_screen.c +++ /dev/null @@ -1,593 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * Copyright 2008 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 "dd_pipe.h" -#include "dd_public.h" -#include "util/u_memory.h" -#include -#include - - -static const char * -dd_screen_get_name(struct pipe_screen *_screen) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_name(screen); -} - -static const char * -dd_screen_get_vendor(struct pipe_screen *_screen) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_vendor(screen); -} - -static const char * -dd_screen_get_device_vendor(struct pipe_screen *_screen) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_device_vendor(screen); -} - -static const void * -dd_screen_get_compiler_options(struct pipe_screen *_screen, - enum pipe_shader_ir ir, - enum pipe_shader_type shader) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_compiler_options(screen, ir, shader); -} - -static struct disk_cache * -dd_screen_get_disk_shader_cache(struct pipe_screen *_screen) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_disk_shader_cache(screen); -} - -static int -dd_screen_get_param(struct pipe_screen *_screen, - enum pipe_cap param) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_param(screen, param); -} - -static float -dd_screen_get_paramf(struct pipe_screen *_screen, - enum pipe_capf param) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_paramf(screen, param); -} - -static int -dd_screen_get_compute_param(struct pipe_screen *_screen, - enum pipe_shader_ir ir_type, - enum pipe_compute_cap param, - void *ret) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_compute_param(screen, ir_type, param, ret); -} - -static int -dd_screen_get_shader_param(struct pipe_screen *_screen, - enum pipe_shader_type shader, - enum pipe_shader_cap param) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_shader_param(screen, shader, param); -} - -static uint64_t -dd_screen_get_timestamp(struct pipe_screen *_screen) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_timestamp(screen); -} - -static void dd_screen_query_memory_info(struct pipe_screen *_screen, - struct pipe_memory_info *info) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->query_memory_info(screen, info); -} - -static struct pipe_context * -dd_screen_context_create(struct pipe_screen *_screen, void *priv, - unsigned flags) -{ - struct dd_screen *dscreen = dd_screen(_screen); - struct pipe_screen *screen = dscreen->screen; - - flags |= PIPE_CONTEXT_DEBUG; - - return dd_context_create(dscreen, - screen->context_create(screen, priv, flags)); -} - -static boolean -dd_screen_is_format_supported(struct pipe_screen *_screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned sample_count, - unsigned tex_usage) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->is_format_supported(screen, format, target, sample_count, - tex_usage); -} - -static boolean -dd_screen_can_create_resource(struct pipe_screen *_screen, - const struct pipe_resource *templat) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->can_create_resource(screen, templat); -} - -static void -dd_screen_flush_frontbuffer(struct pipe_screen *_screen, - struct pipe_resource *resource, - unsigned level, unsigned layer, - void *context_private, - struct pipe_box *sub_box) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->flush_frontbuffer(screen, resource, level, layer, context_private, - sub_box); -} - -static int -dd_screen_get_driver_query_info(struct pipe_screen *_screen, - unsigned index, - struct pipe_driver_query_info *info) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_driver_query_info(screen, index, info); -} - -static int -dd_screen_get_driver_query_group_info(struct pipe_screen *_screen, - unsigned index, - struct pipe_driver_query_group_info *info) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->get_driver_query_group_info(screen, index, info); -} - - -static void -dd_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->get_driver_uuid(screen, uuid); -} - -static void -dd_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->get_device_uuid(screen, uuid); -} - -/******************************************************************** - * resource - */ - -static struct pipe_resource * -dd_screen_resource_create(struct pipe_screen *_screen, - const struct pipe_resource *templat) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - struct pipe_resource *res = screen->resource_create(screen, templat); - - if (!res) - return NULL; - res->screen = _screen; - return res; -} - -static struct pipe_resource * -dd_screen_resource_from_handle(struct pipe_screen *_screen, - const struct pipe_resource *templ, - struct winsys_handle *handle, - unsigned usage) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - struct pipe_resource *res = - screen->resource_from_handle(screen, templ, handle, usage); - - if (!res) - return NULL; - res->screen = _screen; - return res; -} - -static struct pipe_resource * -dd_screen_resource_from_user_memory(struct pipe_screen *_screen, - const struct pipe_resource *templ, - void *user_memory) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - struct pipe_resource *res = - screen->resource_from_user_memory(screen, templ, user_memory); - - if (!res) - return NULL; - res->screen = _screen; - return res; -} - -static struct pipe_resource * -dd_screen_resource_from_memobj(struct pipe_screen *_screen, - const struct pipe_resource *templ, - struct pipe_memory_object *memobj, - uint64_t offset) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - struct pipe_resource *res = - screen->resource_from_memobj(screen, templ, memobj, offset); - - if (!res) - return NULL; - res->screen = _screen; - return res; -} - -static void -dd_screen_resource_changed(struct pipe_screen *_screen, - struct pipe_resource *res) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->resource_changed(screen, res); -} - -static void -dd_screen_resource_destroy(struct pipe_screen *_screen, - struct pipe_resource *res) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->resource_destroy(screen, res); -} - -static boolean -dd_screen_resource_get_handle(struct pipe_screen *_screen, - struct pipe_context *_pipe, - struct pipe_resource *resource, - struct winsys_handle *handle, - unsigned usage) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL; - - return screen->resource_get_handle(screen, pipe, resource, handle, usage); -} - -static bool -dd_screen_check_resource_capability(struct pipe_screen *_screen, - struct pipe_resource *resource, - unsigned bind) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->check_resource_capability(screen, resource, bind); -} - - -/******************************************************************** - * fence - */ - -static void -dd_screen_fence_reference(struct pipe_screen *_screen, - struct pipe_fence_handle **pdst, - struct pipe_fence_handle *src) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->fence_reference(screen, pdst, src); -} - -static boolean -dd_screen_fence_finish(struct pipe_screen *_screen, - struct pipe_context *_ctx, - struct pipe_fence_handle *fence, - uint64_t timeout) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - struct pipe_context *ctx = _ctx ? dd_context(_ctx)->pipe : NULL; - - return screen->fence_finish(screen, ctx, fence, timeout); -} - -/******************************************************************** - * memobj - */ - -static struct pipe_memory_object * -dd_screen_memobj_create_from_handle(struct pipe_screen *_screen, - struct winsys_handle *handle, - bool dedicated) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - return screen->memobj_create_from_handle(screen, handle, dedicated); -} - -static void -dd_screen_memobj_destroy(struct pipe_screen *_screen, - struct pipe_memory_object *memobj) -{ - struct pipe_screen *screen = dd_screen(_screen)->screen; - - screen->memobj_destroy(screen, memobj); -} -/******************************************************************** - * screen - */ - -static void -dd_screen_destroy(struct pipe_screen *_screen) -{ - struct dd_screen *dscreen = dd_screen(_screen); - struct pipe_screen *screen = dscreen->screen; - - screen->destroy(screen); - FREE(dscreen); -} - -static void -skip_space(const char **p) -{ - while (isspace(**p)) - (*p)++; -} - -static bool -match_word(const char **cur, const char *word) -{ - size_t len = strlen(word); - if (strncmp(*cur, word, len) != 0) - return false; - - const char *p = *cur + len; - if (*p) { - if (!isspace(*p)) - return false; - - *cur = p + 1; - } else { - *cur = p; - } - - return true; -} - -static bool -match_uint(const char **cur, unsigned *value) -{ - char *end; - unsigned v = strtoul(*cur, &end, 0); - if (end == *cur || (*end && !isspace(*end))) - return false; - *cur = end; - *value = v; - return true; -} - -struct pipe_screen * -ddebug_screen_create(struct pipe_screen *screen) -{ - struct dd_screen *dscreen; - const char *option; - bool flush = false; - bool verbose = false; - bool transfers = false; - unsigned timeout = 1000; - unsigned apitrace_dump_call = 0; - enum dd_dump_mode mode = DD_DUMP_ONLY_HANGS; - - option = debug_get_option("GALLIUM_DDEBUG", NULL); - if (!option) - return screen; - - if (!strcmp(option, "help")) { - puts("Gallium driver debugger"); - puts(""); - puts("Usage:"); - puts(""); - puts(" GALLIUM_DDEBUG=\"[] [(always|apitrace "); - puts(" Change the default timeout for GPU hang detection (default=1000ms)."); - puts(" Setting this to 0 will disable GPU hang detection entirely."); - puts(""); - puts("always"); - puts(" Dump information about all draw calls."); - puts(""); - puts("transfers"); - puts(" Also dump and do hang detection on transfers."); - puts(""); - puts("apitrace "); - puts(" Dump information about the draw call corresponding to the given"); - puts(" apitrace call number and exit."); - puts(""); - puts("flush"); - puts(" Flush after every draw call."); - puts(""); - puts("verbose"); - puts(" Write additional information to stderr."); - puts(""); - puts("GALLIUM_DDEBUG_SKIP=count"); - puts(" Skip dumping on the first count draw calls (only relevant with 'always')."); - puts(""); - exit(0); - } - - for (;;) { - skip_space(&option); - if (!*option) - break; - - if (match_word(&option, "always")) { - if (mode == DD_DUMP_APITRACE_CALL) { - printf("ddebug: both 'always' and 'apitrace' specified\n"); - exit(1); - } - - mode = DD_DUMP_ALL_CALLS; - } else if (match_word(&option, "flush")) { - flush = true; - } else if (match_word(&option, "transfers")) { - transfers = true; - } else if (match_word(&option, "verbose")) { - verbose = true; - } else if (match_word(&option, "apitrace")) { - if (mode != DD_DUMP_ONLY_HANGS) { - printf("ddebug: 'apitrace' can only appear once and not mixed with 'always'\n"); - exit(1); - } - - if (!match_uint(&option, &apitrace_dump_call)) { - printf("ddebug: expected call number after 'apitrace'\n"); - exit(1); - } - - mode = DD_DUMP_APITRACE_CALL; - } else if (match_uint(&option, &timeout)) { - /* no-op */ - } else { - printf("ddebug: bad options: %s\n", option); - exit(1); - } - } - - dscreen = CALLOC_STRUCT(dd_screen); - if (!dscreen) - return NULL; - -#define SCR_INIT(_member) \ - dscreen->base._member = screen->_member ? dd_screen_##_member : NULL - - dscreen->base.destroy = dd_screen_destroy; - dscreen->base.get_name = dd_screen_get_name; - dscreen->base.get_vendor = dd_screen_get_vendor; - dscreen->base.get_device_vendor = dd_screen_get_device_vendor; - SCR_INIT(get_disk_shader_cache); - dscreen->base.get_param = dd_screen_get_param; - dscreen->base.get_paramf = dd_screen_get_paramf; - dscreen->base.get_compute_param = dd_screen_get_compute_param; - dscreen->base.get_shader_param = dd_screen_get_shader_param; - dscreen->base.query_memory_info = dd_screen_query_memory_info; - /* get_video_param */ - /* get_compute_param */ - SCR_INIT(get_timestamp); - dscreen->base.context_create = dd_screen_context_create; - dscreen->base.is_format_supported = dd_screen_is_format_supported; - /* is_video_format_supported */ - SCR_INIT(can_create_resource); - dscreen->base.resource_create = dd_screen_resource_create; - dscreen->base.resource_from_handle = dd_screen_resource_from_handle; - SCR_INIT(resource_from_memobj); - SCR_INIT(resource_from_user_memory); - SCR_INIT(check_resource_capability); - dscreen->base.resource_get_handle = dd_screen_resource_get_handle; - SCR_INIT(resource_changed); - dscreen->base.resource_destroy = dd_screen_resource_destroy; - SCR_INIT(flush_frontbuffer); - SCR_INIT(fence_reference); - SCR_INIT(fence_finish); - SCR_INIT(memobj_create_from_handle); - SCR_INIT(memobj_destroy); - SCR_INIT(get_driver_query_info); - SCR_INIT(get_driver_query_group_info); - SCR_INIT(get_compiler_options); - SCR_INIT(get_driver_uuid); - SCR_INIT(get_device_uuid); - -#undef SCR_INIT - - dscreen->screen = screen; - dscreen->timeout_ms = timeout; - dscreen->dump_mode = mode; - dscreen->flush_always = flush; - dscreen->transfers = transfers; - dscreen->verbose = verbose; - dscreen->apitrace_dump_call = apitrace_dump_call; - - switch (dscreen->dump_mode) { - case DD_DUMP_ALL_CALLS: - fprintf(stderr, "Gallium debugger active. Logging all calls.\n"); - break; - case DD_DUMP_APITRACE_CALL: - fprintf(stderr, "Gallium debugger active. Going to dump an apitrace call.\n"); - break; - default: - fprintf(stderr, "Gallium debugger active.\n"); - break; - } - - if (dscreen->timeout_ms > 0) - fprintf(stderr, "Hang detection timeout is %ums.\n", dscreen->timeout_ms); - else - fprintf(stderr, "Hang detection is disabled.\n"); - - dscreen->skip_count = debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0); - if (dscreen->skip_count > 0) { - fprintf(stderr, "Gallium debugger skipping the first %u draw calls.\n", - dscreen->skip_count); - } - - return &dscreen->base; -} diff --git a/src/gallium/drivers/ddebug/dd_util.h b/src/gallium/drivers/ddebug/dd_util.h deleted file mode 100644 index bdfb7cc9163..00000000000 --- a/src/gallium/drivers/ddebug/dd_util.h +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * Copyright 2008 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 DD_UTIL_H -#define DD_UTIL_H - -#include -#include -#include -#include - -#include "c99_alloca.h" -#include "os/os_process.h" -#include "util/u_atomic.h" -#include "util/u_debug.h" - -/* name of the directory in home */ -#define DD_DIR "ddebug_dumps" - -static inline void -dd_get_debug_filename_and_mkdir(char *buf, size_t buflen, bool verbose) -{ - static unsigned index; - char proc_name[128], dir[256]; - - if (!os_get_process_name(proc_name, sizeof(proc_name))) { - fprintf(stderr, "dd: can't get the process name\n"); - strcpy(proc_name, "unknown"); - } - - snprintf(dir, sizeof(dir), "%s/"DD_DIR, debug_get_option("HOME", ".")); - - if (mkdir(dir, 0774) && errno != EEXIST) - fprintf(stderr, "dd: can't create a directory (%i)\n", errno); - - snprintf(buf, buflen, "%s/%s_%u_%08u", dir, proc_name, getpid(), - p_atomic_inc_return(&index) - 1); - - if (verbose) - fprintf(stderr, "dd: dumping to file %s\n", buf); -} - -static inline FILE * -dd_get_debug_file(bool verbose) -{ - char name[512]; - FILE *f; - - dd_get_debug_filename_and_mkdir(name, sizeof(name), verbose); - f = fopen(name, "w"); - if (!f) { - fprintf(stderr, "dd: can't open file %s\n", name); - return NULL; - } - - return f; -} - -static inline void -dd_parse_apitrace_marker(const char *string, int len, unsigned *call_number) -{ - unsigned num; - char *s; - - if (len <= 0) - return; - - /* Make it zero-terminated. */ - s = alloca(len + 1); - memcpy(s, string, len); - s[len] = 0; - - /* Parse the number. */ - errno = 0; - num = strtol(s, NULL, 10); - if (errno) - return; - - *call_number = num; -} - -#endif /* DD_UTIL_H */ diff --git a/src/gallium/drivers/ddebug/meson.build b/src/gallium/drivers/ddebug/meson.build deleted file mode 100644 index 09ede3d04d4..00000000000 --- a/src/gallium/drivers/ddebug/meson.build +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright © 2017 Dylan Baker - -# 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS 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. - -libddebug = static_library( - 'ddebug', - files('dd_context.c', 'dd_draw.c', 'dd_pipe.h', 'dd_public.h', 'dd_screen.c', - 'dd_util.h'), - c_args : [c_vis_args], - include_directories : [inc_gallium, inc_include, inc_src, inc_gallium_aux], - build_by_default : false, -) diff --git a/src/gallium/drivers/noop/Makefile.am b/src/gallium/drivers/noop/Makefile.am deleted file mode 100644 index 1a4354e0b4d..00000000000 --- a/src/gallium/drivers/noop/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -################################################################################ - -# Meta-driver which combines whichever software rasterizers have been -# built into a single convenience library. - -include Makefile.sources -include $(top_srcdir)/src/gallium/Automake.inc - -AM_CFLAGS = \ - $(GALLIUM_DRIVER_CFLAGS) - -noinst_LTLIBRARIES = libnoop.la - -libnoop_la_SOURCES = $(C_SOURCES) - -EXTRA_DIST = SConscript meson.build diff --git a/src/gallium/drivers/noop/Makefile.sources b/src/gallium/drivers/noop/Makefile.sources deleted file mode 100644 index 6d4228630bc..00000000000 --- a/src/gallium/drivers/noop/Makefile.sources +++ /dev/null @@ -1,4 +0,0 @@ -C_SOURCES := \ - noop_pipe.c \ - noop_public.h \ - noop_state.c diff --git a/src/gallium/drivers/noop/SConscript b/src/gallium/drivers/noop/SConscript deleted file mode 100644 index 9cb2e29cbe3..00000000000 --- a/src/gallium/drivers/noop/SConscript +++ /dev/null @@ -1,13 +0,0 @@ -####################################################################### -# SConscript for noop convenience library - -Import('*') - -env = env.Clone() - -noop = env.ConvenienceLibrary( - target = 'noop', - source = env.ParseSourceList('Makefile.sources', 'C_SOURCES') - ) + extra - -Export('noop') diff --git a/src/gallium/drivers/noop/meson.build b/src/gallium/drivers/noop/meson.build deleted file mode 100644 index c4bb1508e3c..00000000000 --- a/src/gallium/drivers/noop/meson.build +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright © 2017 Dylan Baker - -# 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS 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. - -libnoop = static_library( - 'noop', - files('noop_pipe.c', 'noop_public.h', 'noop_state.c'), - c_args : [c_vis_args], - include_directories : [inc_gallium, inc_include, inc_src, inc_gallium_aux], - build_by_default : false, -) diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c deleted file mode 100644 index d1e795dab16..00000000000 --- a/src/gallium/drivers/noop/noop_pipe.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 -#include -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "util/u_memory.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_upload_mgr.h" -#include "noop_public.h" - -DEBUG_GET_ONCE_BOOL_OPTION(noop, "GALLIUM_NOOP", FALSE) - -void noop_init_state_functions(struct pipe_context *ctx); - -struct noop_pipe_screen { - struct pipe_screen pscreen; - struct pipe_screen *oscreen; -}; - -/* - * query - */ -struct noop_query { - unsigned query; -}; -static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index) -{ - struct noop_query *query = CALLOC_STRUCT(noop_query); - - return (struct pipe_query *)query; -} - -static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query) -{ - FREE(query); -} - -static boolean noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) -{ - return true; -} - -static bool noop_end_query(struct pipe_context *ctx, struct pipe_query *query) -{ - return true; -} - -static boolean noop_get_query_result(struct pipe_context *ctx, - struct pipe_query *query, - boolean wait, - union pipe_query_result *vresult) -{ - uint64_t *result = (uint64_t*)vresult; - - *result = 0; - return TRUE; -} - -static void -noop_set_active_query_state(struct pipe_context *pipe, boolean enable) -{ -} - - -/* - * resource - */ -struct noop_resource { - struct pipe_resource base; - unsigned size; - char *data; - struct sw_displaytarget *dt; -}; - -static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, - const struct pipe_resource *templ) -{ - struct noop_resource *nresource; - unsigned stride; - - nresource = CALLOC_STRUCT(noop_resource); - if (!nresource) - return NULL; - - stride = util_format_get_stride(templ->format, templ->width0); - nresource->base = *templ; - nresource->base.screen = screen; - nresource->size = stride * templ->height0 * templ->depth0; - nresource->data = MALLOC(nresource->size); - pipe_reference_init(&nresource->base.reference, 1); - if (nresource->data == NULL) { - FREE(nresource); - return NULL; - } - return &nresource->base; -} - -static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *screen, - const struct pipe_resource *templ, - struct winsys_handle *handle, - unsigned usage) -{ - struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; - struct pipe_screen *oscreen = noop_screen->oscreen; - struct pipe_resource *result; - struct pipe_resource *noop_resource; - - result = oscreen->resource_from_handle(oscreen, templ, handle, usage); - noop_resource = noop_resource_create(screen, result); - pipe_resource_reference(&result, NULL); - return noop_resource; -} - -static boolean noop_resource_get_handle(struct pipe_screen *pscreen, - struct pipe_context *ctx, - struct pipe_resource *resource, - struct winsys_handle *handle, - unsigned usage) -{ - struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; - struct pipe_screen *screen = noop_screen->oscreen; - struct pipe_resource *tex; - bool result; - - /* resource_get_handle musn't fail. Just create something and return it. */ - tex = screen->resource_create(screen, resource); - if (!tex) - return false; - - result = screen->resource_get_handle(screen, NULL, tex, handle, usage); - pipe_resource_reference(&tex, NULL); - return result; -} - -static void noop_resource_destroy(struct pipe_screen *screen, - struct pipe_resource *resource) -{ - struct noop_resource *nresource = (struct noop_resource *)resource; - - FREE(nresource->data); - FREE(resource); -} - - -/* - * transfer - */ -static void *noop_transfer_map(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, - enum pipe_transfer_usage usage, - const struct pipe_box *box, - struct pipe_transfer **ptransfer) -{ - struct pipe_transfer *transfer; - struct noop_resource *nresource = (struct noop_resource *)resource; - - transfer = CALLOC_STRUCT(pipe_transfer); - if (!transfer) - return NULL; - pipe_resource_reference(&transfer->resource, resource); - transfer->level = level; - transfer->usage = usage; - transfer->box = *box; - transfer->stride = 1; - transfer->layer_stride = 1; - *ptransfer = transfer; - - return nresource->data; -} - -static void noop_transfer_flush_region(struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ -} - -static void noop_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - pipe_resource_reference(&transfer->resource, NULL); - FREE(transfer); -} - -static void noop_buffer_subdata(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned usage, unsigned offset, - unsigned size, const void *data) -{ -} - -static void noop_texture_subdata(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box, - const void *data, - unsigned stride, - unsigned layer_stride) -{ -} - - -/* - * clear/copy - */ -static void noop_clear(struct pipe_context *ctx, unsigned buffers, - const union pipe_color_union *color, double depth, unsigned stencil) -{ -} - -static void noop_clear_render_target(struct pipe_context *ctx, - struct pipe_surface *dst, - const union pipe_color_union *color, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ -} - -static void noop_clear_depth_stencil(struct pipe_context *ctx, - struct pipe_surface *dst, - unsigned clear_flags, - double depth, - unsigned stencil, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ -} - -static void noop_resource_copy_region(struct pipe_context *ctx, - struct pipe_resource *dst, - unsigned dst_level, - unsigned dstx, unsigned dsty, unsigned dstz, - struct pipe_resource *src, - unsigned src_level, - const struct pipe_box *src_box) -{ -} - - -static void noop_blit(struct pipe_context *ctx, - const struct pipe_blit_info *info) -{ -} - - -static void -noop_flush_resource(struct pipe_context *ctx, - struct pipe_resource *resource) -{ -} - - -/* - * context - */ -static void noop_flush(struct pipe_context *ctx, - struct pipe_fence_handle **fence, - unsigned flags) -{ - if (fence) - *fence = NULL; -} - -static void noop_destroy_context(struct pipe_context *ctx) -{ - if (ctx->stream_uploader) - u_upload_destroy(ctx->stream_uploader); - - FREE(ctx); -} - -static boolean noop_generate_mipmap(struct pipe_context *ctx, - struct pipe_resource *resource, - enum pipe_format format, - unsigned base_level, - unsigned last_level, - unsigned first_layer, - unsigned last_layer) -{ - return true; -} - -static struct pipe_context *noop_create_context(struct pipe_screen *screen, - void *priv, unsigned flags) -{ - struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); - - if (!ctx) - return NULL; - - ctx->screen = screen; - ctx->priv = priv; - - ctx->stream_uploader = u_upload_create_default(ctx); - if (!ctx->stream_uploader) { - FREE(ctx); - return NULL; - } - ctx->const_uploader = ctx->stream_uploader; - - ctx->destroy = noop_destroy_context; - ctx->flush = noop_flush; - ctx->clear = noop_clear; - ctx->clear_render_target = noop_clear_render_target; - ctx->clear_depth_stencil = noop_clear_depth_stencil; - ctx->resource_copy_region = noop_resource_copy_region; - ctx->generate_mipmap = noop_generate_mipmap; - ctx->blit = noop_blit; - ctx->flush_resource = noop_flush_resource; - ctx->create_query = noop_create_query; - ctx->destroy_query = noop_destroy_query; - ctx->begin_query = noop_begin_query; - ctx->end_query = noop_end_query; - ctx->get_query_result = noop_get_query_result; - ctx->set_active_query_state = noop_set_active_query_state; - ctx->transfer_map = noop_transfer_map; - ctx->transfer_flush_region = noop_transfer_flush_region; - ctx->transfer_unmap = noop_transfer_unmap; - ctx->buffer_subdata = noop_buffer_subdata; - ctx->texture_subdata = noop_texture_subdata; - noop_init_state_functions(ctx); - - return ctx; -} - - -/* - * pipe_screen - */ -static void noop_flush_frontbuffer(struct pipe_screen *_screen, - struct pipe_resource *resource, - unsigned level, unsigned layer, - void *context_private, struct pipe_box *box) -{ -} - -static const char *noop_get_vendor(struct pipe_screen* pscreen) -{ - return "X.Org"; -} - -static const char *noop_get_device_vendor(struct pipe_screen* pscreen) -{ - return "NONE"; -} - -static const char *noop_get_name(struct pipe_screen* pscreen) -{ - return "NOOP"; -} - -static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) -{ - struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; - - return screen->get_param(screen, param); -} - -static float noop_get_paramf(struct pipe_screen* pscreen, - enum pipe_capf param) -{ - struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; - - return screen->get_paramf(screen, param); -} - -static int noop_get_shader_param(struct pipe_screen* pscreen, - enum pipe_shader_type shader, - enum pipe_shader_cap param) -{ - struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; - - return screen->get_shader_param(screen, shader, param); -} - -static int noop_get_compute_param(struct pipe_screen *pscreen, - enum pipe_shader_ir ir_type, - enum pipe_compute_cap param, - void *ret) -{ - struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; - - return screen->get_compute_param(screen, ir_type, param, ret); -} - -static boolean noop_is_format_supported(struct pipe_screen* pscreen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned sample_count, - unsigned usage) -{ - struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; - - return screen->is_format_supported(screen, format, target, sample_count, usage); -} - -static uint64_t noop_get_timestamp(struct pipe_screen *pscreen) -{ - return 0; -} - -static void noop_destroy_screen(struct pipe_screen *screen) -{ - struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; - struct pipe_screen *oscreen = noop_screen->oscreen; - - oscreen->destroy(oscreen); - FREE(screen); -} - -static void noop_fence_reference(struct pipe_screen *screen, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - -static boolean noop_fence_finish(struct pipe_screen *screen, - struct pipe_context *ctx, - struct pipe_fence_handle *fence, - uint64_t timeout) -{ - return true; -} - -static void noop_query_memory_info(struct pipe_screen *pscreen, - struct pipe_memory_info *info) -{ - struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; - struct pipe_screen *screen = noop_screen->oscreen; - - screen->query_memory_info(screen, info); -} - -struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) -{ - struct noop_pipe_screen *noop_screen; - struct pipe_screen *screen; - - if (!debug_get_option_noop()) { - return oscreen; - } - - noop_screen = CALLOC_STRUCT(noop_pipe_screen); - if (!noop_screen) { - return NULL; - } - noop_screen->oscreen = oscreen; - screen = &noop_screen->pscreen; - - screen->destroy = noop_destroy_screen; - screen->get_name = noop_get_name; - screen->get_vendor = noop_get_vendor; - screen->get_device_vendor = noop_get_device_vendor; - screen->get_param = noop_get_param; - screen->get_shader_param = noop_get_shader_param; - screen->get_compute_param = noop_get_compute_param; - screen->get_paramf = noop_get_paramf; - screen->is_format_supported = noop_is_format_supported; - screen->context_create = noop_create_context; - screen->resource_create = noop_resource_create; - screen->resource_from_handle = noop_resource_from_handle; - screen->resource_get_handle = noop_resource_get_handle; - screen->resource_destroy = noop_resource_destroy; - screen->flush_frontbuffer = noop_flush_frontbuffer; - screen->get_timestamp = noop_get_timestamp; - screen->fence_reference = noop_fence_reference; - screen->fence_finish = noop_fence_finish; - screen->query_memory_info = noop_query_memory_info; - - return screen; -} diff --git a/src/gallium/drivers/noop/noop_public.h b/src/gallium/drivers/noop/noop_public.h deleted file mode 100644 index 180ea597fab..00000000000 --- a/src/gallium/drivers/noop/noop_public.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 NOOP_PUBLIC_H -#define NOOP_PUBLIC_H - -struct pipe_screen; -struct pipe_screen *noop_screen_create(struct pipe_screen *screen); - -#endif diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c deleted file mode 100644 index 80cfae8ad49..00000000000 --- a/src/gallium/drivers/noop/noop_state.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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 -#include -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "util/u_memory.h" -#include "util/u_inlines.h" -#include "util/u_transfer.h" - -static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) -{ -} - -static void noop_launch_grid(struct pipe_context *ctx, - const struct pipe_grid_info *info) -{ -} - -static void noop_set_blend_color(struct pipe_context *ctx, - const struct pipe_blend_color *state) -{ -} - -static void *noop_create_blend_state(struct pipe_context *ctx, - const struct pipe_blend_state *state) -{ - return MALLOC(1); -} - -static void *noop_create_dsa_state(struct pipe_context *ctx, - const struct pipe_depth_stencil_alpha_state *state) -{ - return MALLOC(1); -} - -static void *noop_create_rs_state(struct pipe_context *ctx, - const struct pipe_rasterizer_state *state) -{ - return MALLOC(1); -} - -static void *noop_create_sampler_state(struct pipe_context *ctx, - const struct pipe_sampler_state *state) -{ - return MALLOC(1); -} - -static struct pipe_sampler_view *noop_create_sampler_view(struct pipe_context *ctx, - struct pipe_resource *texture, - const struct pipe_sampler_view *state) -{ - struct pipe_sampler_view *sampler_view = CALLOC_STRUCT(pipe_sampler_view); - - if (!sampler_view) - return NULL; - - /* initialize base object */ - *sampler_view = *state; - sampler_view->texture = NULL; - pipe_resource_reference(&sampler_view->texture, texture); - pipe_reference_init(&sampler_view->reference, 1); - sampler_view->context = ctx; - return sampler_view; -} - -static struct pipe_surface *noop_create_surface(struct pipe_context *ctx, - struct pipe_resource *texture, - const struct pipe_surface *surf_tmpl) -{ - struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); - - if (!surface) - return NULL; - pipe_reference_init(&surface->reference, 1); - pipe_resource_reference(&surface->texture, texture); - surface->context = ctx; - surface->format = surf_tmpl->format; - surface->width = texture->width0; - surface->height = texture->height0; - surface->texture = texture; - surface->u.tex.first_layer = surf_tmpl->u.tex.first_layer; - surface->u.tex.last_layer = surf_tmpl->u.tex.last_layer; - surface->u.tex.level = surf_tmpl->u.tex.level; - - return surface; -} - -static void noop_set_sampler_views(struct pipe_context *ctx, - enum pipe_shader_type shader, - unsigned start, unsigned count, - struct pipe_sampler_view **views) -{ -} - -static void noop_bind_sampler_states(struct pipe_context *ctx, - enum pipe_shader_type shader, - unsigned start, unsigned count, - void **states) -{ -} - -static void noop_set_clip_state(struct pipe_context *ctx, - const struct pipe_clip_state *state) -{ -} - -static void noop_set_polygon_stipple(struct pipe_context *ctx, - const struct pipe_poly_stipple *state) -{ -} - -static void noop_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) -{ -} - -static void noop_set_scissor_states(struct pipe_context *ctx, - unsigned start_slot, - unsigned num_scissors, - const struct pipe_scissor_state *state) -{ -} - -static void noop_set_stencil_ref(struct pipe_context *ctx, - const struct pipe_stencil_ref *state) -{ -} - -static void noop_set_viewport_states(struct pipe_context *ctx, - unsigned start_slot, - unsigned num_viewports, - const struct pipe_viewport_state *state) -{ -} - -static void noop_set_framebuffer_state(struct pipe_context *ctx, - const struct pipe_framebuffer_state *state) -{ -} - -static void noop_set_constant_buffer(struct pipe_context *ctx, - enum pipe_shader_type shader, uint index, - const struct pipe_constant_buffer *cb) -{ -} - - -static void noop_sampler_view_destroy(struct pipe_context *ctx, - struct pipe_sampler_view *state) -{ - pipe_resource_reference(&state->texture, NULL); - FREE(state); -} - - -static void noop_surface_destroy(struct pipe_context *ctx, - struct pipe_surface *surface) -{ - pipe_resource_reference(&surface->texture, NULL); - FREE(surface); -} - -static void noop_bind_state(struct pipe_context *ctx, void *state) -{ -} - -static void noop_delete_state(struct pipe_context *ctx, void *state) -{ - FREE(state); -} - -static void noop_set_vertex_buffers(struct pipe_context *ctx, - unsigned start_slot, unsigned count, - const struct pipe_vertex_buffer *buffers) -{ -} - -static void *noop_create_vertex_elements(struct pipe_context *ctx, - unsigned count, - const struct pipe_vertex_element *state) -{ - return MALLOC(1); -} - -static void *noop_create_shader_state(struct pipe_context *ctx, - const struct pipe_shader_state *state) -{ - return MALLOC(1); -} - -static void *noop_create_compute_state(struct pipe_context *ctx, - const struct pipe_compute_state *state) -{ - return MALLOC(1); -} - -static struct pipe_stream_output_target *noop_create_stream_output_target( - struct pipe_context *ctx, - struct pipe_resource *res, - unsigned buffer_offset, - unsigned buffer_size) -{ - struct pipe_stream_output_target *t = CALLOC_STRUCT(pipe_stream_output_target); - if (!t) - return NULL; - - pipe_reference_init(&t->reference, 1); - pipe_resource_reference(&t->buffer, res); - t->buffer_offset = buffer_offset; - t->buffer_size = buffer_size; - return t; -} - -static void noop_stream_output_target_destroy(struct pipe_context *ctx, - struct pipe_stream_output_target *t) -{ - pipe_resource_reference(&t->buffer, NULL); - FREE(t); -} - -static void noop_set_stream_output_targets(struct pipe_context *ctx, - unsigned num_targets, - struct pipe_stream_output_target **targets, - const unsigned *offsets) -{ -} - -void noop_init_state_functions(struct pipe_context *ctx); - -void noop_init_state_functions(struct pipe_context *ctx) -{ - ctx->create_blend_state = noop_create_blend_state; - ctx->create_depth_stencil_alpha_state = noop_create_dsa_state; - ctx->create_fs_state = noop_create_shader_state; - ctx->create_rasterizer_state = noop_create_rs_state; - ctx->create_sampler_state = noop_create_sampler_state; - ctx->create_sampler_view = noop_create_sampler_view; - ctx->create_surface = noop_create_surface; - ctx->create_vertex_elements_state = noop_create_vertex_elements; - ctx->create_compute_state = noop_create_compute_state; - ctx->create_tcs_state = noop_create_shader_state; - ctx->create_tes_state = noop_create_shader_state; - ctx->create_gs_state = noop_create_shader_state; - ctx->create_vs_state = noop_create_shader_state; - ctx->bind_blend_state = noop_bind_state; - ctx->bind_depth_stencil_alpha_state = noop_bind_state; - ctx->bind_sampler_states = noop_bind_sampler_states; - ctx->bind_fs_state = noop_bind_state; - ctx->bind_rasterizer_state = noop_bind_state; - ctx->bind_vertex_elements_state = noop_bind_state; - ctx->bind_compute_state = noop_bind_state; - ctx->bind_tcs_state = noop_bind_state; - ctx->bind_tes_state = noop_bind_state; - ctx->bind_gs_state = noop_bind_state; - ctx->bind_vs_state = noop_bind_state; - ctx->delete_blend_state = noop_delete_state; - ctx->delete_depth_stencil_alpha_state = noop_delete_state; - ctx->delete_fs_state = noop_delete_state; - ctx->delete_rasterizer_state = noop_delete_state; - ctx->delete_sampler_state = noop_delete_state; - ctx->delete_vertex_elements_state = noop_delete_state; - ctx->delete_compute_state = noop_delete_state; - ctx->delete_tcs_state = noop_delete_state; - ctx->delete_tes_state = noop_delete_state; - ctx->delete_gs_state = noop_delete_state; - ctx->delete_vs_state = noop_delete_state; - ctx->set_blend_color = noop_set_blend_color; - ctx->set_clip_state = noop_set_clip_state; - ctx->set_constant_buffer = noop_set_constant_buffer; - ctx->set_sampler_views = noop_set_sampler_views; - ctx->set_framebuffer_state = noop_set_framebuffer_state; - ctx->set_polygon_stipple = noop_set_polygon_stipple; - ctx->set_sample_mask = noop_set_sample_mask; - ctx->set_scissor_states = noop_set_scissor_states; - ctx->set_stencil_ref = noop_set_stencil_ref; - ctx->set_vertex_buffers = noop_set_vertex_buffers; - ctx->set_viewport_states = noop_set_viewport_states; - ctx->sampler_view_destroy = noop_sampler_view_destroy; - ctx->surface_destroy = noop_surface_destroy; - ctx->draw_vbo = noop_draw_vbo; - ctx->launch_grid = noop_launch_grid; - ctx->create_stream_output_target = noop_create_stream_output_target; - ctx->stream_output_target_destroy = noop_stream_output_target_destroy; - ctx->set_stream_output_targets = noop_set_stream_output_targets; -} diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c index 817a6d5ee92..b7d40db21cb 100644 --- a/src/gallium/drivers/radeonsi/si_debug.c +++ b/src/gallium/drivers/radeonsi/si_debug.c @@ -27,7 +27,7 @@ #include "sid.h" #include "gfx9d.h" #include "sid_tables.h" -#include "ddebug/dd_util.h" +#include "driver_ddebug/dd_util.h" #include "util/u_dump.h" #include "util/u_log.h" #include "util/u_memory.h" diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 4928e6f5f3a..466546b76b7 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -37,7 +37,7 @@ #include "util/u_upload_mgr.h" #include "util/xmlconfig.h" #include "vl/vl_decoder.h" -#include "../ddebug/dd_util.h" +#include "driver_ddebug/dd_util.h" static const struct debug_named_value debug_options[] = { /* Shader logging options: */ diff --git a/src/gallium/drivers/rbug/Makefile.am b/src/gallium/drivers/rbug/Makefile.am deleted file mode 100644 index c784d84232e..00000000000 --- a/src/gallium/drivers/rbug/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright © 2012 Intel Corporation -# -# 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, sublicense, -# 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 -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS 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 Makefile.sources -include $(top_srcdir)/src/gallium/Automake.inc - -AM_CFLAGS = \ - $(GALLIUM_DRIVER_CFLAGS) - -noinst_LTLIBRARIES = librbug.la - -librbug_la_SOURCES = $(C_SOURCES) - -EXTRA_DIST = SConscript README meson.build diff --git a/src/gallium/drivers/rbug/Makefile.sources b/src/gallium/drivers/rbug/Makefile.sources deleted file mode 100644 index f9f1d5c3a49..00000000000 --- a/src/gallium/drivers/rbug/Makefile.sources +++ /dev/null @@ -1,9 +0,0 @@ -C_SOURCES := \ - rbug_context.c \ - rbug_context.h \ - rbug_core.c \ - rbug_objects.c \ - rbug_objects.h \ - rbug_public.h \ - rbug_screen.c \ - rbug_screen.h diff --git a/src/gallium/drivers/rbug/README b/src/gallium/drivers/rbug/README deleted file mode 100644 index 0edf0ad89de..00000000000 --- a/src/gallium/drivers/rbug/README +++ /dev/null @@ -1,44 +0,0 @@ - RBUG PIPE DRIVER - - -= About = - -This directory contains a Gallium3D remote debugger pipe driver. -It provides remote debugging functionality. - - -= Usage = - -Do - - GALLIUM_RBUG=true progs/trivial/tri - -which should open gallium remote debugging session. While the program is running -you can launch the small remote debugging application from progs/rbug. More -information is in that directory. Also for a gui see: - - http://cgit.freedesktop.org/mesa/rbug-gui - - -= Integrating = - -You can integrate the rbug pipe driver either inside the state tracker or the -target. The procedure on both cases is the same. Let's assume you have a -pipe_screen obtained by the usual means (variable and function names are just -for illustration purposes): - - real_screen = real_screen_create(...); - -The rbug screen is then created by doing - - rbug_screen = rbug_screen_create(real_screen); - -You can then simply use rbug_screen instead of real_screen. - -You can create as many contexts you wish from rbug_screen::context_create they -are automatically wrapped by rbug_screen. - - --- -Jose Fonseca -Jakob Bornecrantz diff --git a/src/gallium/drivers/rbug/SConscript b/src/gallium/drivers/rbug/SConscript deleted file mode 100644 index 63209abac2e..00000000000 --- a/src/gallium/drivers/rbug/SConscript +++ /dev/null @@ -1,12 +0,0 @@ -Import('*') - -env = env.Clone() - -rbug = env.ConvenienceLibrary( - target = 'rbug', - source = env.ParseSourceList('Makefile.sources', 'C_SOURCES') - ) - -env.Alias('rbug', rbug) - -Export('rbug') diff --git a/src/gallium/drivers/rbug/meson.build b/src/gallium/drivers/rbug/meson.build deleted file mode 100644 index 9c74171f7b5..00000000000 --- a/src/gallium/drivers/rbug/meson.build +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright © 2017 Dylan Baker - -# 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS 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. - -librbug = static_library( - 'rbug', - files('rbug_context.c', 'rbug_context.h', 'rbug_core.c', 'rbug_objects.c', - 'rbug_objects.h', 'rbug_public.h', 'rbug_screen.c', 'rbug_screen.h'), - include_directories : [inc_gallium, inc_gallium_aux, inc_include, inc_src], - c_args : [c_vis_args], - build_by_default : false, -) diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c deleted file mode 100644 index e1f3c4f2844..00000000000 --- a/src/gallium/drivers/rbug/rbug_context.c +++ /dev/null @@ -1,1274 +0,0 @@ -/************************************************************************** - * - * 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 "util/simple_list.h" - -#include "rbug/rbug_context.h" - -#include "rbug_context.h" -#include "rbug_objects.h" - - -static void -rbug_destroy(struct pipe_context *_pipe) -{ - struct rbug_screen *rb_screen = rbug_screen(_pipe->screen); - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - rbug_screen_remove_from_list(rb_screen, contexts, rb_pipe); - - mtx_lock(&rb_pipe->call_mutex); - pipe->destroy(pipe); - rb_pipe->pipe = NULL; - mtx_unlock(&rb_pipe->call_mutex); - - FREE(rb_pipe); -} - -static void -rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag) -{ - - if (rb_pipe->draw_blocker & flag) { - rb_pipe->draw_blocked |= flag; - } else if ((rb_pipe->draw_rule.blocker & flag) && - (rb_pipe->draw_blocker & RBUG_BLOCK_RULE)) { - unsigned k; - boolean block = FALSE; - unsigned sh; - - debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__, - (void *) rb_pipe->draw_rule.shader[PIPE_SHADER_FRAGMENT], - (void *) rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT], - (void *) rb_pipe->draw_rule.shader[PIPE_SHADER_VERTEX], - (void *) rb_pipe->curr.shader[PIPE_SHADER_VERTEX], - (void *) rb_pipe->draw_rule.surf, 0, - (void *) rb_pipe->draw_rule.texture, 0); - for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { - if (rb_pipe->draw_rule.shader[sh] && - rb_pipe->draw_rule.shader[sh] == rb_pipe->curr.shader[sh]) - block = TRUE; - } - - if (rb_pipe->draw_rule.surf && - rb_pipe->draw_rule.surf == rb_pipe->curr.zsbuf) - block = TRUE; - if (rb_pipe->draw_rule.surf) - for (k = 0; k < rb_pipe->curr.nr_cbufs; k++) - if (rb_pipe->draw_rule.surf == rb_pipe->curr.cbufs[k]) - block = TRUE; - if (rb_pipe->draw_rule.texture) { - for (sh = 0; sh < ARRAY_SIZE(rb_pipe->curr.num_views); sh++) { - for (k = 0; k < rb_pipe->curr.num_views[sh]; k++) { - if (rb_pipe->draw_rule.texture == rb_pipe->curr.texs[sh][k]) { - block = TRUE; - sh = PIPE_SHADER_TYPES; /* to break out of both loops */ - break; - } - } - } - } - - if (block) - rb_pipe->draw_blocked |= (flag | RBUG_BLOCK_RULE); - } - - if (rb_pipe->draw_blocked) - rbug_notify_draw_blocked(rb_pipe); - - /* wait for rbug to clear the blocked flag */ - while (rb_pipe->draw_blocked & flag) { - rb_pipe->draw_blocked |= flag; - cnd_wait(&rb_pipe->draw_cond, &rb_pipe->draw_mutex); - } - -} - -static void -rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->draw_mutex); - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - - mtx_lock(&rb_pipe->call_mutex); - /* XXX loop over PIPE_SHADER_x here */ - if (!(rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT] && rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT]->disabled) && - !(rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY] && rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY]->disabled) && - !(rb_pipe->curr.shader[PIPE_SHADER_VERTEX] && rb_pipe->curr.shader[PIPE_SHADER_VERTEX]->disabled)) - pipe->draw_vbo(pipe, info); - mtx_unlock(&rb_pipe->call_mutex); - - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); - mtx_unlock(&rb_pipe->draw_mutex); -} - -static struct pipe_query * -rbug_create_query(struct pipe_context *_pipe, - unsigned query_type, - unsigned index) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_query *query; - - mtx_lock(&rb_pipe->call_mutex); - query = pipe->create_query(pipe, - query_type, - index); - mtx_unlock(&rb_pipe->call_mutex); - return query; -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->destroy_query(pipe, - query); - mtx_unlock(&rb_pipe->call_mutex); -} - -static boolean -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; - boolean ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->begin_query(pipe, query); - mtx_unlock(&rb_pipe->call_mutex); - return ret; -} - -static bool -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; - bool ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->end_query(pipe, - query); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -static boolean -rbug_get_query_result(struct pipe_context *_pipe, - struct pipe_query *query, - boolean wait, - union pipe_query_result *result) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - boolean ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->get_query_result(pipe, - query, - wait, - result); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -static void -rbug_set_active_query_state(struct pipe_context *_pipe, boolean enable) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_active_query_state(pipe, enable); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - void *ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->create_blend_state(pipe, - blend); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->bind_blend_state(pipe, - blend); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->delete_blend_state(pipe, - blend); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - void *ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->create_sampler_state(pipe, - sampler); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -static void -rbug_bind_sampler_states(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, unsigned count, - void **samplers) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->bind_sampler_states(pipe, shader, start, count, samplers); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->delete_sampler_state(pipe, - sampler); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - void *ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->create_rasterizer_state(pipe, - rasterizer); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->bind_rasterizer_state(pipe, - rasterizer); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->delete_rasterizer_state(pipe, - rasterizer); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - void *ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->create_depth_stencil_alpha_state(pipe, - depth_stencil_alpha); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->bind_depth_stencil_alpha_state(pipe, - depth_stencil_alpha); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->delete_depth_stencil_alpha_state(pipe, - depth_stencil_alpha); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void * -rbug_create_fs_state(struct pipe_context *_pipe, - const struct pipe_shader_state *state) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - void *result; - - mtx_lock(&rb_pipe->call_mutex); - result = pipe->create_fs_state(pipe, state); - mtx_unlock(&rb_pipe->call_mutex); - - if (!result) - return NULL; - - return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_FRAGMENT); -} - -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; - void *fs; - - mtx_lock(&rb_pipe->call_mutex); - - fs = rbug_shader_unwrap(_fs); - rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT] = rbug_shader(_fs); - pipe->bind_fs_state(pipe, - fs); - - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_delete_fs_state(struct pipe_context *_pipe, - void *_fs) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_shader *rb_shader = rbug_shader(_fs); - - mtx_lock(&rb_pipe->call_mutex); - rbug_shader_destroy(rb_pipe, rb_shader); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void * -rbug_create_vs_state(struct pipe_context *_pipe, - const struct pipe_shader_state *state) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - void *result; - - mtx_lock(&rb_pipe->call_mutex); - result = pipe->create_vs_state(pipe, state); - mtx_unlock(&rb_pipe->call_mutex); - - if (!result) - return NULL; - - return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_VERTEX); -} - -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; - void *vs; - - mtx_lock(&rb_pipe->call_mutex); - - vs = rbug_shader_unwrap(_vs); - rb_pipe->curr.shader[PIPE_SHADER_VERTEX] = rbug_shader(_vs); - pipe->bind_vs_state(pipe, - vs); - - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_delete_vs_state(struct pipe_context *_pipe, - void *_vs) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_shader *rb_shader = rbug_shader(_vs); - - mtx_unlock(&rb_pipe->call_mutex); - rbug_shader_destroy(rb_pipe, rb_shader); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void * -rbug_create_gs_state(struct pipe_context *_pipe, - const struct pipe_shader_state *state) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - void *result; - - mtx_lock(&rb_pipe->call_mutex); - result = pipe->create_gs_state(pipe, state); - mtx_unlock(&rb_pipe->call_mutex); - - if (!result) - return NULL; - - return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_GEOM); -} - -static void -rbug_bind_gs_state(struct pipe_context *_pipe, - void *_gs) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - void *gs; - - mtx_lock(&rb_pipe->call_mutex); - - gs = rbug_shader_unwrap(_gs); - rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY] = rbug_shader(_gs); - pipe->bind_gs_state(pipe, - gs); - - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_delete_gs_state(struct pipe_context *_pipe, - void *_gs) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_shader *rb_shader = rbug_shader(_gs); - - mtx_lock(&rb_pipe->call_mutex); - rbug_shader_destroy(rb_pipe, rb_shader); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - void *ret; - - mtx_lock(&rb_pipe->call_mutex); - ret = pipe->create_vertex_elements_state(pipe, - num_elements, - vertex_elements); - mtx_unlock(&rb_pipe->call_mutex); - - return ret; -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->bind_vertex_elements_state(pipe, - velems); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->delete_vertex_elements_state(pipe, - velems); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_blend_color(pipe, - blend_color); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_stencil_ref(pipe, - stencil_ref); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_clip_state(pipe, - clip); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_constant_buffer(struct pipe_context *_pipe, - enum pipe_shader_type shader, - uint index, - const struct pipe_constant_buffer *_cb) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_constant_buffer cb; - - /* XXX hmm? unwrap the input state */ - if (_cb) { - cb = *_cb; - cb.buffer = rbug_resource_unwrap(_cb->buffer); - } - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_constant_buffer(pipe, - shader, - index, - _cb ? &cb : NULL); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - /* must protect curr status */ - mtx_lock(&rb_pipe->call_mutex); - - rb_pipe->curr.nr_cbufs = 0; - memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs)); - rb_pipe->curr.zsbuf = NULL; - - /* unwrap the input state */ - if (_state) { - memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); - - rb_pipe->curr.nr_cbufs = _state->nr_cbufs; - for(i = 0; i < _state->nr_cbufs; i++) { - unwrapped_state.cbufs[i] = rbug_surface_unwrap(_state->cbufs[i]); - if (_state->cbufs[i]) - rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture); - } - unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf); - if (_state->zsbuf) - rb_pipe->curr.zsbuf = rbug_resource(_state->zsbuf->texture); - state = &unwrapped_state; - } - - pipe->set_framebuffer_state(pipe, - state); - - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_polygon_stipple(pipe, - poly_stipple); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_scissor_states(struct pipe_context *_pipe, - unsigned start_slot, - unsigned num_scissors, - const struct pipe_scissor_state *scissor) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_scissor_states(pipe, start_slot, num_scissors, scissor); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_viewport_states(struct pipe_context *_pipe, - unsigned start_slot, - unsigned num_viewports, - const struct pipe_viewport_state *viewport) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_viewport_states(pipe, start_slot, num_viewports, viewport); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_sampler_views(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, - 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_SHADER_SAMPLER_VIEWS]; - struct pipe_sampler_view **views = NULL; - unsigned i; - - assert(start == 0); /* XXX fix */ - - /* must protect curr status */ - mtx_lock(&rb_pipe->call_mutex); - - rb_pipe->curr.num_views[shader] = 0; - memset(rb_pipe->curr.views[shader], 0, sizeof(rb_pipe->curr.views[shader])); - memset(rb_pipe->curr.texs[shader], 0, sizeof(rb_pipe->curr.texs[shader])); - memset(unwrapped_views, 0, sizeof(unwrapped_views)); - - if (_views) { - rb_pipe->curr.num_views[shader] = num; - for (i = 0; i < num; i++) { - rb_pipe->curr.views[shader][i] = rbug_sampler_view(_views[i]); - rb_pipe->curr.texs[shader][i] = rbug_resource(_views[i] ? _views[i]->texture : NULL); - unwrapped_views[i] = rbug_sampler_view_unwrap(_views[i]); - } - views = unwrapped_views; - } - - pipe->set_sampler_views(pipe, shader, start, num, views); - - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_vertex_buffers(struct pipe_context *_pipe, - unsigned start_slot, 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; - - mtx_lock(&rb_pipe->call_mutex); - - if (num_buffers && _buffers) { - memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); - for (i = 0; i < num_buffers; i++) { - if (!_buffers[i].is_user_buffer) - unwrapped_buffers[i].buffer.resource = - rbug_resource_unwrap(_buffers[i].buffer.resource); - } - buffers = unwrapped_buffers; - } - - pipe->set_vertex_buffers(pipe, start_slot, - num_buffers, - buffers); - - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_sample_mask(struct pipe_context *_pipe, - unsigned sample_mask) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_sample_mask(pipe, sample_mask); - mtx_unlock(&rb_pipe->call_mutex); -} - -static struct pipe_stream_output_target * -rbug_create_stream_output_target(struct pipe_context *_pipe, - struct pipe_resource *_res, - unsigned buffer_offset, unsigned buffer_size) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *res = rbug_resource_unwrap(_res); - struct pipe_stream_output_target *target; - - mtx_lock(&rb_pipe->call_mutex); - target = pipe->create_stream_output_target(pipe, res, buffer_offset, - buffer_size); - mtx_unlock(&rb_pipe->call_mutex); - return target; -} - -static void -rbug_stream_output_target_destroy(struct pipe_context *_pipe, - struct pipe_stream_output_target *target) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->stream_output_target_destroy(pipe, target); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_set_stream_output_targets(struct pipe_context *_pipe, - unsigned num_targets, - struct pipe_stream_output_target **targets, - const unsigned *offsets) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->set_stream_output_targets(pipe, num_targets, targets, offsets); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_resource_copy_region(struct pipe_context *_pipe, - struct pipe_resource *_dst, - unsigned dst_level, - unsigned dstx, - unsigned dsty, - unsigned dstz, - struct pipe_resource *_src, - unsigned src_level, - const struct pipe_box *src_box) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource_dst = rbug_resource(_dst); - struct rbug_resource *rb_resource_src = rbug_resource(_src); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *dst = rb_resource_dst->resource; - struct pipe_resource *src = rb_resource_src->resource; - - mtx_lock(&rb_pipe->call_mutex); - pipe->resource_copy_region(pipe, - dst, - dst_level, - dstx, - dsty, - dstz, - src, - src_level, - src_box); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_blit(struct pipe_context *_pipe, const struct pipe_blit_info *_blit_info) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource_dst = rbug_resource(_blit_info->dst.resource); - struct rbug_resource *rb_resource_src = rbug_resource(_blit_info->src.resource); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *dst = rb_resource_dst->resource; - struct pipe_resource *src = rb_resource_src->resource; - struct pipe_blit_info blit_info; - - blit_info = *_blit_info; - blit_info.dst.resource = dst; - blit_info.src.resource = src; - - mtx_lock(&rb_pipe->call_mutex); - pipe->blit(pipe, &blit_info); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_flush_resource(struct pipe_context *_pipe, - struct pipe_resource *_res) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource_res = rbug_resource(_res); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *res = rb_resource_res->resource; - - mtx_lock(&rb_pipe->call_mutex); - pipe->flush_resource(pipe, res); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_clear(struct pipe_context *_pipe, - unsigned buffers, - const union pipe_color_union *color, - double depth, - unsigned stencil) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->clear(pipe, - buffers, - color, - depth, - stencil); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_clear_render_target(struct pipe_context *_pipe, - struct pipe_surface *_dst, - const union pipe_color_union *color, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ - 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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->clear_render_target(pipe, - dst, - color, - dstx, - dsty, - width, - height, - render_condition_enabled); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_clear_depth_stencil(struct pipe_context *_pipe, - struct pipe_surface *_dst, - unsigned clear_flags, - double depth, - unsigned stencil, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ - 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; - - mtx_lock(&rb_pipe->call_mutex); - pipe->clear_depth_stencil(pipe, - dst, - clear_flags, - depth, - stencil, - dstx, - dsty, - width, - height, - render_condition_enabled); - mtx_unlock(&rb_pipe->call_mutex); -} - -static void -rbug_flush(struct pipe_context *_pipe, - struct pipe_fence_handle **fence, - unsigned flags) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; - - mtx_lock(&rb_pipe->call_mutex); - pipe->flush(pipe, fence, flags); - mtx_unlock(&rb_pipe->call_mutex); -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - result = pipe->create_sampler_view(pipe, - resource, - templ); - mtx_unlock(&rb_pipe->call_mutex); - - 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_surface * -rbug_context_create_surface(struct pipe_context *_pipe, - struct pipe_resource *_resource, - const struct pipe_surface *surf_tmpl) -{ - 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_surface *result; - - mtx_lock(&rb_pipe->call_mutex); - result = pipe->create_surface(pipe, - resource, - surf_tmpl); - mtx_unlock(&rb_pipe->call_mutex); - - if (result) - return rbug_surface_create(rb_pipe, rb_resource, result); - return NULL; -} - -static void -rbug_context_surface_destroy(struct pipe_context *_pipe, - struct pipe_surface *_surface) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_surface *rb_surface = rbug_surface(_surface); - - mtx_lock(&rb_pipe->call_mutex); - rbug_surface_destroy(rb_pipe, - rb_surface); - mtx_unlock(&rb_pipe->call_mutex); -} - - - -static void * -rbug_context_transfer_map(struct pipe_context *_context, - struct pipe_resource *_resource, - unsigned level, - unsigned usage, - const struct pipe_box *box, - struct pipe_transfer **transfer) -{ - 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; - void *map; - - mtx_lock(&rb_pipe->call_mutex); - map = context->transfer_map(context, - resource, - level, - usage, - box, &result); - mtx_unlock(&rb_pipe->call_mutex); - - *transfer = rbug_transfer_create(rb_pipe, rb_resource, result); - return *transfer ? map : NULL; -} - -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; - - mtx_lock(&rb_pipe->call_mutex); - context->transfer_flush_region(context, - transfer, - box); - mtx_unlock(&rb_pipe->call_mutex); -} - - -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; - - mtx_lock(&rb_pipe->call_mutex); - context->transfer_unmap(context, - transfer); - rbug_transfer_destroy(rb_pipe, - rb_transfer); - mtx_unlock(&rb_pipe->call_mutex); -} - - -static void -rbug_context_buffer_subdata(struct pipe_context *_context, - struct pipe_resource *_resource, - unsigned usage, unsigned offset, - unsigned size, const void *data) -{ - 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; - - mtx_lock(&rb_pipe->call_mutex); - context->buffer_subdata(context, resource, usage, offset, size, data); - mtx_unlock(&rb_pipe->call_mutex); -} - - -static void -rbug_context_texture_subdata(struct pipe_context *_context, - struct pipe_resource *_resource, - unsigned level, - unsigned usage, - const struct pipe_box *box, - const void *data, - unsigned stride, - unsigned layer_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; - - mtx_lock(&rb_pipe->call_mutex); - context->texture_subdata(context, - resource, - level, - usage, - box, - data, - stride, - layer_stride); - mtx_unlock(&rb_pipe->call_mutex); -} - - -struct pipe_context * -rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) -{ - struct rbug_context *rb_pipe; - struct rbug_screen *rb_screen = rbug_screen(_screen); - - if (!rb_screen) - return NULL; - - rb_pipe = CALLOC_STRUCT(rbug_context); - if (!rb_pipe) - return NULL; - - (void) mtx_init(&rb_pipe->draw_mutex, mtx_plain); - cnd_init(&rb_pipe->draw_cond); - (void) mtx_init(&rb_pipe->call_mutex, mtx_plain); - (void) mtx_init(&rb_pipe->list_mutex, mtx_plain); - make_empty_list(&rb_pipe->shaders); - - rb_pipe->base.screen = _screen; - rb_pipe->base.priv = pipe->priv; /* expose wrapped data */ - rb_pipe->base.draw = NULL; - rb_pipe->base.stream_uploader = pipe->stream_uploader; - rb_pipe->base.const_uploader = pipe->const_uploader; - - rb_pipe->base.destroy = rbug_destroy; - rb_pipe->base.draw_vbo = rbug_draw_vbo; - 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.set_active_query_state = rbug_set_active_query_state; - 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_sampler_states = rbug_bind_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_gs_state = rbug_create_gs_state; - rb_pipe->base.bind_gs_state = rbug_bind_gs_state; - rb_pipe->base.delete_gs_state = rbug_delete_gs_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_states = rbug_set_scissor_states; - rb_pipe->base.set_viewport_states = rbug_set_viewport_states; - rb_pipe->base.set_sampler_views = rbug_set_sampler_views; - rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers; - rb_pipe->base.set_sample_mask = rbug_set_sample_mask; - rb_pipe->base.create_stream_output_target = rbug_create_stream_output_target; - rb_pipe->base.stream_output_target_destroy = rbug_stream_output_target_destroy; - rb_pipe->base.set_stream_output_targets = rbug_set_stream_output_targets; - rb_pipe->base.resource_copy_region = rbug_resource_copy_region; - rb_pipe->base.blit = rbug_blit; - rb_pipe->base.flush_resource = rbug_flush_resource; - rb_pipe->base.clear = rbug_clear; - rb_pipe->base.clear_render_target = rbug_clear_render_target; - rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil; - rb_pipe->base.flush = rbug_flush; - 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.create_surface = rbug_context_create_surface; - rb_pipe->base.surface_destroy = rbug_context_surface_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.buffer_subdata = rbug_context_buffer_subdata; - rb_pipe->base.texture_subdata = rbug_context_texture_subdata; - - rb_pipe->pipe = pipe; - - rbug_screen_add_to_list(rb_screen, contexts, rb_pipe); - - if (debug_get_bool_option("GALLIUM_RBUG_START_BLOCKED", FALSE)) { - rb_pipe->draw_blocked = RBUG_BLOCK_BEFORE; - } - - return &rb_pipe->base; -} diff --git a/src/gallium/drivers/rbug/rbug_context.h b/src/gallium/drivers/rbug/rbug_context.h deleted file mode 100644 index e89c6eaac01..00000000000 --- a/src/gallium/drivers/rbug/rbug_context.h +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************** - * - * 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 */ - mtx_t call_mutex; - - /* current state */ - struct { - struct rbug_shader *shader[PIPE_SHADER_TYPES]; - - struct rbug_sampler_view *views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; - struct rbug_resource *texs[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; - unsigned num_views[PIPE_SHADER_TYPES]; - - unsigned nr_cbufs; - struct rbug_resource *cbufs[PIPE_MAX_COLOR_BUFS]; - struct rbug_resource *zsbuf; - } curr; - - /* draw locking */ - mtx_t draw_mutex; - cnd_t draw_cond; - unsigned draw_num_rules; - int draw_blocker; - int draw_blocked; - - struct { - struct rbug_shader *shader[PIPE_SHADER_TYPES]; - - struct rbug_resource *texture; - struct rbug_resource *surf; - - int blocker; - } draw_rule; - - /* list of state objects */ - mtx_t 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 deleted file mode 100644 index 76394039b9b..00000000000 --- a/src/gallium/drivers/rbug/rbug_core.c +++ /dev/null @@ -1,888 +0,0 @@ -/************************************************************************** - * - * 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/simple_list.h" -#include "util/u_network.h" -#include "util/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)) - -#define container_of(ptr, type, field) \ - (type*)((char*)ptr - offsetof(type, field)) - -struct rbug_rbug -{ - struct rbug_screen *rb_screen; - struct rbug_connection *con; - thrd_t thread; - boolean running; -}; - -int -rbug_thread(void *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 = container_of(ptr, 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 = container_of(ptr, 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 *rb_shader, - struct tgsi_token *tokens) -{ - void *state = NULL; - struct pipe_shader_state pss; - memset(&pss, 0, sizeof(pss)); - pss.tokens = tokens; - - switch(rb_shader->type) { - case RBUG_SHADER_FRAGMENT: - state = pipe->create_fs_state(pipe, &pss); - break; - case RBUG_SHADER_VERTEX: - state = pipe->create_vs_state(pipe, &pss); - break; - case RBUG_SHADER_GEOM: - state = pipe->create_gs_state(pipe, &pss); - break; - default: - assert(0); - break; - } - - return state; -} - -static void -rbug_shader_bind_locked(struct pipe_context *pipe, - struct rbug_shader *rb_shader, - void *state) -{ - switch(rb_shader->type) { - case RBUG_SHADER_FRAGMENT: - pipe->bind_fs_state(pipe, state); - break; - case RBUG_SHADER_VERTEX: - pipe->bind_vs_state(pipe, state); - break; - case RBUG_SHADER_GEOM: - pipe->bind_gs_state(pipe, state); - break; - default: - assert(0); - break; - } -} - -static void -rbug_shader_delete_locked(struct pipe_context *pipe, - struct rbug_shader *rb_shader, - void *state) -{ - switch(rb_shader->type) { - case RBUG_SHADER_FRAGMENT: - pipe->delete_fs_state(pipe, state); - break; - case RBUG_SHADER_VERTEX: - pipe->delete_vs_state(pipe, state); - break; - case RBUG_SHADER_GEOM: - pipe->delete_gs_state(pipe, state); - break; - default: - assert(0); - break; - } -} - -/************************************************ - * 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; - - mtx_lock(&rb_screen->list_mutex); - texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t)); - foreach(ptr, &rb_screen->resources) { - tr_tex = container_of(ptr, struct rbug_resource, list); - texs[i++] = VOID2U64(tr_tex); - } - mtx_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; - uint16_t num_layers; - - mtx_lock(&rb_screen->list_mutex); - foreach(ptr, &rb_screen->resources) { - tr_tex = container_of(ptr, struct rbug_resource, list); - if (gpti->texture == VOID2U64(tr_tex)) - break; - tr_tex = NULL; - } - - if (!tr_tex) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - t = tr_tex->resource; - num_layers = util_num_layers(t, 0); - - rbug_send_texture_info_reply(tr_rbug->con, serial, - t->target, t->format, - &t->width0, 1, - &t->height0, 1, - &num_layers, 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); - - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - foreach(ptr, &rb_screen->resources) { - tr_tex = container_of(ptr, struct rbug_resource, list); - if (gptr->texture == VOID2U64(tr_tex)) - break; - tr_tex = NULL; - } - - if (!tr_tex) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - tex = tr_tex->resource; - map = pipe_transfer_map(context, tex, - gptr->level, gptr->face + gptr->zslice, - PIPE_TRANSFER_READ, - gptr->x, gptr->y, gptr->w, gptr->h, &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); - - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t)); - foreach(ptr, &rb_screen->contexts) { - rb_context = container_of(ptr, struct rbug_context, list); - ctxs[i++] = VOID2U64(rb_context); - } - mtx_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_SHADER_SAMPLER_VIEWS]; - unsigned i; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, info->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - /* protect the pipe context */ - mtx_lock(&rb_context->draw_mutex); - mtx_lock(&rb_context->call_mutex); - - for (i = 0; i < rb_context->curr.nr_cbufs; i++) - cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]); - - /* XXX what about vertex/geometry shader texture views? */ - for (i = 0; i < rb_context->curr.num_views[PIPE_SHADER_FRAGMENT]; i++) - texs[i] = VOID2U64(rb_context->curr.texs[PIPE_SHADER_FRAGMENT][i]); - - rbug_send_context_info_reply(tr_rbug->con, serial, - VOID2U64(rb_context->curr.shader[PIPE_SHADER_VERTEX]), VOID2U64(rb_context->curr.shader[PIPE_SHADER_FRAGMENT]), - texs, rb_context->curr.num_views[PIPE_SHADER_FRAGMENT], - cbufs, rb_context->curr.nr_cbufs, - VOID2U64(rb_context->curr.zsbuf), - rb_context->draw_blocker, rb_context->draw_blocked, NULL); - - mtx_unlock(&rb_context->call_mutex); - mtx_unlock(&rb_context->draw_mutex); - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, block->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_lock(&rb_context->draw_mutex); - rb_context->draw_blocker |= block->block; - mtx_unlock(&rb_context->draw_mutex); - - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, step->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_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; - } - mtx_unlock(&rb_context->draw_mutex); - - cnd_broadcast(&rb_context->draw_cond); - - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, unblock->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_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; - mtx_unlock(&rb_context->draw_mutex); - - cnd_broadcast(&rb_context->draw_cond); - - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, rule->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_lock(&rb_context->draw_mutex); - rb_context->draw_rule.shader[PIPE_SHADER_VERTEX] = U642VOID(rule->vertex); - rb_context->draw_rule.shader[PIPE_SHADER_FRAGMENT] = U642VOID(rule->fragment); - rb_context->draw_rule.texture = 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; - mtx_unlock(&rb_context->draw_mutex); - - cnd_broadcast(&rb_context->draw_cond); - - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, flush->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - /* protect the pipe context */ - mtx_lock(&rb_context->call_mutex); - - rb_context->pipe->flush(rb_context->pipe, NULL, 0); - - mtx_unlock(&rb_context->call_mutex); - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, list->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_lock(&rb_context->list_mutex); - shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t)); - foreach(ptr, &rb_context->shaders) { - tr_shdr = container_of(ptr, struct rbug_shader, list); - shdrs[i++] = VOID2U64(tr_shdr); - } - - mtx_unlock(&rb_context->list_mutex); - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, info->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_lock(&rb_context->list_mutex); - - tr_shdr = rbug_get_shader_locked(rb_context, info->shader); - - if (!tr_shdr) { - mtx_unlock(&rb_context->list_mutex); - mtx_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); - - mtx_unlock(&rb_context->list_mutex); - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, dis->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_lock(&rb_context->list_mutex); - - tr_shdr = rbug_get_shader_locked(rb_context, dis->shader); - - if (!tr_shdr) { - mtx_unlock(&rb_context->list_mutex); - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - tr_shdr->disabled = dis->disable; - - mtx_unlock(&rb_context->list_mutex); - mtx_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; - - mtx_lock(&rb_screen->list_mutex); - rb_context = rbug_get_context_locked(rb_screen, rep->context); - - if (!rb_context) { - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - mtx_lock(&rb_context->list_mutex); - - tr_shdr = rbug_get_shader_locked(rb_context, rep->shader); - - if (!tr_shdr) { - mtx_unlock(&rb_context->list_mutex); - mtx_unlock(&rb_screen->list_mutex); - return -ESRCH; - } - - /* protect the pipe context */ - mtx_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.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == 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.shader[PIPE_SHADER_FRAGMENT] == tr_shdr || rb_context->curr.shader[PIPE_SHADER_VERTEX] == tr_shdr) - rbug_shader_bind_locked(pipe, tr_shdr, state); - - /* save state */ - tr_shdr->replaced_shader = state; - -out: - mtx_unlock(&rb_context->call_mutex); - mtx_unlock(&rb_context->list_mutex); - mtx_unlock(&rb_screen->list_mutex); - - return 0; - -err: - FREE(tr_shdr->replaced_tokens); - tr_shdr->replaced_shader = NULL; - tr_shdr->replaced_tokens = NULL; - - mtx_unlock(&rb_context->call_mutex); - mtx_unlock(&rb_context->list_mutex); - mtx_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; -} - -int -rbug_thread(void *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 0; - } - - 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 0; -} - -/********************************************************** - * - */ - -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 = u_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; - thrd_join(tr_rbug->thread, NULL); - - 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 deleted file mode 100644 index 2aa4e123f87..00000000000 --- a/src/gallium/drivers/rbug/rbug_objects.c +++ /dev/null @@ -1,250 +0,0 @@ -/************************************************************************** - * - * 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); -} diff --git a/src/gallium/drivers/rbug/rbug_objects.h b/src/gallium/drivers/rbug/rbug_objects.h deleted file mode 100644 index 02973e07996..00000000000 --- a/src/gallium/drivers/rbug/rbug_objects.h +++ /dev/null @@ -1,228 +0,0 @@ -/************************************************************************** - * - * 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; -}; - - -enum rbug_shader_type -{ - RBUG_SHADER_GEOM, - RBUG_SHADER_VERTEX, - RBUG_SHADER_FRAGMENT, -}; - -struct rbug_shader -{ - struct rbug_list list; - - void *shader; - void *tokens; - void *replaced_shader; - void *replaced_tokens; - - enum rbug_shader_type type; - 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_context *rb_context, - struct rbug_resource *rb_resource, - struct pipe_surface *surface); - -void -rbug_surface_destroy(struct rbug_context *rb_context, - 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); - -void * -rbug_shader_create(struct rbug_context *rb_context, - const struct pipe_shader_state *state, - void *result, enum rbug_shader_type type); - -void -rbug_shader_destroy(struct rbug_context *rb_context, - struct rbug_shader *rb_shader); - - -#endif /* RBUG_OBJECTS_H */ diff --git a/src/gallium/drivers/rbug/rbug_public.h b/src/gallium/drivers/rbug/rbug_public.h deleted file mode 100644 index 83f9c94e31f..00000000000 --- a/src/gallium/drivers/rbug/rbug_public.h +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************** - * - * 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 - -#ifdef __cplusplus -extern "C" { -#endif - -struct pipe_screen; -struct pipe_context; - -struct pipe_screen * -rbug_screen_create(struct pipe_screen *screen); - -boolean -rbug_enabled(void); - -#ifdef __cplusplus -} -#endif - -#endif /* RBUG_PUBLIC_H */ diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c deleted file mode 100644 index 2477edbadf0..00000000000 --- a/src/gallium/drivers/rbug/rbug_screen.c +++ /dev/null @@ -1,343 +0,0 @@ -/************************************************************************** - * - * 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/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 const char * -rbug_screen_get_device_vendor(struct pipe_screen *_screen) -{ - struct rbug_screen *rb_screen = rbug_screen(_screen); - struct pipe_screen *screen = rb_screen->screen; - - return screen->get_device_vendor(screen); -} - -static struct disk_cache * -rbug_screen_get_disk_shader_cache(struct pipe_screen *_screen) -{ - struct pipe_screen *screen = rbug_screen(_screen)->screen; - - return screen->get_disk_shader_cache(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 int -rbug_screen_get_shader_param(struct pipe_screen *_screen, - enum pipe_shader_type shader, - enum pipe_shader_cap param) -{ - struct rbug_screen *rb_screen = rbug_screen(_screen); - struct pipe_screen *screen = rb_screen->screen; - - return screen->get_shader_param(screen, shader, - param); -} - -static float -rbug_screen_get_paramf(struct pipe_screen *_screen, - enum pipe_capf 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 sample_count, - unsigned tex_usage) -{ - struct rbug_screen *rb_screen = rbug_screen(_screen); - struct pipe_screen *screen = rb_screen->screen; - - return screen->is_format_supported(screen, - format, - target, - sample_count, - tex_usage); -} - -static struct pipe_context * -rbug_screen_context_create(struct pipe_screen *_screen, - void *priv, unsigned flags) -{ - 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, flags); - 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, - unsigned usage) -{ - 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, usage); - - result = rbug_resource_create(rbug_screen(_screen), result); - - return result; -} - -static bool -rbug_screen_check_resource_capability(struct pipe_screen *_screen, - struct pipe_resource *_resource, - unsigned bind) -{ - 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->check_resource_capability(screen, resource, bind); -} - -static boolean -rbug_screen_resource_get_handle(struct pipe_screen *_screen, - struct pipe_context *_pipe, - struct pipe_resource *_resource, - struct winsys_handle *handle, - unsigned usage) -{ - struct rbug_screen *rb_screen = rbug_screen(_screen); - struct rbug_context *rb_pipe = rbug_context(_pipe); - 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, rb_pipe ? rb_pipe->pipe : NULL, - resource, handle, usage); -} - -static void -rbug_screen_resource_changed(struct pipe_screen *_screen, - struct pipe_resource *_resource) -{ - 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; - - screen->resource_changed(screen, resource); -} - -static void -rbug_screen_resource_destroy(struct pipe_screen *screen, - struct pipe_resource *_resource) -{ - rbug_resource_destroy(rbug_resource(_resource)); -} - -static void -rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, - struct pipe_resource *_resource, - unsigned level, unsigned layer, - void *context_private, struct pipe_box *sub_box) -{ - 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; - - screen->flush_frontbuffer(screen, - resource, - level, layer, - context_private, sub_box); -} - -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 boolean -rbug_screen_fence_finish(struct pipe_screen *_screen, - struct pipe_context *_ctx, - struct pipe_fence_handle *fence, - uint64_t timeout) -{ - struct rbug_screen *rb_screen = rbug_screen(_screen); - struct pipe_screen *screen = rb_screen->screen; - struct pipe_context *ctx = _ctx ? rbug_context(_ctx)->pipe : NULL; - - return screen->fence_finish(screen, ctx, fence, timeout); -} - -boolean -rbug_enabled() -{ - return debug_get_option_rbug(); -} - -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; - - (void) mtx_init(&rb_screen->list_mutex, mtx_plain); - make_empty_list(&rb_screen->contexts); - make_empty_list(&rb_screen->resources); - make_empty_list(&rb_screen->surfaces); - make_empty_list(&rb_screen->transfers); - -#define SCR_INIT(_member) \ - rb_screen->base._member = screen->_member ? rbug_screen_##_member : 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; - SCR_INIT(get_disk_shader_cache); - rb_screen->base.get_device_vendor = rbug_screen_get_device_vendor; - rb_screen->base.get_param = rbug_screen_get_param; - rb_screen->base.get_shader_param = rbug_screen_get_shader_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; - SCR_INIT(check_resource_capability); - rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle; - SCR_INIT(resource_changed); - rb_screen->base.resource_destroy = rbug_screen_resource_destroy; - rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer; - rb_screen->base.fence_reference = rbug_screen_fence_reference; - rb_screen->base.fence_finish = rbug_screen_fence_finish; - - rb_screen->screen = screen; - - rb_screen->private_context = screen->context_create(screen, NULL, 0); - 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 deleted file mode 100644 index 1972005753b..00000000000 --- a/src/gallium/drivers/rbug/rbug_screen.h +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** - * - * 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; - - mtx_t 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 { \ - mtx_lock(&scr->list_mutex); \ - insert_at_head(&scr->name, &obj->list); \ - scr->num_##name++; \ - mtx_unlock(&scr->list_mutex); \ - } while (0) - -#define rbug_screen_remove_from_list(scr, name, obj) \ - do { \ - mtx_lock(&scr->list_mutex); \ - remove_from_list(&obj->list); \ - scr->num_##name--; \ - mtx_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 */ diff --git a/src/gallium/drivers/trace/Makefile.am b/src/gallium/drivers/trace/Makefile.am deleted file mode 100644 index 9c834a6d526..00000000000 --- a/src/gallium/drivers/trace/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -include Makefile.sources -include $(top_srcdir)/src/gallium/Automake.inc - -AM_CFLAGS = \ - $(GALLIUM_DRIVER_CFLAGS) \ - $(MSVC2013_COMPAT_CFLAGS) - -noinst_LTLIBRARIES = libtrace.la - -libtrace_la_SOURCES = $(C_SOURCES) - -EXTRA_DIST = SConscript \ - README \ - trace.xsl \ - meson.build diff --git a/src/gallium/drivers/trace/Makefile.sources b/src/gallium/drivers/trace/Makefile.sources deleted file mode 100644 index 4c019a3bc60..00000000000 --- a/src/gallium/drivers/trace/Makefile.sources +++ /dev/null @@ -1,13 +0,0 @@ -C_SOURCES := \ - tr_context.c \ - tr_context.h \ - tr_dump.c \ - tr_dump_defines.h \ - tr_dump.h \ - tr_dump_state.c \ - tr_dump_state.h \ - tr_public.h \ - tr_screen.c \ - tr_screen.h \ - tr_texture.c \ - tr_texture.h diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README deleted file mode 100644 index cacd2e17498..00000000000 --- a/src/gallium/drivers/trace/README +++ /dev/null @@ -1,55 +0,0 @@ - TRACE PIPE DRIVER - - -= About = - -This directory contains a Gallium3D trace debugger pipe driver. -It can traces all incoming calls. - - -= Usage = - -== Tracing == - -For tracing then do - - GALLIUM_TRACE=tri.trace trivial/tri - -which should create a tri.trace file, which is an XML file. You can view copying -trace.xsl to the same directory, and opening with a XSLT capable browser such as -Firefox or Internet Explorer. - -For long traces you can use the - - src/gallium/tools/trace/dump.py tri.trace | less -R - - -== Remote debugging == - -For remote debugging see: - - src/gallium/drivers/rbug/README - - -= Integrating = - -You can integrate the trace pipe driver either inside the state tracker or the -target. The procedure on both cases is the same. Let's assume you have a -pipe_screen obtained by the usual means (variable and function names are just -for illustration purposes): - - real_screen = real_screen_create(...); - -The trace screen is then created by doing - - trace_screen = trace_screen_create(real_screen); - -You can then simply use trace_screen instead of real_screen. - -You can create as many contexts you wish from trace_screen::context_create they -are automatically wrapped by trace_screen. - - --- -Jose Fonseca -Jakob Bornecrantz diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript deleted file mode 100644 index 7397983647a..00000000000 --- a/src/gallium/drivers/trace/SConscript +++ /dev/null @@ -1,14 +0,0 @@ -Import('*') - -env = env.Clone() - -env.MSVC2013Compat() - -trace = env.ConvenienceLibrary( - target = 'trace', - source = env.ParseSourceList('Makefile.sources', 'C_SOURCES') - ) - -env.Alias('trace', trace) - -Export('trace') diff --git a/src/gallium/drivers/trace/meson.build b/src/gallium/drivers/trace/meson.build deleted file mode 100644 index 4fc5d8ba0f6..00000000000 --- a/src/gallium/drivers/trace/meson.build +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright © 2017 Dylan Baker - -# 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS 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. - -libtrace = static_library( - 'trace', - files('tr_context.c', 'tr_context.h', 'tr_dump.c', 'tr_dump_defines.h', - 'tr_dump.h', 'tr_dump_state.c', 'tr_dump_state.h', 'tr_public.h', - 'tr_screen.c', 'tr_screen.h', 'tr_texture.c', 'tr_texture.h'), - c_args : [c_msvc_compat_args, c_vis_args], - include_directories : [inc_gallium, inc_gallium_aux, inc_include, inc_src], - build_by_default : false, -) diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c deleted file mode 100644 index 6d918d42a38..00000000000 --- a/src/gallium/drivers/trace/tr_context.c +++ /dev/null @@ -1,1948 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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 "pipe/p_format.h" -#include "pipe/p_screen.h" - -#include "tr_dump.h" -#include "tr_dump_defines.h" -#include "tr_dump_state.h" -#include "tr_public.h" -#include "tr_screen.h" -#include "tr_texture.h" -#include "tr_context.h" - - -struct trace_query -{ - unsigned type; - - struct pipe_query *query; -}; - - -static inline struct trace_query * -trace_query(struct pipe_query *query) -{ - return (struct trace_query *)query; -} - - -static inline struct pipe_query * -trace_query_unwrap(struct pipe_query *query) -{ - if (query) { - return trace_query(query)->query; - } else { - return NULL; - } -} - - -static inline struct pipe_surface * -trace_surface_unwrap(struct trace_context *tr_ctx, - struct pipe_surface *surface) -{ - struct trace_surface *tr_surf; - - if (!surface) - return NULL; - - assert(surface->texture); - if (!surface->texture) - return surface; - - tr_surf = trace_surface(surface); - - assert(tr_surf->surface); - return tr_surf->surface; -} - - -static void -trace_context_draw_vbo(struct pipe_context *_pipe, - const struct pipe_draw_info *info) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "draw_vbo"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(draw_info, info); - - trace_dump_trace_flush(); - - pipe->draw_vbo(pipe, info); - - trace_dump_call_end(); -} - - -static struct pipe_query * -trace_context_create_query(struct pipe_context *_pipe, - unsigned query_type, - unsigned index) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_query *query; - - trace_dump_call_begin("pipe_context", "create_query"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(query_type, query_type); - trace_dump_arg(int, index); - - query = pipe->create_query(pipe, query_type, index); - - trace_dump_ret(ptr, query); - - trace_dump_call_end(); - - /* Wrap query object. */ - if (query) { - struct trace_query *tr_query = CALLOC_STRUCT(trace_query); - if (tr_query) { - tr_query->type = query_type; - tr_query->query = query; - query = (struct pipe_query *)tr_query; - } else { - pipe->destroy_query(pipe, query); - query = NULL; - } - } - - return query; -} - - -static void -trace_context_destroy_query(struct pipe_context *_pipe, - struct pipe_query *_query) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct trace_query *tr_query = trace_query(_query); - struct pipe_query *query = tr_query->query; - - FREE(tr_query); - - trace_dump_call_begin("pipe_context", "destroy_query"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, query); - - pipe->destroy_query(pipe, query); - - trace_dump_call_end(); -} - - -static boolean -trace_context_begin_query(struct pipe_context *_pipe, - struct pipe_query *query) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - boolean ret; - - query = trace_query_unwrap(query); - - trace_dump_call_begin("pipe_context", "begin_query"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, query); - - ret = pipe->begin_query(pipe, query); - - trace_dump_call_end(); - return ret; -} - - -static bool -trace_context_end_query(struct pipe_context *_pipe, - struct pipe_query *query) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - bool ret; - - query = trace_query_unwrap(query); - - trace_dump_call_begin("pipe_context", "end_query"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, query); - - ret = pipe->end_query(pipe, query); - - trace_dump_call_end(); - return ret; -} - - -static boolean -trace_context_get_query_result(struct pipe_context *_pipe, - struct pipe_query *_query, - boolean wait, - union pipe_query_result *result) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct trace_query *tr_query = trace_query(_query); - struct pipe_query *query = tr_query->query; - boolean ret; - - trace_dump_call_begin("pipe_context", "get_query_result"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, query); - - ret = pipe->get_query_result(pipe, query, wait, result); - - trace_dump_arg_begin("result"); - if (ret) { - trace_dump_query_result(tr_query->type, result); - } else { - trace_dump_null(); - } - trace_dump_arg_end(); - - trace_dump_ret(bool, ret); - - trace_dump_call_end(); - - return ret; -} - - -static void -trace_context_set_active_query_state(struct pipe_context *_pipe, - boolean enable) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_active_query_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(bool, enable); - - pipe->set_active_query_state(pipe, enable); - - trace_dump_call_end(); -} - - -static void * -trace_context_create_blend_state(struct pipe_context *_pipe, - const struct pipe_blend_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - void * result; - - trace_dump_call_begin("pipe_context", "create_blend_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(blend_state, state); - - result = pipe->create_blend_state(pipe, state); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static void -trace_context_bind_blend_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "bind_blend_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->bind_blend_state(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_delete_blend_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_blend_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->delete_blend_state(pipe, state); - - trace_dump_call_end(); -} - - -static void * -trace_context_create_sampler_state(struct pipe_context *_pipe, - const struct pipe_sampler_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - void * result; - - trace_dump_call_begin("pipe_context", "create_sampler_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(sampler_state, state); - - result = pipe->create_sampler_state(pipe, state); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static void -trace_context_bind_sampler_states(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, - unsigned num_states, - void **states) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - /* remove this when we have pipe->bind_sampler_states(..., start, ...) */ - assert(start == 0); - - trace_dump_call_begin("pipe_context", "bind_sampler_states"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, shader); - trace_dump_arg(uint, start); - trace_dump_arg(uint, num_states); - trace_dump_arg_array(ptr, states, num_states); - - pipe->bind_sampler_states(pipe, shader, start, num_states, states); - - trace_dump_call_end(); -} - - -static void -trace_context_delete_sampler_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_sampler_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->delete_sampler_state(pipe, state); - - trace_dump_call_end(); -} - - -static void * -trace_context_create_rasterizer_state(struct pipe_context *_pipe, - const struct pipe_rasterizer_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - void * result; - - trace_dump_call_begin("pipe_context", "create_rasterizer_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(rasterizer_state, state); - - result = pipe->create_rasterizer_state(pipe, state); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static void -trace_context_bind_rasterizer_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "bind_rasterizer_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->bind_rasterizer_state(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_delete_rasterizer_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_rasterizer_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->delete_rasterizer_state(pipe, state); - - trace_dump_call_end(); -} - - -static void * -trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, - const struct pipe_depth_stencil_alpha_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - void * result; - - trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state"); - - result = pipe->create_depth_stencil_alpha_state(pipe, state); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(depth_stencil_alpha_state, state); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static void -trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "bind_depth_stencil_alpha_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->bind_depth_stencil_alpha_state(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_depth_stencil_alpha_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->delete_depth_stencil_alpha_state(pipe, state); - - trace_dump_call_end(); -} - - -#define TRACE_SHADER_STATE(shader_type) \ - static void * \ - trace_context_create_##shader_type##_state(struct pipe_context *_pipe, \ - const struct pipe_shader_state *state) \ - { \ - struct trace_context *tr_ctx = trace_context(_pipe); \ - struct pipe_context *pipe = tr_ctx->pipe; \ - void * result; \ - trace_dump_call_begin("pipe_context", "create_" #shader_type "_state"); \ - trace_dump_arg(ptr, pipe); \ - trace_dump_arg(shader_state, state); \ - result = pipe->create_##shader_type##_state(pipe, state); \ - trace_dump_ret(ptr, result); \ - trace_dump_call_end(); \ - return result; \ - } \ - \ - static void \ - trace_context_bind_##shader_type##_state(struct pipe_context *_pipe, \ - void *state) \ - { \ - struct trace_context *tr_ctx = trace_context(_pipe); \ - struct pipe_context *pipe = tr_ctx->pipe; \ - trace_dump_call_begin("pipe_context", "bind_" #shader_type "_state"); \ - trace_dump_arg(ptr, pipe); \ - trace_dump_arg(ptr, state); \ - pipe->bind_##shader_type##_state(pipe, state); \ - trace_dump_call_end(); \ - } \ - \ - static void \ - trace_context_delete_##shader_type##_state(struct pipe_context *_pipe, \ - void *state) \ - { \ - struct trace_context *tr_ctx = trace_context(_pipe); \ - struct pipe_context *pipe = tr_ctx->pipe; \ - trace_dump_call_begin("pipe_context", "delete_" #shader_type "_state"); \ - trace_dump_arg(ptr, pipe); \ - trace_dump_arg(ptr, state); \ - pipe->delete_##shader_type##_state(pipe, state); \ - trace_dump_call_end(); \ - } - -TRACE_SHADER_STATE(fs) -TRACE_SHADER_STATE(vs) -TRACE_SHADER_STATE(gs) -TRACE_SHADER_STATE(tcs) -TRACE_SHADER_STATE(tes) - -#undef TRACE_SHADER_STATE - - -static inline void * -trace_context_create_compute_state(struct pipe_context *_pipe, - const struct pipe_compute_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - void * result; - - trace_dump_call_begin("pipe_context", "create_compute_state"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(compute_state, state); - result = pipe->create_compute_state(pipe, state); - trace_dump_ret(ptr, result); - trace_dump_call_end(); - return result; -} - -static inline void -trace_context_bind_compute_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "bind_compute_state"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - pipe->bind_compute_state(pipe, state); - trace_dump_call_end(); -} - -static inline void -trace_context_delete_compute_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_compute_state"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - pipe->delete_compute_state(pipe, state); - trace_dump_call_end(); -} - -static void * -trace_context_create_vertex_elements_state(struct pipe_context *_pipe, - unsigned num_elements, - const struct pipe_vertex_element *elements) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - void * result; - - trace_dump_call_begin("pipe_context", "create_vertex_elements_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, num_elements); - - trace_dump_arg_begin("elements"); - trace_dump_struct_array(vertex_element, elements, num_elements); - trace_dump_arg_end(); - - result = pipe->create_vertex_elements_state(pipe, num_elements, elements); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static void -trace_context_bind_vertex_elements_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "bind_vertex_elements_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->bind_vertex_elements_state(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_delete_vertex_elements_state(struct pipe_context *_pipe, - void *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_vertex_elements_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); - - pipe->delete_vertex_elements_state(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_set_blend_color(struct pipe_context *_pipe, - const struct pipe_blend_color *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_blend_color"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(blend_color, state); - - pipe->set_blend_color(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_set_stencil_ref(struct pipe_context *_pipe, - const struct pipe_stencil_ref *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_stencil_ref"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(stencil_ref, state); - - pipe->set_stencil_ref(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_set_clip_state(struct pipe_context *_pipe, - const struct pipe_clip_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_clip_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(clip_state, state); - - pipe->set_clip_state(pipe, state); - - trace_dump_call_end(); -} - -static void -trace_context_set_sample_mask(struct pipe_context *_pipe, - unsigned sample_mask) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_sample_mask"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, sample_mask); - - pipe->set_sample_mask(pipe, sample_mask); - - trace_dump_call_end(); -} - -static void -trace_context_set_constant_buffer(struct pipe_context *_pipe, - enum pipe_shader_type shader, uint index, - const struct pipe_constant_buffer *constant_buffer) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_constant_buffer"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, shader); - trace_dump_arg(uint, index); - trace_dump_arg(constant_buffer, constant_buffer); - - pipe->set_constant_buffer(pipe, shader, index, constant_buffer); - - trace_dump_call_end(); -} - - -static void -trace_context_set_framebuffer_state(struct pipe_context *_pipe, - const struct pipe_framebuffer_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_framebuffer_state unwrapped_state; - unsigned i; - - - /* Unwrap the input state */ - memcpy(&unwrapped_state, state, sizeof(unwrapped_state)); - for (i = 0; i < state->nr_cbufs; ++i) - unwrapped_state.cbufs[i] = trace_surface_unwrap(tr_ctx, state->cbufs[i]); - for (i = state->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; ++i) - unwrapped_state.cbufs[i] = NULL; - unwrapped_state.zsbuf = trace_surface_unwrap(tr_ctx, state->zsbuf); - state = &unwrapped_state; - - trace_dump_call_begin("pipe_context", "set_framebuffer_state"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(framebuffer_state, state); - - pipe->set_framebuffer_state(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_set_polygon_stipple(struct pipe_context *_pipe, - const struct pipe_poly_stipple *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_polygon_stipple"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(poly_stipple, state); - - pipe->set_polygon_stipple(pipe, state); - - trace_dump_call_end(); -} - - -static void -trace_context_set_scissor_states(struct pipe_context *_pipe, - unsigned start_slot, - unsigned num_scissors, - const struct pipe_scissor_state *states) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_scissor_states"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, start_slot); - trace_dump_arg(uint, num_scissors); - trace_dump_arg(scissor_state, states); - - pipe->set_scissor_states(pipe, start_slot, num_scissors, states); - - trace_dump_call_end(); -} - - -static void -trace_context_set_viewport_states(struct pipe_context *_pipe, - unsigned start_slot, - unsigned num_viewports, - const struct pipe_viewport_state *states) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_viewport_states"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, start_slot); - trace_dump_arg(uint, num_viewports); - trace_dump_arg(viewport_state, states); - - pipe->set_viewport_states(pipe, start_slot, num_viewports, states); - - trace_dump_call_end(); -} - - -static struct pipe_sampler_view * -trace_context_create_sampler_view(struct pipe_context *_pipe, - struct pipe_resource *resource, - const struct pipe_sampler_view *templ) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_sampler_view *result; - struct trace_sampler_view *tr_view; - - trace_dump_call_begin("pipe_context", "create_sampler_view"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, resource); - - trace_dump_arg_begin("templ"); - trace_dump_sampler_view_template(templ, resource->target); - trace_dump_arg_end(); - - result = pipe->create_sampler_view(pipe, resource, templ); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - /* - * Wrap pipe_sampler_view - */ - tr_view = CALLOC_STRUCT(trace_sampler_view); - tr_view->base = *templ; - tr_view->base.reference.count = 1; - tr_view->base.texture = NULL; - pipe_resource_reference(&tr_view->base.texture, resource); - tr_view->base.context = _pipe; - tr_view->sampler_view = result; - result = &tr_view->base; - - return result; -} - - -static void -trace_context_sampler_view_destroy(struct pipe_context *_pipe, - struct pipe_sampler_view *_view) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_sampler_view *tr_view = trace_sampler_view(_view); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_sampler_view *view = tr_view->sampler_view; - - assert(_view->context == _pipe); - - trace_dump_call_begin("pipe_context", "sampler_view_destroy"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, view); - - pipe_sampler_view_reference(&tr_view->sampler_view, NULL); - - trace_dump_call_end(); - - pipe_resource_reference(&_view->texture, NULL); - FREE(_view); -} - -/******************************************************************** - * surface - */ - - -static struct pipe_surface * -trace_context_create_surface(struct pipe_context *_pipe, - struct pipe_resource *resource, - const struct pipe_surface *surf_tmpl) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_surface *result = NULL; - - trace_dump_call_begin("pipe_context", "create_surface"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, resource); - - trace_dump_arg_begin("surf_tmpl"); - trace_dump_surface_template(surf_tmpl, resource->target); - trace_dump_arg_end(); - - - result = pipe->create_surface(pipe, resource, surf_tmpl); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - result = trace_surf_create(tr_ctx, resource, result); - - return result; -} - - -static void -trace_context_surface_destroy(struct pipe_context *_pipe, - struct pipe_surface *_surface) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct trace_surface *tr_surf = trace_surface(_surface); - struct pipe_surface *surface = tr_surf->surface; - - trace_dump_call_begin("pipe_context", "surface_destroy"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, surface); - - trace_dump_call_end(); - - trace_surf_destroy(tr_surf); -} - - -static void -trace_context_set_sampler_views(struct pipe_context *_pipe, - enum pipe_shader_type shader, - unsigned start, - unsigned num, - struct pipe_sampler_view **views) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_sampler_view *tr_view; - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SHADER_SAMPLER_VIEWS]; - unsigned i; - - /* remove this when we have pipe->set_sampler_views(..., start, ...) */ - assert(start == 0); - - for (i = 0; i < num; ++i) { - tr_view = trace_sampler_view(views[i]); - unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL; - } - views = unwrapped_views; - - trace_dump_call_begin("pipe_context", "set_sampler_views"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, shader); - trace_dump_arg(uint, start); - trace_dump_arg(uint, num); - trace_dump_arg_array(ptr, views, num); - - pipe->set_sampler_views(pipe, shader, start, num, views); - - trace_dump_call_end(); -} - - -static void -trace_context_set_vertex_buffers(struct pipe_context *_pipe, - unsigned start_slot, unsigned num_buffers, - const struct pipe_vertex_buffer *buffers) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_vertex_buffers"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, start_slot); - trace_dump_arg(uint, num_buffers); - - trace_dump_arg_begin("buffers"); - trace_dump_struct_array(vertex_buffer, buffers, num_buffers); - trace_dump_arg_end(); - - pipe->set_vertex_buffers(pipe, start_slot, num_buffers, buffers); - - trace_dump_call_end(); -} - - -static struct pipe_stream_output_target * -trace_context_create_stream_output_target(struct pipe_context *_pipe, - struct pipe_resource *res, - unsigned buffer_offset, - unsigned buffer_size) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_stream_output_target *result; - - trace_dump_call_begin("pipe_context", "create_stream_output_target"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, res); - trace_dump_arg(uint, buffer_offset); - trace_dump_arg(uint, buffer_size); - - result = pipe->create_stream_output_target(pipe, - res, buffer_offset, buffer_size); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static void -trace_context_stream_output_target_destroy( - struct pipe_context *_pipe, - struct pipe_stream_output_target *target) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "stream_output_target_destroy"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, target); - - pipe->stream_output_target_destroy(pipe, target); - - trace_dump_call_end(); -} - - -static void -trace_context_set_stream_output_targets(struct pipe_context *_pipe, - unsigned num_targets, - struct pipe_stream_output_target **tgs, - const unsigned *offsets) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "set_stream_output_targets"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, num_targets); - trace_dump_arg_array(ptr, tgs, num_targets); - trace_dump_arg_array(uint, offsets, num_targets); - - pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets); - - trace_dump_call_end(); -} - - -static void -trace_context_resource_copy_region(struct pipe_context *_pipe, - struct pipe_resource *dst, - unsigned dst_level, - unsigned dstx, unsigned dsty, unsigned dstz, - struct pipe_resource *src, - unsigned src_level, - const struct pipe_box *src_box) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "resource_copy_region"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, dst); - trace_dump_arg(uint, dst_level); - trace_dump_arg(uint, dstx); - trace_dump_arg(uint, dsty); - trace_dump_arg(uint, dstz); - trace_dump_arg(ptr, src); - trace_dump_arg(uint, src_level); - trace_dump_arg(box, src_box); - - pipe->resource_copy_region(pipe, - dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); - - trace_dump_call_end(); -} - - -static void -trace_context_blit(struct pipe_context *_pipe, - const struct pipe_blit_info *_info) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_blit_info info = *_info; - - trace_dump_call_begin("pipe_context", "blit"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(blit_info, _info); - - pipe->blit(pipe, &info); - - trace_dump_call_end(); -} - - -static void -trace_context_flush_resource(struct pipe_context *_pipe, - struct pipe_resource *resource) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "flush_resource"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, resource); - - pipe->flush_resource(pipe, resource); - - trace_dump_call_end(); -} - - -static void -trace_context_clear(struct pipe_context *_pipe, - unsigned buffers, - const union pipe_color_union *color, - double depth, - unsigned stencil) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "clear"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, buffers); - trace_dump_arg_begin("color"); - if (color) - trace_dump_array(float, color->f, 4); - else - trace_dump_null(); - trace_dump_arg_end(); - trace_dump_arg(float, depth); - trace_dump_arg(uint, stencil); - - pipe->clear(pipe, buffers, color, depth, stencil); - - trace_dump_call_end(); -} - - -static void -trace_context_clear_render_target(struct pipe_context *_pipe, - struct pipe_surface *dst, - const union pipe_color_union *color, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - dst = trace_surface_unwrap(tr_ctx, dst); - - trace_dump_call_begin("pipe_context", "clear_render_target"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, dst); - trace_dump_arg_array(float, color->f, 4); - trace_dump_arg(uint, dstx); - trace_dump_arg(uint, dsty); - trace_dump_arg(uint, width); - trace_dump_arg(uint, height); - trace_dump_arg(bool, render_condition_enabled); - - pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height, - render_condition_enabled); - - trace_dump_call_end(); -} - -static void -trace_context_clear_depth_stencil(struct pipe_context *_pipe, - struct pipe_surface *dst, - unsigned clear_flags, - double depth, - unsigned stencil, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - bool render_condition_enabled) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - dst = trace_surface_unwrap(tr_ctx, dst); - - trace_dump_call_begin("pipe_context", "clear_depth_stencil"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, dst); - trace_dump_arg(uint, clear_flags); - trace_dump_arg(float, depth); - trace_dump_arg(uint, stencil); - trace_dump_arg(uint, dstx); - trace_dump_arg(uint, dsty); - trace_dump_arg(uint, width); - trace_dump_arg(uint, height); - trace_dump_arg(bool, render_condition_enabled); - - pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil, - dstx, dsty, width, height, - render_condition_enabled); - - trace_dump_call_end(); -} - -static inline void -trace_context_clear_texture(struct pipe_context *_pipe, - struct pipe_resource *res, - unsigned level, - const struct pipe_box *box, - const void *data) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - - trace_dump_call_begin("pipe_context", "clear_texture"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, res); - trace_dump_arg(uint, level); - trace_dump_arg_begin("box"); - trace_dump_box(box); - trace_dump_arg_end(); - trace_dump_arg(ptr, data); - - pipe->clear_texture(pipe, res, level, box, data); - - trace_dump_call_end(); -} - -static void -trace_context_flush(struct pipe_context *_pipe, - struct pipe_fence_handle **fence, - unsigned flags) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "flush"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, flags); - - pipe->flush(pipe, fence, flags); - - if (fence) - trace_dump_ret(ptr, *fence); - - trace_dump_call_end(); -} - - -static inline boolean -trace_context_generate_mipmap(struct pipe_context *_pipe, - struct pipe_resource *res, - enum pipe_format format, - unsigned base_level, - unsigned last_level, - unsigned first_layer, - unsigned last_layer) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - boolean ret; - - trace_dump_call_begin("pipe_context", "generate_mipmap"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, res); - - trace_dump_arg(format, format); - trace_dump_arg(uint, base_level); - trace_dump_arg(uint, last_level); - trace_dump_arg(uint, first_layer); - trace_dump_arg(uint, last_layer); - - ret = pipe->generate_mipmap(pipe, res, format, base_level, last_level, - first_layer, last_layer); - - trace_dump_ret(bool, ret); - trace_dump_call_end(); - - return ret; -} - - -static void -trace_context_destroy(struct pipe_context *_pipe) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "destroy"); - trace_dump_arg(ptr, pipe); - trace_dump_call_end(); - - pipe->destroy(pipe); - - FREE(tr_ctx); -} - - -/******************************************************************** - * transfer - */ - - -static void * -trace_context_transfer_map(struct pipe_context *_context, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box, - struct pipe_transfer **transfer) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - struct pipe_transfer *result = NULL; - void *map; - - /* - * Map and transfers can't be serialized so we convert all write transfers - * to texture/buffer_subdata and ignore read transfers. - */ - - map = context->transfer_map(context, resource, level, usage, box, &result); - if (!map) - return NULL; - - *transfer = trace_transfer_create(tr_context, resource, result); - - if (map) { - if (usage & PIPE_TRANSFER_WRITE) { - trace_transfer(*transfer)->map = map; - } - } - - return *transfer ? map : NULL; -} - -static void -trace_context_transfer_flush_region( struct pipe_context *_context, - struct pipe_transfer *_transfer, - const struct pipe_box *box) -{ - struct trace_context *tr_context = trace_context(_context); - struct trace_transfer *tr_transfer = trace_transfer(_transfer); - struct pipe_context *context = tr_context->pipe; - struct pipe_transfer *transfer = tr_transfer->transfer; - - context->transfer_flush_region(context, transfer, box); -} - -static void -trace_context_transfer_unmap(struct pipe_context *_context, - struct pipe_transfer *_transfer) -{ - struct trace_context *tr_ctx = trace_context(_context); - struct trace_transfer *tr_trans = trace_transfer(_transfer); - struct pipe_context *context = tr_ctx->pipe; - struct pipe_transfer *transfer = tr_trans->transfer; - - if (tr_trans->map) { - /* - * Fake a texture/buffer_subdata - */ - - struct pipe_resource *resource = transfer->resource; - unsigned level = transfer->level; - unsigned usage = transfer->usage; - const struct pipe_box *box = &transfer->box; - unsigned stride = transfer->stride; - unsigned layer_stride = transfer->layer_stride; - - if (resource->target == PIPE_BUFFER) - trace_dump_call_begin("pipe_context", "buffer_subdata"); - else - trace_dump_call_begin("pipe_context", "texture_subdata"); - - trace_dump_arg(ptr, context); - trace_dump_arg(ptr, resource); - trace_dump_arg(uint, level); - trace_dump_arg(uint, usage); - trace_dump_arg(box, box); - - trace_dump_arg_begin("data"); - trace_dump_box_bytes(tr_trans->map, - resource, - box, - stride, - layer_stride); - trace_dump_arg_end(); - - trace_dump_arg(uint, stride); - trace_dump_arg(uint, layer_stride); - - trace_dump_call_end(); - - tr_trans->map = NULL; - } - - context->transfer_unmap(context, transfer); - trace_transfer_destroy(tr_ctx, tr_trans); -} - - -static void -trace_context_buffer_subdata(struct pipe_context *_context, - struct pipe_resource *resource, - unsigned usage, unsigned offset, - unsigned size, const void *data) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - struct pipe_box box; - - trace_dump_call_begin("pipe_context", "buffer_subdata"); - - trace_dump_arg(ptr, context); - trace_dump_arg(ptr, resource); - trace_dump_arg(uint, usage); - trace_dump_arg(uint, offset); - trace_dump_arg(uint, size); - - trace_dump_arg_begin("data"); - u_box_1d(offset, size, &box); - trace_dump_box_bytes(data, resource, &box, 0, 0); - trace_dump_arg_end(); - - trace_dump_call_end(); - - context->buffer_subdata(context, resource, usage, offset, size, data); -} - - -static void -trace_context_texture_subdata(struct pipe_context *_context, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box, - const void *data, - unsigned stride, - unsigned layer_stride) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "texture_subdata"); - - trace_dump_arg(ptr, context); - trace_dump_arg(ptr, resource); - trace_dump_arg(uint, level); - trace_dump_arg(uint, usage); - trace_dump_arg(box, box); - - trace_dump_arg_begin("data"); - trace_dump_box_bytes(data, - resource, - box, - stride, - layer_stride); - trace_dump_arg_end(); - - trace_dump_arg(uint, stride); - trace_dump_arg(uint, layer_stride); - - trace_dump_call_end(); - - context->texture_subdata(context, resource, level, usage, box, - data, stride, layer_stride); -} - -static void -trace_context_invalidate_resource(struct pipe_context *_context, - struct pipe_resource *resource) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "invalidate_resource"); - - trace_dump_arg(ptr, context); - trace_dump_arg(ptr, resource); - - trace_dump_call_end(); - - context->invalidate_resource(context, resource); -} - -static void -trace_context_render_condition(struct pipe_context *_context, - struct pipe_query *query, - boolean condition, - enum pipe_render_cond_flag mode) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - query = trace_query_unwrap(query); - - trace_dump_call_begin("pipe_context", "render_condition"); - - trace_dump_arg(ptr, context); - trace_dump_arg(ptr, query); - trace_dump_arg(bool, condition); - trace_dump_arg(uint, mode); - - trace_dump_call_end(); - - context->render_condition(context, query, condition, mode); -} - - -static void -trace_context_texture_barrier(struct pipe_context *_context, unsigned flags) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "texture_barrier"); - - trace_dump_arg(ptr, context); - trace_dump_arg(uint, flags); - - trace_dump_call_end(); - - context->texture_barrier(context, flags); -} - - -static void -trace_context_memory_barrier(struct pipe_context *_context, - unsigned flags) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "memory_barrier"); - trace_dump_arg(ptr, context); - trace_dump_arg(uint, flags); - trace_dump_call_end(); - - context->memory_barrier(context, flags); -} - - -static bool -trace_context_resource_commit(struct pipe_context *_context, - struct pipe_resource *resource, - unsigned level, struct pipe_box *box, bool commit) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "resource_commit"); - trace_dump_arg(ptr, context); - trace_dump_arg(ptr, resource); - trace_dump_arg(uint, level); - trace_dump_arg(box, box); - trace_dump_arg(bool, commit); - trace_dump_call_end(); - - return context->resource_commit(context, resource, level, box, commit); -} - -static void -trace_context_set_tess_state(struct pipe_context *_context, - const float default_outer_level[4], - const float default_inner_level[2]) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "set_tess_state"); - trace_dump_arg(ptr, context); - trace_dump_arg_array(float, default_outer_level, 4); - trace_dump_arg_array(float, default_inner_level, 2); - trace_dump_call_end(); - - context->set_tess_state(context, default_outer_level, default_inner_level); -} - - -static void trace_context_set_shader_buffers(struct pipe_context *_context, - enum pipe_shader_type shader, - unsigned start, unsigned nr, - const struct pipe_shader_buffer *buffers) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "set_shader_buffers"); - trace_dump_arg(ptr, context); - trace_dump_arg(uint, shader); - trace_dump_arg(uint, start); - trace_dump_arg_begin("buffers"); - trace_dump_struct_array(shader_buffer, buffers, nr); - trace_dump_arg_end(); - trace_dump_call_end(); - - context->set_shader_buffers(context, shader, start, nr, buffers); -} - -static void trace_context_set_shader_images(struct pipe_context *_context, - enum pipe_shader_type shader, - unsigned start, unsigned nr, - const struct pipe_image_view *images) -{ - struct trace_context *tr_context = trace_context(_context); - struct pipe_context *context = tr_context->pipe; - - trace_dump_call_begin("pipe_context", "set_shader_images"); - trace_dump_arg(ptr, context); - trace_dump_arg(uint, shader); - trace_dump_arg(uint, start); - trace_dump_arg_begin("images"); - trace_dump_struct_array(image_view, images, nr); - trace_dump_arg_end(); - trace_dump_call_end(); - - context->set_shader_images(context, shader, start, nr, images); -} - -static void trace_context_launch_grid(struct pipe_context *_pipe, - const struct pipe_grid_info *info) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "launch_grid"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(grid_info, info); - - trace_dump_trace_flush(); - - pipe->launch_grid(pipe, info); - - trace_dump_call_end(); -} - -static uint64_t trace_context_create_texture_handle(struct pipe_context *_pipe, - struct pipe_sampler_view *view, - const struct pipe_sampler_state *state) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - uint64_t handle; - - trace_dump_call_begin("pipe_context", "create_texture_handle"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, view); - trace_dump_arg_begin("state"); - trace_dump_arg(sampler_state, state); - trace_dump_arg_end(); - - handle = pipe->create_texture_handle(pipe, view, state); - - trace_dump_ret(uint, handle); - trace_dump_call_end(); - - return handle; -} - -static void trace_context_delete_texture_handle(struct pipe_context *_pipe, - uint64_t handle) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_texture_handle"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, handle); - trace_dump_call_end(); - - pipe->delete_texture_handle(pipe, handle); -} - -static void trace_context_make_texture_handle_resident(struct pipe_context *_pipe, - uint64_t handle, - bool resident) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "make_texture_handle_resident"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, handle); - trace_dump_arg(bool, resident); - trace_dump_call_end(); - - pipe->make_texture_handle_resident(pipe, handle, resident); -} - -static uint64_t trace_context_create_image_handle(struct pipe_context *_pipe, - const struct pipe_image_view *image) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - uint64_t handle; - - trace_dump_call_begin("pipe_context", "create_image_handle"); - trace_dump_arg(ptr, pipe); - trace_dump_arg_begin("image"); - trace_dump_image_view(image); - trace_dump_arg_end(); - - handle = pipe->create_image_handle(pipe, image); - - trace_dump_ret(uint, handle); - trace_dump_call_end(); - - return handle; -} - -static void trace_context_delete_image_handle(struct pipe_context *_pipe, - uint64_t handle) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "delete_image_handle"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, handle); - trace_dump_call_end(); - - pipe->delete_image_handle(pipe, handle); -} - -static void trace_context_make_image_handle_resident(struct pipe_context *_pipe, - uint64_t handle, - unsigned access, - bool resident) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct pipe_context *pipe = tr_ctx->pipe; - - trace_dump_call_begin("pipe_context", "make_image_handle_resident"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, handle); - trace_dump_arg(uint, access); - trace_dump_arg(bool, resident); - trace_dump_call_end(); - - pipe->make_image_handle_resident(pipe, handle, access, resident); -} - -struct pipe_context * -trace_context_create(struct trace_screen *tr_scr, - struct pipe_context *pipe) -{ - struct trace_context *tr_ctx; - - if (!pipe) - goto error1; - - if (!trace_enabled()) - goto error1; - - tr_ctx = CALLOC_STRUCT(trace_context); - if (!tr_ctx) - goto error1; - - tr_ctx->base.priv = pipe->priv; /* expose wrapped priv data */ - tr_ctx->base.screen = &tr_scr->base; - tr_ctx->base.stream_uploader = pipe->stream_uploader; - tr_ctx->base.const_uploader = pipe->const_uploader; - - tr_ctx->base.destroy = trace_context_destroy; - -#define TR_CTX_INIT(_member) \ - tr_ctx->base . _member = pipe -> _member ? trace_context_ ## _member : NULL - - TR_CTX_INIT(draw_vbo); - TR_CTX_INIT(render_condition); - TR_CTX_INIT(create_query); - TR_CTX_INIT(destroy_query); - TR_CTX_INIT(begin_query); - TR_CTX_INIT(end_query); - TR_CTX_INIT(get_query_result); - TR_CTX_INIT(set_active_query_state); - TR_CTX_INIT(create_blend_state); - TR_CTX_INIT(bind_blend_state); - TR_CTX_INIT(delete_blend_state); - TR_CTX_INIT(create_sampler_state); - TR_CTX_INIT(bind_sampler_states); - TR_CTX_INIT(delete_sampler_state); - TR_CTX_INIT(create_rasterizer_state); - TR_CTX_INIT(bind_rasterizer_state); - TR_CTX_INIT(delete_rasterizer_state); - TR_CTX_INIT(create_depth_stencil_alpha_state); - TR_CTX_INIT(bind_depth_stencil_alpha_state); - TR_CTX_INIT(delete_depth_stencil_alpha_state); - TR_CTX_INIT(create_fs_state); - TR_CTX_INIT(bind_fs_state); - TR_CTX_INIT(delete_fs_state); - TR_CTX_INIT(create_vs_state); - TR_CTX_INIT(bind_vs_state); - TR_CTX_INIT(delete_vs_state); - TR_CTX_INIT(create_gs_state); - TR_CTX_INIT(bind_gs_state); - TR_CTX_INIT(delete_gs_state); - TR_CTX_INIT(create_tcs_state); - TR_CTX_INIT(bind_tcs_state); - TR_CTX_INIT(delete_tcs_state); - TR_CTX_INIT(create_tes_state); - TR_CTX_INIT(bind_tes_state); - TR_CTX_INIT(delete_tes_state); - TR_CTX_INIT(create_compute_state); - TR_CTX_INIT(bind_compute_state); - TR_CTX_INIT(delete_compute_state); - TR_CTX_INIT(create_vertex_elements_state); - TR_CTX_INIT(bind_vertex_elements_state); - TR_CTX_INIT(delete_vertex_elements_state); - TR_CTX_INIT(set_blend_color); - TR_CTX_INIT(set_stencil_ref); - TR_CTX_INIT(set_clip_state); - TR_CTX_INIT(set_sample_mask); - TR_CTX_INIT(set_constant_buffer); - TR_CTX_INIT(set_framebuffer_state); - TR_CTX_INIT(set_polygon_stipple); - TR_CTX_INIT(set_scissor_states); - TR_CTX_INIT(set_viewport_states); - TR_CTX_INIT(set_sampler_views); - TR_CTX_INIT(create_sampler_view); - TR_CTX_INIT(sampler_view_destroy); - TR_CTX_INIT(create_surface); - TR_CTX_INIT(surface_destroy); - TR_CTX_INIT(set_vertex_buffers); - TR_CTX_INIT(create_stream_output_target); - TR_CTX_INIT(stream_output_target_destroy); - TR_CTX_INIT(set_stream_output_targets); - TR_CTX_INIT(resource_copy_region); - TR_CTX_INIT(blit); - TR_CTX_INIT(flush_resource); - TR_CTX_INIT(clear); - TR_CTX_INIT(clear_render_target); - TR_CTX_INIT(clear_depth_stencil); - TR_CTX_INIT(clear_texture); - TR_CTX_INIT(flush); - TR_CTX_INIT(generate_mipmap); - TR_CTX_INIT(texture_barrier); - TR_CTX_INIT(memory_barrier); - TR_CTX_INIT(resource_commit); - TR_CTX_INIT(set_tess_state); - TR_CTX_INIT(set_shader_buffers); - TR_CTX_INIT(launch_grid); - TR_CTX_INIT(set_shader_images); - TR_CTX_INIT(create_texture_handle); - TR_CTX_INIT(delete_texture_handle); - TR_CTX_INIT(make_texture_handle_resident); - TR_CTX_INIT(create_image_handle); - TR_CTX_INIT(delete_image_handle); - TR_CTX_INIT(make_image_handle_resident); - - TR_CTX_INIT(transfer_map); - TR_CTX_INIT(transfer_unmap); - TR_CTX_INIT(transfer_flush_region); - TR_CTX_INIT(buffer_subdata); - TR_CTX_INIT(texture_subdata); - TR_CTX_INIT(invalidate_resource); - -#undef TR_CTX_INIT - - tr_ctx->pipe = pipe; - - return &tr_ctx->base; - -error1: - return pipe; -} - - -/** - * Sanity checker: check that the given context really is a - * trace context (and not the wrapped driver's context). - */ -void -trace_context_check(const struct pipe_context *pipe) -{ - MAYBE_UNUSED struct trace_context *tr_ctx = (struct trace_context *) pipe; - assert(tr_ctx->base.destroy == trace_context_destroy); -} diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h deleted file mode 100644 index ad57d9d5243..00000000000 --- a/src/gallium/drivers/trace/tr_context.h +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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 TR_CONTEXT_H_ -#define TR_CONTEXT_H_ - - -#include "pipe/p_compiler.h" -#include "util/u_debug.h" -#include "pipe/p_context.h" - -#include "tr_screen.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -struct trace_screen; - -struct trace_context -{ - struct pipe_context base; - - struct pipe_context *pipe; -}; - - -void -trace_context_check(const struct pipe_context *pipe); - - -static inline struct trace_context * -trace_context(struct pipe_context *pipe) -{ - assert(pipe); -#ifdef DEBUG - trace_context_check(pipe); -#endif - return (struct trace_context *)pipe; -} - - -struct pipe_context * -trace_context_create(struct trace_screen *tr_scr, - struct pipe_context *pipe); - - -#ifdef __cplusplus -} -#endif - -#endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c deleted file mode 100644 index 49349496ac6..00000000000 --- a/src/gallium/drivers/trace/tr_dump.c +++ /dev/null @@ -1,599 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - - -/** - * @file - * Trace dumping functions. - * - * For now we just use standard XML for dumping the trace calls, as this is - * simple to write, parse, and visually inspect, but the actual representation - * is abstracted out of this file, so that we can switch to a binary - * representation if/when it becomes justified. - * - * @author Jose Fonseca - */ - -#include "pipe/p_config.h" - -#include -#include - -#include "pipe/p_compiler.h" -#include "os/os_thread.h" -#include "util/os_time.h" -#include "util/u_debug.h" -#include "util/u_memory.h" -#include "util/u_string.h" -#include "util/u_math.h" -#include "util/u_format.h" - -#include "tr_dump.h" -#include "tr_screen.h" -#include "tr_texture.h" - - -static boolean close_stream = FALSE; -static FILE *stream = NULL; -static mtx_t call_mutex = _MTX_INITIALIZER_NP; -static long unsigned call_no = 0; -static boolean dumping = FALSE; - - -static inline void -trace_dump_write(const char *buf, size_t size) -{ - if (stream) { - fwrite(buf, size, 1, stream); - } -} - - -static inline void -trace_dump_writes(const char *s) -{ - trace_dump_write(s, strlen(s)); -} - - -static inline void -trace_dump_writef(const char *format, ...) -{ - static char buf[1024]; - unsigned len; - va_list ap; - va_start(ap, format); - len = util_vsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); - trace_dump_write(buf, len); -} - - -static inline void -trace_dump_escape(const char *str) -{ - const unsigned char *p = (const unsigned char *)str; - unsigned char c; - while((c = *p++) != 0) { - if(c == '<') - trace_dump_writes("<"); - else if(c == '>') - trace_dump_writes(">"); - else if(c == '&') - trace_dump_writes("&"); - else if(c == '\'') - trace_dump_writes("'"); - else if(c == '\"') - trace_dump_writes("""); - else if(c >= 0x20 && c <= 0x7e) - trace_dump_writef("%c", c); - else - trace_dump_writef("&#%u;", c); - } -} - - -static inline void -trace_dump_indent(unsigned level) -{ - unsigned i; - for(i = 0; i < level; ++i) - trace_dump_writes("\t"); -} - - -static inline void -trace_dump_newline(void) -{ - trace_dump_writes("\n"); -} - - -static inline void -trace_dump_tag_begin(const char *name) -{ - trace_dump_writes("<"); - trace_dump_writes(name); - trace_dump_writes(">"); -} - -static inline void -trace_dump_tag_begin1(const char *name, - const char *attr1, const char *value1) -{ - trace_dump_writes("<"); - trace_dump_writes(name); - trace_dump_writes(" "); - trace_dump_writes(attr1); - trace_dump_writes("='"); - trace_dump_escape(value1); - trace_dump_writes("'>"); -} - - -static inline void -trace_dump_tag_end(const char *name) -{ - trace_dump_writes(""); -} - -void -trace_dump_trace_flush(void) -{ - if (stream) { - fflush(stream); - } -} - -static void -trace_dump_trace_close(void) -{ - if (stream) { - trace_dump_writes("\n"); - if (close_stream) { - fclose(stream); - close_stream = FALSE; - stream = NULL; - } - call_no = 0; - } -} - - -static void -trace_dump_call_time(int64_t time) -{ - if (stream) { - trace_dump_indent(2); - trace_dump_tag_begin("time"); - trace_dump_int(time); - trace_dump_tag_end("time"); - trace_dump_newline(); - } -} - - -boolean -trace_dump_trace_begin(void) -{ - const char *filename; - - filename = debug_get_option("GALLIUM_TRACE", NULL); - if (!filename) - return FALSE; - - if (!stream) { - - if (strcmp(filename, "stderr") == 0) { - close_stream = FALSE; - stream = stderr; - } - else if (strcmp(filename, "stdout") == 0) { - close_stream = FALSE; - stream = stdout; - } - else { - close_stream = TRUE; - stream = fopen(filename, "wt"); - if (!stream) - return FALSE; - } - - trace_dump_writes("\n"); - trace_dump_writes("\n"); - trace_dump_writes("\n"); - - /* Many applications don't exit cleanly, others may create and destroy a - * screen multiple times, so we only write tag and close at exit - * time. - */ - atexit(trace_dump_trace_close); - } - - return TRUE; -} - -boolean trace_dump_trace_enabled(void) -{ - return stream ? TRUE : FALSE; -} - -/* - * Call lock - */ - -void trace_dump_call_lock(void) -{ - mtx_lock(&call_mutex); -} - -void trace_dump_call_unlock(void) -{ - mtx_unlock(&call_mutex); -} - -/* - * Dumping control - */ - -void trace_dumping_start_locked(void) -{ - dumping = TRUE; -} - -void trace_dumping_stop_locked(void) -{ - dumping = FALSE; -} - -boolean trace_dumping_enabled_locked(void) -{ - return dumping; -} - -void trace_dumping_start(void) -{ - mtx_lock(&call_mutex); - trace_dumping_start_locked(); - mtx_unlock(&call_mutex); -} - -void trace_dumping_stop(void) -{ - mtx_lock(&call_mutex); - trace_dumping_stop_locked(); - mtx_unlock(&call_mutex); -} - -boolean trace_dumping_enabled(void) -{ - boolean ret; - mtx_lock(&call_mutex); - ret = trace_dumping_enabled_locked(); - mtx_unlock(&call_mutex); - return ret; -} - -/* - * Dump functions - */ - -static int64_t call_start_time = 0; - -void trace_dump_call_begin_locked(const char *klass, const char *method) -{ - if (!dumping) - return; - - ++call_no; - trace_dump_indent(1); - trace_dump_writes(""); - trace_dump_newline(); - - call_start_time = os_time_get(); -} - -void trace_dump_call_end_locked(void) -{ - int64_t call_end_time; - - if (!dumping) - return; - - call_end_time = os_time_get(); - - trace_dump_call_time(call_end_time - call_start_time); - trace_dump_indent(1); - trace_dump_tag_end("call"); - trace_dump_newline(); - fflush(stream); -} - -void trace_dump_call_begin(const char *klass, const char *method) -{ - mtx_lock(&call_mutex); - trace_dump_call_begin_locked(klass, method); -} - -void trace_dump_call_end(void) -{ - trace_dump_call_end_locked(); - mtx_unlock(&call_mutex); -} - -void trace_dump_arg_begin(const char *name) -{ - if (!dumping) - return; - - trace_dump_indent(2); - trace_dump_tag_begin1("arg", "name", name); -} - -void trace_dump_arg_end(void) -{ - if (!dumping) - return; - - trace_dump_tag_end("arg"); - trace_dump_newline(); -} - -void trace_dump_ret_begin(void) -{ - if (!dumping) - return; - - trace_dump_indent(2); - trace_dump_tag_begin("ret"); -} - -void trace_dump_ret_end(void) -{ - if (!dumping) - return; - - trace_dump_tag_end("ret"); - trace_dump_newline(); -} - -void trace_dump_bool(int value) -{ - if (!dumping) - return; - - trace_dump_writef("%c", value ? '1' : '0'); -} - -void trace_dump_int(long long int value) -{ - if (!dumping) - return; - - trace_dump_writef("%lli", value); -} - -void trace_dump_uint(long long unsigned value) -{ - if (!dumping) - return; - - trace_dump_writef("%llu", value); -} - -void trace_dump_float(double value) -{ - if (!dumping) - return; - - trace_dump_writef("%g", value); -} - -void trace_dump_bytes(const void *data, - size_t size) -{ - static const char hex_table[16] = "0123456789ABCDEF"; - const uint8_t *p = data; - size_t i; - - if (!dumping) - return; - - trace_dump_writes(""); - for(i = 0; i < size; ++i) { - uint8_t byte = *p++; - char hex[2]; - hex[0] = hex_table[byte >> 4]; - hex[1] = hex_table[byte & 0xf]; - trace_dump_write(hex, 2); - } - trace_dump_writes(""); -} - -void trace_dump_box_bytes(const void *data, - struct pipe_resource *resource, - const struct pipe_box *box, - unsigned stride, - unsigned slice_stride) -{ - enum pipe_format format = resource->format; - size_t size; - - assert(box->height > 0); - assert(box->depth > 0); - - size = util_format_get_nblocksx(format, box->width ) * util_format_get_blocksize(format) - + (util_format_get_nblocksy(format, box->height) - 1) * stride - + (box->depth - 1) * slice_stride; - - /* - * Only dump buffer transfers to avoid huge files. - * TODO: Make this run-time configurable - */ - if (resource->target != PIPE_BUFFER) { - size = 0; - } - - trace_dump_bytes(data, size); -} - -void trace_dump_string(const char *str) -{ - if (!dumping) - return; - - trace_dump_writes(""); - trace_dump_escape(str); - trace_dump_writes(""); -} - -void trace_dump_enum(const char *value) -{ - if (!dumping) - return; - - trace_dump_writes(""); - trace_dump_escape(value); - trace_dump_writes(""); -} - -void trace_dump_array_begin(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_array_end(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_elem_begin(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_elem_end(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_struct_begin(const char *name) -{ - if (!dumping) - return; - - trace_dump_writef("", name); -} - -void trace_dump_struct_end(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_member_begin(const char *name) -{ - if (!dumping) - return; - - trace_dump_writef("", name); -} - -void trace_dump_member_end(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_null(void) -{ - if (!dumping) - return; - - trace_dump_writes(""); -} - -void trace_dump_ptr(const void *value) -{ - if (!dumping) - return; - - if(value) - trace_dump_writef("0x%08lx", (unsigned long)(uintptr_t)value); - else - trace_dump_null(); -} - -void trace_dump_surface_ptr(struct pipe_surface *_surface) -{ - if (!dumping) - return; - - if (_surface) { - struct trace_surface *tr_surf = trace_surface(_surface); - trace_dump_ptr(tr_surf->surface); - } else { - trace_dump_null(); - } -} - -void trace_dump_transfer_ptr(struct pipe_transfer *_transfer) -{ - if (!dumping) - return; - - if (_transfer) { - struct trace_transfer *tr_tran = trace_transfer(_transfer); - trace_dump_ptr(tr_tran->transfer); - } else { - trace_dump_null(); - } -} diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h deleted file mode 100644 index 7a268e31c46..00000000000 --- a/src/gallium/drivers/trace/tr_dump.h +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - -/** - * @file - * Trace data dumping primitives. - */ - -#ifndef TR_DUMP_H -#define TR_DUMP_H - - -#include "pipe/p_compiler.h" -#include "pipe/p_format.h" - -struct pipe_resource; -struct pipe_surface; -struct pipe_transfer; -struct pipe_box; - -/* - * Low level dumping controls. - * - * Opening the trace file and checking if that is opened. - */ -boolean trace_dump_trace_begin(void); -boolean trace_dump_trace_enabled(void); -void trace_dump_trace_flush(void); - -/* - * Lock and unlock the call mutex. - * - * It used by the none locked version of dumping control - * and begin/end call dump functions. - * - * Begin takes the lock while end unlocks it. Use the _locked - * version to avoid locking/unlocking it. - */ -void trace_dump_call_lock(void); -void trace_dump_call_unlock(void); - -/* - * High level dumping control. - */ -void trace_dumping_start_locked(void); -void trace_dumping_stop_locked(void); -boolean trace_dumping_enabled_locked(void); -void trace_dumping_start(void); -void trace_dumping_stop(void); -boolean trace_dumping_enabled(void); - -void trace_dump_call_begin_locked(const char *klass, const char *method); -void trace_dump_call_end_locked(void); -void trace_dump_call_begin(const char *klass, const char *method); -void trace_dump_call_end(void); - -void trace_dump_arg_begin(const char *name); -void trace_dump_arg_end(void); -void trace_dump_ret_begin(void); -void trace_dump_ret_end(void); -void trace_dump_bool(int value); -void trace_dump_int(long long int value); -void trace_dump_uint(long long unsigned value); -void trace_dump_float(double value); -void trace_dump_bytes(const void *data, size_t size); -void trace_dump_box_bytes(const void *data, - struct pipe_resource *resource, - const struct pipe_box *box, - unsigned stride, - unsigned slice_stride); -void trace_dump_string(const char *str); -void trace_dump_enum(const char *value); -void trace_dump_array_begin(void); -void trace_dump_array_end(void); -void trace_dump_elem_begin(void); -void trace_dump_elem_end(void); -void trace_dump_struct_begin(const char *name); -void trace_dump_struct_end(void); -void trace_dump_member_begin(const char *name); -void trace_dump_member_end(void); -void trace_dump_null(void); -void trace_dump_ptr(const void *value); -/* will turn a wrapped object into the real one and dump ptr */ -void trace_dump_surface_ptr(struct pipe_surface *_surface); -void trace_dump_transfer_ptr(struct pipe_transfer *_transfer); - -/* - * Code saving macros. - */ - -#define trace_dump_arg(_type, _arg) \ - do { \ - trace_dump_arg_begin(#_arg); \ - trace_dump_##_type(_arg); \ - trace_dump_arg_end(); \ - } while(0) - -#define trace_dump_arg_struct(_type, _arg) \ - do { \ - trace_dump_arg_begin(#_arg); \ - trace_dump_##_type(&_arg); \ - trace_dump_arg_end(); \ - } while(0) - -#define trace_dump_ret(_type, _arg) \ - do { \ - trace_dump_ret_begin(); \ - trace_dump_##_type(_arg); \ - trace_dump_ret_end(); \ - } while(0) - -#define trace_dump_array(_type, _obj, _size) \ - do { \ - if (_obj) { \ - size_t idx; \ - trace_dump_array_begin(); \ - for(idx = 0; idx < (_size); ++idx) { \ - trace_dump_elem_begin(); \ - trace_dump_##_type((_obj)[idx]); \ - trace_dump_elem_end(); \ - } \ - trace_dump_array_end(); \ - } else { \ - trace_dump_null(); \ - } \ - } while(0) - -#define trace_dump_struct_array(_type, _obj, _size) \ - do { \ - if (_obj) { \ - size_t idx; \ - trace_dump_array_begin(); \ - for(idx = 0; idx < (_size); ++idx) { \ - trace_dump_elem_begin(); \ - trace_dump_##_type(&(_obj)[idx]); \ - trace_dump_elem_end(); \ - } \ - trace_dump_array_end(); \ - } else { \ - trace_dump_null(); \ - } \ - } while(0) - -#define trace_dump_member(_type, _obj, _member) \ - do { \ - trace_dump_member_begin(#_member); \ - trace_dump_##_type((_obj)->_member); \ - trace_dump_member_end(); \ - } while(0) - -#define trace_dump_arg_array(_type, _arg, _size) \ - do { \ - trace_dump_arg_begin(#_arg); \ - trace_dump_array(_type, _arg, _size); \ - trace_dump_arg_end(); \ - } while(0) - -#define trace_dump_member_array(_type, _obj, _member) \ - do { \ - trace_dump_member_begin(#_member); \ - trace_dump_array(_type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ - trace_dump_member_end(); \ - } while(0) - - -#endif /* TR_DUMP_H */ diff --git a/src/gallium/drivers/trace/tr_dump_defines.h b/src/gallium/drivers/trace/tr_dump_defines.h deleted file mode 100644 index 7f969a30333..00000000000 --- a/src/gallium/drivers/trace/tr_dump_defines.h +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************** - * - * Copyright 2013 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 TR_DUMP_DEFINES_H_ -#define TR_DUMP_DEFINES_H_ - -#include "pipe/p_compiler.h" -#include "util/u_format.h" -#include "util/u_dump.h" -#include "tr_dump.h" - - -static inline void -trace_dump_format(enum pipe_format format) -{ - if (!trace_dumping_enabled_locked()) - return; - - trace_dump_enum(util_format_name(format)); -} - - -static inline void -trace_dump_query_type(unsigned value) -{ - if (!trace_dumping_enabled_locked()) - return; - - trace_dump_enum(util_str_query_type(value, FALSE)); -} - - - -#endif /* TR_DUMP_DEFINES_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c deleted file mode 100644 index e7e32237c4c..00000000000 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ /dev/null @@ -1,961 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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_compiler.h" -#include "util/u_memory.h" -#include "util/u_format.h" -#include "tgsi/tgsi_dump.h" - -#include "tr_dump.h" -#include "tr_dump_defines.h" -#include "tr_dump_state.h" - - -void trace_dump_resource_template(const struct pipe_resource *templat) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!templat) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_resource"); - - trace_dump_member(int, templat, target); - trace_dump_member(format, templat, format); - - trace_dump_member_begin("width"); - trace_dump_uint(templat->width0); - trace_dump_member_end(); - - trace_dump_member_begin("height"); - trace_dump_uint(templat->height0); - trace_dump_member_end(); - - trace_dump_member_begin("depth"); - trace_dump_uint(templat->depth0); - trace_dump_member_end(); - - trace_dump_member_begin("array_size"); - trace_dump_uint(templat->array_size); - trace_dump_member_end(); - - trace_dump_member(uint, templat, last_level); - trace_dump_member(uint, templat, nr_samples); - trace_dump_member(uint, templat, usage); - trace_dump_member(uint, templat, bind); - trace_dump_member(uint, templat, flags); - - trace_dump_struct_end(); -} - - -void trace_dump_box(const struct pipe_box *box) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!box) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_box"); - - trace_dump_member(int, box, x); - trace_dump_member(int, box, y); - trace_dump_member(int, box, z); - trace_dump_member(int, box, width); - trace_dump_member(int, box, height); - trace_dump_member(int, box, depth); - - trace_dump_struct_end(); -} - - -void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_rasterizer_state"); - - trace_dump_member(bool, state, flatshade); - trace_dump_member(bool, state, light_twoside); - trace_dump_member(bool, state, clamp_vertex_color); - trace_dump_member(bool, state, clamp_fragment_color); - trace_dump_member(uint, state, front_ccw); - trace_dump_member(uint, state, cull_face); - trace_dump_member(uint, state, fill_front); - trace_dump_member(uint, state, fill_back); - trace_dump_member(bool, state, offset_point); - trace_dump_member(bool, state, offset_line); - trace_dump_member(bool, state, offset_tri); - trace_dump_member(bool, state, scissor); - trace_dump_member(bool, state, poly_smooth); - trace_dump_member(bool, state, poly_stipple_enable); - trace_dump_member(bool, state, point_smooth); - trace_dump_member(bool, state, sprite_coord_mode); - trace_dump_member(bool, state, point_quad_rasterization); - trace_dump_member(bool, state, point_size_per_vertex); - trace_dump_member(bool, state, multisample); - trace_dump_member(bool, state, line_smooth); - trace_dump_member(bool, state, line_stipple_enable); - trace_dump_member(bool, state, line_last_pixel); - - trace_dump_member(bool, state, flatshade_first); - - trace_dump_member(bool, state, half_pixel_center); - trace_dump_member(bool, state, bottom_edge_rule); - - trace_dump_member(bool, state, rasterizer_discard); - - trace_dump_member(bool, state, depth_clip); - - trace_dump_member(bool, state, clip_halfz); - - trace_dump_member(uint, state, clip_plane_enable); - - trace_dump_member(uint, state, line_stipple_factor); - trace_dump_member(uint, state, line_stipple_pattern); - - trace_dump_member(uint, state, sprite_coord_enable); - - trace_dump_member(float, state, line_width); - trace_dump_member(float, state, point_size); - trace_dump_member(float, state, offset_units); - trace_dump_member(float, state, offset_scale); - trace_dump_member(float, state, offset_clamp); - - trace_dump_struct_end(); -} - - -void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_poly_stipple"); - - trace_dump_member_begin("stipple"); - trace_dump_array(uint, - state->stipple, - ARRAY_SIZE(state->stipple)); - trace_dump_member_end(); - - trace_dump_struct_end(); -} - - -void trace_dump_viewport_state(const struct pipe_viewport_state *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_viewport_state"); - - trace_dump_member_array(float, state, scale); - trace_dump_member_array(float, state, translate); - - trace_dump_struct_end(); -} - - -void trace_dump_scissor_state(const struct pipe_scissor_state *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_scissor_state"); - - trace_dump_member(uint, state, minx); - trace_dump_member(uint, state, miny); - trace_dump_member(uint, state, maxx); - trace_dump_member(uint, state, maxy); - - trace_dump_struct_end(); -} - - -void trace_dump_clip_state(const struct pipe_clip_state *state) -{ - unsigned i; - - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_clip_state"); - - trace_dump_member_begin("ucp"); - trace_dump_array_begin(); - for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { - trace_dump_elem_begin(); - trace_dump_array(float, state->ucp[i], 4); - trace_dump_elem_end(); - } - trace_dump_array_end(); - trace_dump_member_end(); - - trace_dump_struct_end(); -} - - -void trace_dump_shader_state(const struct pipe_shader_state *state) -{ - unsigned i; - - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - - trace_dump_struct_begin("pipe_shader_state"); - - trace_dump_member_begin("tokens"); - if (state->tokens) { - static char str[64 * 1024]; - tgsi_dump_str(state->tokens, 0, str, sizeof(str)); - trace_dump_string(str); - } else { - trace_dump_null(); - } - trace_dump_member_end(); - - trace_dump_member_begin("stream_output"); - trace_dump_struct_begin("pipe_stream_output_info"); - trace_dump_member(uint, &state->stream_output, num_outputs); - trace_dump_member_array(uint, &state->stream_output, stride); - trace_dump_member_begin("output"); - trace_dump_array_begin(); - for(i = 0; i < state->stream_output.num_outputs; ++i) { - trace_dump_elem_begin(); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->stream_output.output[i], register_index); - trace_dump_member(uint, &state->stream_output.output[i], start_component); - trace_dump_member(uint, &state->stream_output.output[i], num_components); - trace_dump_member(uint, &state->stream_output.output[i], output_buffer); - trace_dump_member(uint, &state->stream_output.output[i], dst_offset); - trace_dump_member(uint, &state->stream_output.output[i], stream); - trace_dump_struct_end(); - trace_dump_elem_end(); - } - trace_dump_array_end(); - trace_dump_member_end(); // output - trace_dump_struct_end(); - trace_dump_member_end(); // stream_output - - trace_dump_struct_end(); -} - - -void trace_dump_compute_state(const struct pipe_compute_state *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_compute_state"); - - trace_dump_member(uint, state, ir_type); - - trace_dump_member_begin("prog"); - if (state->prog && state->ir_type == PIPE_SHADER_IR_TGSI) { - static char str[64 * 1024]; - tgsi_dump_str(state->prog, 0, str, sizeof(str)); - trace_dump_string(str); - } else { - trace_dump_null(); - } - trace_dump_member_end(); - - trace_dump_member(uint, state, req_local_mem); - trace_dump_member(uint, state, req_private_mem); - trace_dump_member(uint, state, req_input_mem); - - trace_dump_struct_end(); -} - - -void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state) -{ - unsigned i; - - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_depth_stencil_alpha_state"); - - trace_dump_member_begin("depth"); - trace_dump_struct_begin("pipe_depth_state"); - trace_dump_member(bool, &state->depth, enabled); - trace_dump_member(bool, &state->depth, writemask); - trace_dump_member(uint, &state->depth, func); - trace_dump_struct_end(); - trace_dump_member_end(); - - trace_dump_member_begin("stencil"); - trace_dump_array_begin(); - for(i = 0; i < ARRAY_SIZE(state->stencil); ++i) { - trace_dump_elem_begin(); - trace_dump_struct_begin("pipe_stencil_state"); - trace_dump_member(bool, &state->stencil[i], enabled); - trace_dump_member(uint, &state->stencil[i], func); - trace_dump_member(uint, &state->stencil[i], fail_op); - trace_dump_member(uint, &state->stencil[i], zpass_op); - trace_dump_member(uint, &state->stencil[i], zfail_op); - trace_dump_member(uint, &state->stencil[i], valuemask); - trace_dump_member(uint, &state->stencil[i], writemask); - trace_dump_struct_end(); - trace_dump_elem_end(); - } - trace_dump_array_end(); - trace_dump_member_end(); - - trace_dump_member_begin("alpha"); - trace_dump_struct_begin("pipe_alpha_state"); - trace_dump_member(bool, &state->alpha, enabled); - trace_dump_member(uint, &state->alpha, func); - trace_dump_member(float, &state->alpha, ref_value); - trace_dump_struct_end(); - trace_dump_member_end(); - - trace_dump_struct_end(); -} - -static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state) -{ - trace_dump_struct_begin("pipe_rt_blend_state"); - - trace_dump_member(uint, state, blend_enable); - - trace_dump_member(uint, state, rgb_func); - trace_dump_member(uint, state, rgb_src_factor); - trace_dump_member(uint, state, rgb_dst_factor); - - trace_dump_member(uint, state, alpha_func); - trace_dump_member(uint, state, alpha_src_factor); - trace_dump_member(uint, state, alpha_dst_factor); - - trace_dump_member(uint, state, colormask); - - trace_dump_struct_end(); -} - -void trace_dump_blend_state(const struct pipe_blend_state *state) -{ - unsigned valid_entries = 1; - - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_blend_state"); - - trace_dump_member(bool, state, dither); - - trace_dump_member(bool, state, logicop_enable); - trace_dump_member(uint, state, logicop_func); - - trace_dump_member(bool, state, independent_blend_enable); - - trace_dump_member_begin("rt"); - if (state->independent_blend_enable) - valid_entries = PIPE_MAX_COLOR_BUFS; - trace_dump_struct_array(rt_blend_state, state->rt, valid_entries); - trace_dump_member_end(); - - trace_dump_struct_end(); -} - - -void trace_dump_blend_color(const struct pipe_blend_color *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_blend_color"); - - trace_dump_member_array(float, state, color); - - trace_dump_struct_end(); -} - -void trace_dump_stencil_ref(const struct pipe_stencil_ref *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_stencil_ref"); - - trace_dump_member_array(uint, state, ref_value); - - trace_dump_struct_end(); -} - -void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - trace_dump_struct_begin("pipe_framebuffer_state"); - - trace_dump_member(uint, state, width); - trace_dump_member(uint, state, height); - trace_dump_member(uint, state, samples); - trace_dump_member(uint, state, layers); - trace_dump_member(uint, state, nr_cbufs); - trace_dump_member_array(ptr, state, cbufs); - trace_dump_member(ptr, state, zsbuf); - - trace_dump_struct_end(); -} - - -void trace_dump_sampler_state(const struct pipe_sampler_state *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_sampler_state"); - - trace_dump_member(uint, state, wrap_s); - trace_dump_member(uint, state, wrap_t); - trace_dump_member(uint, state, wrap_r); - trace_dump_member(uint, state, min_img_filter); - trace_dump_member(uint, state, min_mip_filter); - trace_dump_member(uint, state, mag_img_filter); - trace_dump_member(uint, state, compare_mode); - trace_dump_member(uint, state, compare_func); - trace_dump_member(bool, state, normalized_coords); - trace_dump_member(uint, state, max_anisotropy); - trace_dump_member(bool, state, seamless_cube_map); - trace_dump_member(float, state, lod_bias); - trace_dump_member(float, state, min_lod); - trace_dump_member(float, state, max_lod); - trace_dump_member_array(float, state, border_color.f); - - trace_dump_struct_end(); -} - - -void trace_dump_sampler_view_template(const struct pipe_sampler_view *state, - enum pipe_texture_target target) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_sampler_view"); - - trace_dump_member(format, state, format); - - trace_dump_member_begin("u"); - trace_dump_struct_begin(""); /* anonymous */ - if (target == PIPE_BUFFER) { - trace_dump_member_begin("buf"); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->u.buf, offset); - trace_dump_member(uint, &state->u.buf, size); - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* buf */ - } else { - trace_dump_member_begin("tex"); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->u.tex, first_layer); - trace_dump_member(uint, &state->u.tex, last_layer); - trace_dump_member(uint, &state->u.tex, first_level); - trace_dump_member(uint, &state->u.tex, last_level); - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* tex */ - } - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* u */ - - trace_dump_member(uint, state, swizzle_r); - trace_dump_member(uint, state, swizzle_g); - trace_dump_member(uint, state, swizzle_b); - trace_dump_member(uint, state, swizzle_a); - - trace_dump_struct_end(); -} - - -void trace_dump_surface_template(const struct pipe_surface *state, - enum pipe_texture_target target) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_surface"); - - trace_dump_member(format, state, format); - trace_dump_member(uint, state, width); - trace_dump_member(uint, state, height); - - trace_dump_member_begin("u"); - trace_dump_struct_begin(""); /* anonymous */ - if (target == PIPE_BUFFER) { - trace_dump_member_begin("buf"); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->u.buf, first_element); - trace_dump_member(uint, &state->u.buf, last_element); - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* buf */ - } else { - trace_dump_member_begin("tex"); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->u.tex, level); - trace_dump_member(uint, &state->u.tex, first_layer); - trace_dump_member(uint, &state->u.tex, last_layer); - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* tex */ - } - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* u */ - - trace_dump_struct_end(); -} - - -void trace_dump_transfer(const struct pipe_transfer *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_transfer"); - - trace_dump_member(uint, state, box.x); - trace_dump_member(uint, state, box.y); - trace_dump_member(uint, state, box.z); - trace_dump_member(uint, state, box.width); - trace_dump_member(uint, state, box.height); - trace_dump_member(uint, state, box.depth); - - trace_dump_member(uint, state, stride); - trace_dump_member(uint, state, layer_stride); - trace_dump_member(uint, state, usage); - - trace_dump_member(ptr, state, resource); - - trace_dump_struct_end(); -} - - -void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_vertex_buffer"); - - trace_dump_member(uint, state, stride); - trace_dump_member(bool, state, is_user_buffer); - trace_dump_member(uint, state, buffer_offset); - trace_dump_member(ptr, state, buffer.resource); - - trace_dump_struct_end(); -} - - -void trace_dump_vertex_element(const struct pipe_vertex_element *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_vertex_element"); - - trace_dump_member(uint, state, src_offset); - - trace_dump_member(uint, state, vertex_buffer_index); - - trace_dump_member(format, state, src_format); - - trace_dump_struct_end(); -} - - -void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_constant_buffer"); - trace_dump_member(ptr, state, buffer); - trace_dump_member(uint, state, buffer_offset); - trace_dump_member(uint, state, buffer_size); - trace_dump_struct_end(); -} - - -void trace_dump_shader_buffer(const struct pipe_shader_buffer *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if(!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_shader_buffer"); - trace_dump_member(ptr, state, buffer); - trace_dump_member(uint, state, buffer_offset); - trace_dump_member(uint, state, buffer_size); - trace_dump_struct_end(); -} - - -void trace_dump_image_view(const struct pipe_image_view *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if(!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_image_view"); - trace_dump_member(ptr, state, resource); - trace_dump_member(uint, state, format); - trace_dump_member(uint, state, access); - - trace_dump_member_begin("u"); - trace_dump_struct_begin(""); /* anonymous */ - if (state->resource->target == PIPE_BUFFER) { - trace_dump_member_begin("buf"); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->u.buf, offset); - trace_dump_member(uint, &state->u.buf, size); - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* buf */ - } else { - trace_dump_member_begin("tex"); - trace_dump_struct_begin(""); /* anonymous */ - trace_dump_member(uint, &state->u.tex, first_layer); - trace_dump_member(uint, &state->u.tex, last_layer); - trace_dump_member(uint, &state->u.tex, level); - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* tex */ - } - trace_dump_struct_end(); /* anonymous */ - trace_dump_member_end(); /* u */ - - trace_dump_struct_end(); -} - - -void trace_dump_draw_info(const struct pipe_draw_info *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_draw_info"); - - trace_dump_member(uint, state, index_size); - trace_dump_member(uint, state, has_user_indices); - - trace_dump_member(uint, state, mode); - trace_dump_member(uint, state, start); - trace_dump_member(uint, state, count); - - trace_dump_member(uint, state, start_instance); - trace_dump_member(uint, state, instance_count); - - trace_dump_member(uint, state, vertices_per_patch); - - trace_dump_member(int, state, index_bias); - trace_dump_member(uint, state, min_index); - trace_dump_member(uint, state, max_index); - - trace_dump_member(bool, state, primitive_restart); - trace_dump_member(uint, state, restart_index); - - trace_dump_member(ptr, state, index.resource); - trace_dump_member(ptr, state, count_from_stream_output); - - if (!state->indirect) { - trace_dump_member(ptr, state, indirect); - } else { - trace_dump_member(uint, state, indirect->offset); - trace_dump_member(uint, state, indirect->stride); - trace_dump_member(uint, state, indirect->draw_count); - trace_dump_member(uint, state, indirect->indirect_draw_count_offset); - trace_dump_member(ptr, state, indirect->buffer); - trace_dump_member(ptr, state, indirect->indirect_draw_count); - } - - trace_dump_struct_end(); -} - -void trace_dump_blit_info(const struct pipe_blit_info *info) -{ - char mask[7]; - - if (!trace_dumping_enabled_locked()) - return; - - if (!info) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_blit_info"); - - trace_dump_member_begin("dst"); - trace_dump_struct_begin("dst"); - trace_dump_member(ptr, &info->dst, resource); - trace_dump_member(uint, &info->dst, level); - trace_dump_member(format, &info->dst, format); - trace_dump_member_begin("box"); - trace_dump_box(&info->dst.box); - trace_dump_member_end(); - trace_dump_struct_end(); - trace_dump_member_end(); - - trace_dump_member_begin("src"); - trace_dump_struct_begin("src"); - trace_dump_member(ptr, &info->src, resource); - trace_dump_member(uint, &info->src, level); - trace_dump_member(format, &info->src, format); - trace_dump_member_begin("box"); - trace_dump_box(&info->src.box); - trace_dump_member_end(); - trace_dump_struct_end(); - trace_dump_member_end(); - - mask[0] = (info->mask & PIPE_MASK_R) ? 'R' : '-'; - mask[1] = (info->mask & PIPE_MASK_G) ? 'G' : '-'; - mask[2] = (info->mask & PIPE_MASK_B) ? 'B' : '-'; - mask[3] = (info->mask & PIPE_MASK_A) ? 'A' : '-'; - mask[4] = (info->mask & PIPE_MASK_Z) ? 'Z' : '-'; - mask[5] = (info->mask & PIPE_MASK_S) ? 'S' : '-'; - mask[6] = 0; - - trace_dump_member_begin("mask"); - trace_dump_string(mask); - trace_dump_member_end(); - trace_dump_member(uint, info, filter); - - trace_dump_member(bool, info, scissor_enable); - trace_dump_member_begin("scissor"); - trace_dump_scissor_state(&info->scissor); - trace_dump_member_end(); - - trace_dump_struct_end(); -} - -void -trace_dump_query_result(unsigned query_type, - const union pipe_query_result *result) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!result) { - trace_dump_null(); - return; - } - - switch (query_type) { - case PIPE_QUERY_OCCLUSION_PREDICATE: - case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: - case PIPE_QUERY_SO_OVERFLOW_PREDICATE: - case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: - case PIPE_QUERY_GPU_FINISHED: - trace_dump_bool(result->b); - break; - - case PIPE_QUERY_OCCLUSION_COUNTER: - case PIPE_QUERY_TIMESTAMP: - case PIPE_QUERY_TIME_ELAPSED: - case PIPE_QUERY_PRIMITIVES_GENERATED: - case PIPE_QUERY_PRIMITIVES_EMITTED: - trace_dump_uint(result->u64); - break; - - case PIPE_QUERY_SO_STATISTICS: - trace_dump_struct_begin("pipe_query_data_so_statistics"); - trace_dump_member(uint, &result->so_statistics, num_primitives_written); - trace_dump_member(uint, &result->so_statistics, primitives_storage_needed); - trace_dump_struct_end(); - break; - - case PIPE_QUERY_TIMESTAMP_DISJOINT: - trace_dump_struct_begin("pipe_query_data_timestamp_disjoint"); - trace_dump_member(uint, &result->timestamp_disjoint, frequency); - trace_dump_member(bool, &result->timestamp_disjoint, disjoint); - trace_dump_struct_end(); - break; - - case PIPE_QUERY_PIPELINE_STATISTICS: - trace_dump_struct_begin("pipe_query_data_pipeline_statistics"); - trace_dump_member(uint, &result->pipeline_statistics, ia_vertices); - trace_dump_member(uint, &result->pipeline_statistics, ia_primitives); - trace_dump_member(uint, &result->pipeline_statistics, vs_invocations); - trace_dump_member(uint, &result->pipeline_statistics, gs_invocations); - trace_dump_member(uint, &result->pipeline_statistics, gs_primitives); - trace_dump_member(uint, &result->pipeline_statistics, c_invocations); - trace_dump_member(uint, &result->pipeline_statistics, c_primitives); - trace_dump_member(uint, &result->pipeline_statistics, ps_invocations); - trace_dump_member(uint, &result->pipeline_statistics, hs_invocations); - trace_dump_member(uint, &result->pipeline_statistics, ds_invocations); - trace_dump_member(uint, &result->pipeline_statistics, cs_invocations); - trace_dump_struct_end(); - break; - - default: - assert(query_type >= PIPE_QUERY_DRIVER_SPECIFIC); - trace_dump_uint(result->u64); - break; - } -} - -void trace_dump_grid_info(const struct pipe_grid_info *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if (!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_grid_info"); - - trace_dump_member(uint, state, pc); - trace_dump_member(ptr, state, input); - - trace_dump_member_begin("block"); - trace_dump_array(uint, state->block, ARRAY_SIZE(state->block)); - trace_dump_member_end(); - - trace_dump_member_begin("grid"); - trace_dump_array(uint, state->grid, ARRAY_SIZE(state->grid)); - trace_dump_member_end(); - - trace_dump_member(ptr, state, indirect); - trace_dump_member(uint, state, indirect_offset); - - trace_dump_struct_end(); -} - diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h deleted file mode 100644 index baff0252f9b..00000000000 --- a/src/gallium/drivers/trace/tr_dump_state.h +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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 TR_DUMP_STATE_H_ -#define TR_DUMP_STATE_H_ - -#include "pipe/p_state.h" -#include "pipe/p_shader_tokens.h" - - -void trace_dump_resource_template(const struct pipe_resource *templat); - -void trace_dump_box(const struct pipe_box *box); - -void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); - -void trace_dump_poly_stipple(const struct pipe_poly_stipple *state); - -void trace_dump_viewport_state(const struct pipe_viewport_state *state); - -void trace_dump_scissor_state(const struct pipe_scissor_state *state); - -void trace_dump_clip_state(const struct pipe_clip_state *state); - -void trace_dump_token(const struct tgsi_token *token); - -void trace_dump_shader_state(const struct pipe_shader_state *state); - -void trace_dump_compute_state(const struct pipe_compute_state *state); - -void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state); - -void trace_dump_blend_state(const struct pipe_blend_state *state); - -void trace_dump_blend_color(const struct pipe_blend_color *state); - -void trace_dump_stencil_ref(const struct pipe_stencil_ref *state); - -void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); - -void trace_dump_sampler_state(const struct pipe_sampler_state *state); - -void trace_dump_sampler_view_template(const struct pipe_sampler_view *view, - enum pipe_texture_target target); - -void trace_dump_surface_template(const struct pipe_surface *state, - enum pipe_texture_target target); - -void trace_dump_transfer(const struct pipe_transfer *state); - -void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); - -void trace_dump_vertex_element(const struct pipe_vertex_element *state); - -void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); - -void trace_dump_shader_buffer(const struct pipe_shader_buffer *buffer); - -void trace_dump_draw_info(const struct pipe_draw_info *state); - -void trace_dump_blit_info(const struct pipe_blit_info *); - -void trace_dump_query_result(unsigned query_type, - const union pipe_query_result *result); - -void trace_dump_grid_info(const struct pipe_grid_info *state); - -void trace_dump_image_view(const struct pipe_image_view *view); - -#endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_public.h b/src/gallium/drivers/trace/tr_public.h deleted file mode 100644 index b03133f8d97..00000000000 --- a/src/gallium/drivers/trace/tr_public.h +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************** - * - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - **************************************************************************/ - -#ifndef TR_PUBLIC_H -#define TR_PUBLIC_H - -#include "pipe/p_compiler.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct pipe_screen; -struct pipe_context; - -struct pipe_screen * -trace_screen_create(struct pipe_screen *screen); - -boolean -trace_enabled(void); - -#ifdef __cplusplus -} -#endif - -#endif /* TR_PUBLIC_H */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c deleted file mode 100644 index d5a81249b51..00000000000 --- a/src/gallium/drivers/trace/tr_screen.c +++ /dev/null @@ -1,684 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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_format.h" -#include "util/u_memory.h" -#include "util/simple_list.h" - -#include "tr_dump.h" -#include "tr_dump_defines.h" -#include "tr_dump_state.h" -#include "tr_texture.h" -#include "tr_context.h" -#include "tr_screen.h" -#include "tr_public.h" - - -static boolean trace = FALSE; - -static const char * -trace_screen_get_name(struct pipe_screen *_screen) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - const char *result; - - trace_dump_call_begin("pipe_screen", "get_name"); - - trace_dump_arg(ptr, screen); - - result = screen->get_name(screen); - - trace_dump_ret(string, result); - - trace_dump_call_end(); - - return result; -} - - -static const char * -trace_screen_get_vendor(struct pipe_screen *_screen) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - const char *result; - - trace_dump_call_begin("pipe_screen", "get_vendor"); - - trace_dump_arg(ptr, screen); - - result = screen->get_vendor(screen); - - trace_dump_ret(string, result); - - trace_dump_call_end(); - - return result; -} - - -static const char * -trace_screen_get_device_vendor(struct pipe_screen *_screen) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - const char *result; - - trace_dump_call_begin("pipe_screen", "get_device_vendor"); - - trace_dump_arg(ptr, screen); - - result = screen->get_device_vendor(screen); - - trace_dump_ret(string, result); - - trace_dump_call_end(); - - return result; -} - - -static struct disk_cache * -trace_screen_get_disk_shader_cache(struct pipe_screen *_screen) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - - trace_dump_call_begin("pipe_screen", "get_disk_shader_cache"); - - trace_dump_arg(ptr, screen); - - struct disk_cache *result = screen->get_disk_shader_cache(screen); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; -} - - -static int -trace_screen_get_param(struct pipe_screen *_screen, - enum pipe_cap param) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - int result; - - trace_dump_call_begin("pipe_screen", "get_param"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(int, param); - - result = screen->get_param(screen, param); - - trace_dump_ret(int, result); - - trace_dump_call_end(); - - return result; -} - - -static int -trace_screen_get_shader_param(struct pipe_screen *_screen, - enum pipe_shader_type shader, - enum pipe_shader_cap param) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - int result; - - trace_dump_call_begin("pipe_screen", "get_shader_param"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(uint, shader); - trace_dump_arg(int, param); - - result = screen->get_shader_param(screen, shader, param); - - trace_dump_ret(int, result); - - trace_dump_call_end(); - - return result; -} - - -static float -trace_screen_get_paramf(struct pipe_screen *_screen, - enum pipe_capf param) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - float result; - - trace_dump_call_begin("pipe_screen", "get_paramf"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(int, param); - - result = screen->get_paramf(screen, param); - - trace_dump_ret(float, result); - - trace_dump_call_end(); - - return result; -} - - -static int -trace_screen_get_compute_param(struct pipe_screen *_screen, - enum pipe_shader_ir ir_type, - enum pipe_compute_cap param, void *data) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - int result; - - trace_dump_call_begin("pipe_screen", "get_compute_param"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(int, ir_type); - trace_dump_arg(int, param); - trace_dump_arg(ptr, data); - - result = screen->get_compute_param(screen, ir_type, param, data); - - trace_dump_ret(int, result); - - trace_dump_call_end(); - - return result; -} - - -static boolean -trace_screen_is_format_supported(struct pipe_screen *_screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned sample_count, - unsigned tex_usage) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - boolean result; - - trace_dump_call_begin("pipe_screen", "is_format_supported"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(format, format); - trace_dump_arg(int, target); - trace_dump_arg(uint, sample_count); - trace_dump_arg(uint, tex_usage); - - result = screen->is_format_supported(screen, format, target, sample_count, - tex_usage); - - trace_dump_ret(bool, result); - - trace_dump_call_end(); - - return result; -} - - -static struct pipe_context * -trace_screen_context_create(struct pipe_screen *_screen, void *priv, - unsigned flags) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_context *result; - - trace_dump_call_begin("pipe_screen", "context_create"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, priv); - trace_dump_arg(uint, flags); - - result = screen->context_create(screen, priv, flags); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - result = trace_context_create(tr_scr, result); - - return result; -} - - -static void -trace_screen_flush_frontbuffer(struct pipe_screen *_screen, - struct pipe_resource *resource, - unsigned level, unsigned layer, - void *context_private, - struct pipe_box *sub_box) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - - trace_dump_call_begin("pipe_screen", "flush_frontbuffer"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, resource); - trace_dump_arg(uint, level); - trace_dump_arg(uint, layer); - /* XXX: hide, as there is nothing we can do with this - trace_dump_arg(ptr, context_private); - */ - - screen->flush_frontbuffer(screen, resource, level, layer, context_private, sub_box); - - trace_dump_call_end(); -} - - -static void -trace_screen_get_driver_uuid(struct pipe_screen *_screen, char *uuid) -{ - struct pipe_screen *screen = trace_screen(_screen)->screen; - - trace_dump_call_begin("pipe_screen", "get_driver_uuid"); - trace_dump_arg(ptr, screen); - - screen->get_driver_uuid(screen, uuid); - - trace_dump_ret(string, uuid); - trace_dump_call_end(); -} - -static void -trace_screen_get_device_uuid(struct pipe_screen *_screen, char *uuid) -{ - struct pipe_screen *screen = trace_screen(_screen)->screen; - - trace_dump_call_begin("pipe_screen", "get_device_uuid"); - trace_dump_arg(ptr, screen); - - screen->get_device_uuid(screen, uuid); - - trace_dump_ret(string, uuid); - trace_dump_call_end(); -} - - -/******************************************************************** - * texture - */ - - -static struct pipe_resource * -trace_screen_resource_create(struct pipe_screen *_screen, - const struct pipe_resource *templat) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_resource *result; - - trace_dump_call_begin("pipe_screen", "resource_create"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(resource_template, templat); - - result = screen->resource_create(screen, templat); - - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - if (result) - result->screen = _screen; - return result; -} - -static struct pipe_resource * -trace_screen_resource_from_handle(struct pipe_screen *_screen, - const struct pipe_resource *templ, - struct winsys_handle *handle, - unsigned usage) -{ - struct trace_screen *tr_screen = trace_screen(_screen); - struct pipe_screen *screen = tr_screen->screen; - struct pipe_resource *result; - - /* TODO trace call */ - - result = screen->resource_from_handle(screen, templ, handle, usage); - - if (result) - result->screen = _screen; - return result; -} - -static bool -trace_screen_check_resource_capability(struct pipe_screen *_screen, - struct pipe_resource *resource, - unsigned bind) -{ - struct pipe_screen *screen = trace_screen(_screen)->screen; - - return screen->check_resource_capability(screen, resource, bind); -} - -static boolean -trace_screen_resource_get_handle(struct pipe_screen *_screen, - struct pipe_context *_pipe, - struct pipe_resource *resource, - struct winsys_handle *handle, - unsigned usage) -{ - struct trace_screen *tr_screen = trace_screen(_screen); - struct trace_context *tr_pipe = _pipe ? trace_context(_pipe) : NULL; - struct pipe_screen *screen = tr_screen->screen; - - /* TODO trace call */ - - return screen->resource_get_handle(screen, tr_pipe ? tr_pipe->pipe : NULL, - resource, handle, usage); -} - -static struct pipe_resource * -trace_screen_resource_from_memobj(struct pipe_screen *_screen, - const struct pipe_resource *templ, - struct pipe_memory_object *memobj, - uint64_t offset) -{ - struct pipe_screen *screen = trace_screen(_screen)->screen; - - trace_dump_call_begin("pipe_screen", "resource_from_memobj"); - trace_dump_arg(ptr, screen); - trace_dump_arg(resource_template, templ); - trace_dump_arg(ptr, memobj); - trace_dump_arg(uint, offset); - - struct pipe_resource *res = - screen->resource_from_memobj(screen, templ, memobj, offset); - - if (!res) - return NULL; - res->screen = _screen; - - trace_dump_ret(ptr, res); - trace_dump_call_end(); - return res; -} - -static void -trace_screen_resource_changed(struct pipe_screen *_screen, - struct pipe_resource *resource) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - - trace_dump_call_begin("pipe_screen", "resource_changed"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, resource); - - screen->resource_changed(screen, resource); - - trace_dump_call_end(); -} - -static void -trace_screen_resource_destroy(struct pipe_screen *_screen, - struct pipe_resource *resource) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - - /* Don't trace this, because due to the lack of pipe_resource wrapping, - * we can get this call from inside of driver calls, which would try - * to lock an already-locked mutex. - */ - screen->resource_destroy(screen, resource); -} - - -/******************************************************************** - * fence - */ - - -static void -trace_screen_fence_reference(struct pipe_screen *_screen, - struct pipe_fence_handle **pdst, - struct pipe_fence_handle *src) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_fence_handle *dst; - - assert(pdst); - dst = *pdst; - - trace_dump_call_begin("pipe_screen", "fence_reference"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, dst); - trace_dump_arg(ptr, src); - - screen->fence_reference(screen, pdst, src); - - trace_dump_call_end(); -} - - -static boolean -trace_screen_fence_finish(struct pipe_screen *_screen, - struct pipe_context *_ctx, - struct pipe_fence_handle *fence, - uint64_t timeout) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - struct pipe_context *ctx = _ctx ? trace_context(_ctx)->pipe : NULL; - int result; - - trace_dump_call_begin("pipe_screen", "fence_finish"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, ctx); - trace_dump_arg(ptr, fence); - trace_dump_arg(uint, timeout); - - result = screen->fence_finish(screen, ctx, fence, timeout); - - trace_dump_ret(bool, result); - - trace_dump_call_end(); - - return result; -} - - -/******************************************************************** - * memobj - */ - -static struct pipe_memory_object * -trace_screen_memobj_create_from_handle(struct pipe_screen *_screen, - struct winsys_handle *handle, - bool dedicated) -{ - struct pipe_screen *screen = trace_screen(_screen)->screen; - - trace_dump_call_begin("pipe_screen", "memobj_create_from_handle"); - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, handle); - trace_dump_arg(bool, dedicated); - - struct pipe_memory_object *res = - screen->memobj_create_from_handle(screen, handle, dedicated); - - trace_dump_ret(ptr, res); - trace_dump_call_end(); - - return res; -} - -static void -trace_screen_memobj_destroy(struct pipe_screen *_screen, - struct pipe_memory_object *memobj) -{ - struct pipe_screen *screen = trace_screen(_screen)->screen; - - trace_dump_call_begin("pipe_screen", "memobj_destroy"); - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, memobj); - trace_dump_call_end(); - - screen->memobj_destroy(screen, memobj); -} - - -/******************************************************************** - * screen - */ - -static uint64_t -trace_screen_get_timestamp(struct pipe_screen *_screen) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - uint64_t result; - - trace_dump_call_begin("pipe_screen", "get_timestamp"); - trace_dump_arg(ptr, screen); - - result = screen->get_timestamp(screen); - - trace_dump_ret(uint, result); - trace_dump_call_end(); - - return result; -} - -static void -trace_screen_destroy(struct pipe_screen *_screen) -{ - struct trace_screen *tr_scr = trace_screen(_screen); - struct pipe_screen *screen = tr_scr->screen; - - trace_dump_call_begin("pipe_screen", "destroy"); - trace_dump_arg(ptr, screen); - trace_dump_call_end(); - - screen->destroy(screen); - - FREE(tr_scr); -} - -boolean -trace_enabled(void) -{ - static boolean firstrun = TRUE; - - if (!firstrun) - return trace; - firstrun = FALSE; - - if(trace_dump_trace_begin()) { - trace_dumping_start(); - trace = TRUE; - } - - return trace; -} - -struct pipe_screen * -trace_screen_create(struct pipe_screen *screen) -{ - struct trace_screen *tr_scr; - - if (!trace_enabled()) - goto error1; - - trace_dump_call_begin("", "pipe_screen_create"); - - tr_scr = CALLOC_STRUCT(trace_screen); - if (!tr_scr) - goto error2; - -#define SCR_INIT(_member) \ - tr_scr->base._member = screen->_member ? trace_screen_##_member : NULL - - tr_scr->base.destroy = trace_screen_destroy; - tr_scr->base.get_name = trace_screen_get_name; - tr_scr->base.get_vendor = trace_screen_get_vendor; - tr_scr->base.get_device_vendor = trace_screen_get_device_vendor; - SCR_INIT(get_disk_shader_cache); - tr_scr->base.get_param = trace_screen_get_param; - tr_scr->base.get_shader_param = trace_screen_get_shader_param; - tr_scr->base.get_paramf = trace_screen_get_paramf; - tr_scr->base.get_compute_param = trace_screen_get_compute_param; - tr_scr->base.is_format_supported = trace_screen_is_format_supported; - assert(screen->context_create); - tr_scr->base.context_create = trace_screen_context_create; - tr_scr->base.resource_create = trace_screen_resource_create; - tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; - SCR_INIT(check_resource_capability); - tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; - SCR_INIT(resource_from_memobj); - SCR_INIT(resource_changed); - tr_scr->base.resource_destroy = trace_screen_resource_destroy; - tr_scr->base.fence_reference = trace_screen_fence_reference; - tr_scr->base.fence_finish = trace_screen_fence_finish; - SCR_INIT(memobj_create_from_handle); - SCR_INIT(memobj_destroy); - tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; - tr_scr->base.get_timestamp = trace_screen_get_timestamp; - SCR_INIT(get_driver_uuid); - SCR_INIT(get_device_uuid); - - tr_scr->screen = screen; - - trace_dump_ret(ptr, screen); - trace_dump_call_end(); - - return &tr_scr->base; - -error2: - trace_dump_ret(ptr, screen); - trace_dump_call_end(); -error1: - return screen; -} - - -struct trace_screen * -trace_screen(struct pipe_screen *screen) -{ - assert(screen); - assert(screen->destroy == trace_screen_destroy); - return (struct trace_screen *)screen; -} diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h deleted file mode 100644 index 65ea4fb6a43..00000000000 --- a/src/gallium/drivers/trace/tr_screen.h +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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 TR_SCREEN_H_ -#define TR_SCREEN_H_ - - -#include "pipe/p_screen.h" -#include "os/os_thread.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * It often happens that new data is written directly to the user buffers - * without mapping/unmapping. This flag marks user buffers, so that their - * contents can be dumped before being used by the pipe context. - */ -#define TRACE_FLAG_USER_BUFFER (1 << 31) - - -struct trace_screen -{ - struct pipe_screen base; - - struct pipe_screen *screen; -}; - - -struct trace_screen * -trace_screen(struct pipe_screen *screen); - - -#ifdef __cplusplus -} -#endif - -#endif /* TR_SCREEN_H_ */ diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c deleted file mode 100644 index fe0c7b52c9b..00000000000 --- a/src/gallium/drivers/trace/tr_texture.c +++ /dev/null @@ -1,119 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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_hash_table.h" -#include "util/u_memory.h" -#include "util/simple_list.h" - -#include "tr_screen.h" -#include "tr_context.h" -#include "tr_texture.h" - - -struct pipe_surface * -trace_surf_create(struct trace_context *tr_ctx, - struct pipe_resource *res, - struct pipe_surface *surface) -{ - struct trace_surface *tr_surf; - - if (!surface) - goto error; - - assert(surface->texture == res); - - tr_surf = CALLOC_STRUCT(trace_surface); - if (!tr_surf) - goto error; - - memcpy(&tr_surf->base, surface, sizeof(struct pipe_surface)); - tr_surf->base.context = &tr_ctx->base; - - pipe_reference_init(&tr_surf->base.reference, 1); - tr_surf->base.texture = NULL; - pipe_resource_reference(&tr_surf->base.texture, res); - tr_surf->surface = surface; - - return &tr_surf->base; - -error: - pipe_surface_reference(&surface, NULL); - return NULL; -} - - -void -trace_surf_destroy(struct trace_surface *tr_surf) -{ - trace_context_check(tr_surf->base.context); - pipe_resource_reference(&tr_surf->base.texture, NULL); - pipe_surface_reference(&tr_surf->surface, NULL); - FREE(tr_surf); -} - - -struct pipe_transfer * -trace_transfer_create(struct trace_context *tr_ctx, - struct pipe_resource *res, - struct pipe_transfer *transfer) -{ - struct trace_transfer *tr_trans; - - if (!transfer) - goto error; - - assert(transfer->resource == res); - - tr_trans = CALLOC_STRUCT(trace_transfer); - if (!tr_trans) - goto error; - - memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer)); - - tr_trans->base.resource = NULL; - tr_trans->transfer = transfer; - - pipe_resource_reference(&tr_trans->base.resource, res); - assert(tr_trans->base.resource == res); - - return &tr_trans->base; - -error: - tr_ctx->pipe->transfer_unmap(tr_ctx->pipe, transfer); - return NULL; -} - - -void -trace_transfer_destroy(struct trace_context *tr_context, - struct trace_transfer *tr_trans) -{ - pipe_resource_reference(&tr_trans->base.resource, NULL); - FREE(tr_trans); -} - diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h deleted file mode 100644 index e5dfc53fdb0..00000000000 --- a/src/gallium/drivers/trace/tr_texture.h +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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 TR_TEXTURE_H_ -#define TR_TEXTURE_H_ - - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - -#include "tr_screen.h" - -struct trace_context; - - -struct tr_list -{ - struct tr_list *next; - struct tr_list *prev; -}; - -struct trace_surface -{ - struct pipe_surface base; - - struct pipe_surface *surface; - - struct tr_list list; -}; - - -struct trace_sampler_view -{ - struct pipe_sampler_view base; - - struct pipe_sampler_view *sampler_view; -}; - - -struct trace_transfer -{ - struct pipe_transfer base; - - struct pipe_transfer *transfer; - struct pipe_context *pipe; - - struct tr_list list; - - void *map; -}; - - -static inline struct trace_surface * -trace_surface(struct pipe_surface *surface) -{ - if (!surface) - return NULL; - return (struct trace_surface *)surface; -} - - -static inline struct trace_sampler_view * -trace_sampler_view(struct pipe_sampler_view *sampler_view) -{ - if (!sampler_view) - return NULL; - return (struct trace_sampler_view *)sampler_view; -} - - -static inline struct trace_transfer * -trace_transfer(struct pipe_transfer *transfer) -{ - if (!transfer) - return NULL; - return (struct trace_transfer *)transfer; -} - - -struct pipe_surface * -trace_surf_create(struct trace_context *tr_ctx, - struct pipe_resource *tr_res, - struct pipe_surface *surface); - -void -trace_surf_destroy(struct trace_surface *tr_surf); - -struct pipe_transfer * -trace_transfer_create(struct trace_context *tr_ctx, - struct pipe_resource *tr_res, - struct pipe_transfer *transfer); - -void -trace_transfer_destroy(struct trace_context *tr_ctx, - struct trace_transfer *tr_trans); - - -#endif /* TR_TEXTURE_H_ */ diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl deleted file mode 100644 index 12458ae3287..00000000000 --- a/src/gallium/drivers/trace/trace.xsl +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - - - - - Gallium Trace - - - -
      - -
    - - -
    - - -
  • - - - - - - :: - - - ( - - ) - -
  • -
    - - - - = - - - , - - - - - = - - - - - - - - - - - - ... - - - - - - " - - - - " - - - - - { - - } - - - - - - , - - - - - - NULL - - - - - - - - - - - - - - - - - - - - -
    - - - -
    - - - -
    -
    - - - - - - - - - - - - - - - - - - - - -
    diff --git a/src/gallium/meson.build b/src/gallium/meson.build index 68225112c54..c4dd8e1c26d 100644 --- a/src/gallium/meson.build +++ b/src/gallium/meson.build @@ -24,10 +24,6 @@ inc_gallium_winsys = include_directories('winsys') subdir('auxiliary') subdir('auxiliary/pipe-loader') -subdir('drivers/ddebug') -subdir('drivers/noop') -subdir('drivers/trace') -subdir('drivers/rbug') subdir('winsys/sw/null') if with_dri subdir('winsys/sw/dri') diff --git a/src/gallium/state_trackers/osmesa/Makefile.am b/src/gallium/state_trackers/osmesa/Makefile.am index e5f2a5e18a1..05e3ca0d739 100644 --- a/src/gallium/state_trackers/osmesa/Makefile.am +++ b/src/gallium/state_trackers/osmesa/Makefile.am @@ -33,8 +33,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/gallium/winsys \ -I$(top_srcdir)/src/gallium/state_trackers/glx/xlib \ -I$(top_srcdir)/src/gallium/auxiliary \ - -DGALLIUM_SOFTPIPE \ - -DGALLIUM_TRACE + -DGALLIUM_SOFTPIPE noinst_LTLIBRARIES = libosmesa.la diff --git a/src/gallium/state_trackers/osmesa/meson.build b/src/gallium/state_trackers/osmesa/meson.build index dacf10512d6..912a6226f74 100644 --- a/src/gallium/state_trackers/osmesa/meson.build +++ b/src/gallium/state_trackers/osmesa/meson.build @@ -21,7 +21,7 @@ libosmesa_st = static_library( 'osmesa_st', 'osmesa.c', - c_args : ['-DGALLIUM_SOFTPIPE', '-DGALLIUM_TRACE'], + c_args : ['-DGALLIUM_SOFTPIPE'], include_directories : [ inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_mapi, inc_mesa, ], diff --git a/src/gallium/targets/d3dadapter9/Makefile.am b/src/gallium/targets/d3dadapter9/Makefile.am index c2aae0c7808..69cebbcd16f 100644 --- a/src/gallium/targets/d3dadapter9/Makefile.am +++ b/src/gallium/targets/d3dadapter9/Makefile.am @@ -35,10 +35,7 @@ AM_CFLAGS = \ $(VISIBILITY_CFLAGS) AM_CPPFLAGS = \ - $(DEFINES) \ - -DGALLIUM_DDEBUG \ - -DGALLIUM_RBUG \ - -DGALLIUM_TRACE + $(DEFINES) ninedir = $(D3D_DRIVER_INSTALL_DIR) nine_LTLIBRARIES = d3dadapter9.la @@ -70,9 +67,6 @@ d3dadapter9_la_LIBADD = \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ $(top_builddir)/src/gallium/state_trackers/nine/libninetracker.la \ $(top_builddir)/src/util/libmesautil.la \ - $(top_builddir)/src/gallium/drivers/ddebug/libddebug.la \ - $(top_builddir)/src/gallium/drivers/rbug/librbug.la \ - $(top_builddir)/src/gallium/drivers/trace/libtrace.la \ $(EXPAT_LIBS) \ $(GALLIUM_COMMON_LIB_DEPS) diff --git a/src/gallium/targets/d3dadapter9/meson.build b/src/gallium/targets/d3dadapter9/meson.build index 2cdc0e0e1f4..bd05b4f9692 100644 --- a/src/gallium/targets/d3dadapter9/meson.build +++ b/src/gallium/targets/d3dadapter9/meson.build @@ -25,11 +25,7 @@ nine_version = ['1', '0', '0'] -gallium_nine_c_args = [ - '-DGALLIUM_DDEBUG', - '-DGALLIUM_RBUG', - '-DGALLIUME_TRACE', -] +gallium_nine_c_args = [] gallium_nine_ld_args = [] gallium_nine_link_depends = [] @@ -52,8 +48,8 @@ libgallium_nine = shared_library( link_args : [ld_args_gc_sections, gallium_nine_ld_args], link_depends : gallium_nine_link_depends, link_with : [ - libgalliumvl_stub, libgallium, libnine_st, libmesa_util, libddebug, - librbug, libtrace, libpipe_loader_static, libws_null, libwsw, libswdri, + libgalliumvl_stub, libgallium, libnine_st, libmesa_util, + libpipe_loader_static, libws_null, libwsw, libswdri, libswkmsdri, ], dependencies : [ diff --git a/src/gallium/targets/dri/Makefile.am b/src/gallium/targets/dri/Makefile.am index c6a4c215905..a0778b64e58 100644 --- a/src/gallium/targets/dri/Makefile.am +++ b/src/gallium/targets/dri/Makefile.am @@ -9,11 +9,7 @@ AM_CFLAGS = \ $(GALLIUM_TARGET_CFLAGS) AM_CPPFLAGS = \ - $(DEFINES) \ - -DGALLIUM_DDEBUG \ - -DGALLIUM_NOOP \ - -DGALLIUM_RBUG \ - -DGALLIUM_TRACE + $(DEFINES) dridir = $(DRI_DRIVER_INSTALL_DIR) dri_LTLIBRARIES = gallium_dri.la @@ -47,10 +43,6 @@ gallium_dri_la_LIBADD = \ $(top_builddir)/src/gallium/state_trackers/dri/libdri.la \ $(top_builddir)/src/gallium/auxiliary/libgalliumvl.la \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ - $(top_builddir)/src/gallium/drivers/ddebug/libddebug.la \ - $(top_builddir)/src/gallium/drivers/noop/libnoop.la \ - $(top_builddir)/src/gallium/drivers/rbug/librbug.la \ - $(top_builddir)/src/gallium/drivers/trace/libtrace.la \ $(top_builddir)/src/mapi/shared-glapi/libglapi.la \ $(LIBDRM_LIBS) \ $(SELINUX_LIBS) \ diff --git a/src/gallium/targets/dri/SConscript b/src/gallium/targets/dri/SConscript index ff6ce3bf4e0..69cce3e95fa 100644 --- a/src/gallium/targets/dri/SConscript +++ b/src/gallium/targets/dri/SConscript @@ -14,13 +14,6 @@ env.Append(CPPPATH = [ '#/src/gallium/state_trackers/dri', ]) -if env['build'] == 'release': - env.Append(CPPDEFINES = ['GALLIUM_RBUG']) - env.Prepend(LIBS = [rbug]) -else: - env.Append(CPPDEFINES = ['GALLIUM_TRACE', 'GALLIUM_RBUG']) - env.Prepend(LIBS = [trace, rbug]) - if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') env.Prepend(LIBS = [llvmpipe]) diff --git a/src/gallium/targets/dri/meson.build b/src/gallium/targets/dri/meson.build index 34402975386..bdbd45839ad 100644 --- a/src/gallium/targets/dri/meson.build +++ b/src/gallium/targets/dri/meson.build @@ -23,12 +23,7 @@ # Static targets are always enabled in autotools (unless you modify # configure.ac) -gallium_dri_c_args = [ - '-DGALLIUM_DDEBUG', - '-DGALLIUM_NOOP', - '-DGALLIUM_RBUG', - '-DGALLIUME_TRACE', -] +gallium_dri_c_args = [] gallium_dri_ld_args = [] gallium_dri_link_depends = [] gallium_dri_drivers = [] @@ -55,8 +50,8 @@ libgallium_dri = shared_library( link_depends : gallium_dri_link_depends, link_with : [ libmesa_gallium, libdricommon, libmegadriver_stub, libdri, libgalliumvl, - libgallium, libddebug, libnoop, librbug, libtrace, libglapi, - libpipe_loader_static, libws_null, libwsw, libswdri, libswkmsdri, + libgallium, libglapi, libpipe_loader_static, libws_null, libwsw, libswdri, + libswkmsdri, ], dependencies : [ dep_selinux, dep_expat, dep_libdrm, dep_llvm, dep_thread, diff --git a/src/gallium/targets/graw-gdi/SConscript b/src/gallium/targets/graw-gdi/SConscript index 67d437374fb..e59127cc25e 100644 --- a/src/gallium/targets/graw-gdi/SConscript +++ b/src/gallium/targets/graw-gdi/SConscript @@ -23,8 +23,8 @@ sources = [ ] if True: - env.Append(CPPDEFINES = ['GALLIUM_TRACE', 'GALLIUM_RBUG', 'GALLIUM_SOFTPIPE']) - env.Prepend(LIBS = [trace, rbug, softpipe]) + env.Append(CPPDEFINES = ['GALLIUM_SOFTPIPE']) + env.Prepend(LIBS = [softpipe]) if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') diff --git a/src/gallium/targets/graw-xlib/SConscript b/src/gallium/targets/graw-xlib/SConscript index bf9cf72c6e1..3c6a856e30e 100644 --- a/src/gallium/targets/graw-xlib/SConscript +++ b/src/gallium/targets/graw-xlib/SConscript @@ -20,16 +20,14 @@ env.Append(CPPPATH = [ '#src/gallium/winsys', ]) -env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE']) - sources = [ 'graw_xlib.c', graw_util ] if True: - env.Append(CPPDEFINES = ['GALLIUM_TRACE', 'GALLIUM_RBUG', 'GALLIUM_SOFTPIPE']) - env.Prepend(LIBS = [trace, rbug, softpipe]) + env.Append(CPPDEFINES = ['GALLIUM_SOFTPIPE']) + env.Prepend(LIBS = [softpipe]) if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') diff --git a/src/gallium/targets/haiku-softpipe/SConscript b/src/gallium/targets/haiku-softpipe/SConscript index 89792fba132..ff5adc13125 100644 --- a/src/gallium/targets/haiku-softpipe/SConscript +++ b/src/gallium/targets/haiku-softpipe/SConscript @@ -3,8 +3,6 @@ Import('*') env.Prepend(LIBS = [ ws_haiku, st_haiku, - trace, - rbug, mesautil, compiler, mesa, @@ -17,8 +15,6 @@ env.Prepend(LIBS = [ if True: env.Append(CPPDEFINES = [ 'GALLIUM_SOFTPIPE', - 'GALLIUM_RBUG', - 'GALLIUM_TRACE', ]) env.Prepend(LIBS = [softpipe]) diff --git a/src/gallium/targets/haiku-softpipe/meson.build b/src/gallium/targets/haiku-softpipe/meson.build index 84bcea4bbf2..619706d818d 100644 --- a/src/gallium/targets/haiku-softpipe/meson.build +++ b/src/gallium/targets/haiku-softpipe/meson.build @@ -30,7 +30,7 @@ libswpipe = shared_library( cpp_args : [cpp_vis_args], link_args : [ld_args_bsymbolic, ld_args_gc_sections], link_with : [ - libglapi, libswhgl, libsthgl, libtrace, librbug, libmesa_util, libcompiler, + libglapi, libswhgl, libsthgl, libmesa_util, libcompiler, libmesa_gallium, libglsl, libnir, libgallium, libgl ], dependencies : [ diff --git a/src/gallium/targets/libgl-gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript index b5ba0fabcd0..a8bdc3e5869 100644 --- a/src/gallium/targets/libgl-gdi/SConscript +++ b/src/gallium/targets/libgl-gdi/SConscript @@ -45,8 +45,6 @@ if env['gcc'] and env['machine'] != 'x86_64': else: sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] -drivers += [trace, rbug] - env['no_import_lib'] = 1 # when GLES is enabled, gl* and _glapi_* belong to bridge_glapi and diff --git a/src/gallium/targets/libgl-xlib/Makefile.am b/src/gallium/targets/libgl-xlib/Makefile.am index 1c622946a90..56d548e7c15 100644 --- a/src/gallium/targets/libgl-xlib/Makefile.am +++ b/src/gallium/targets/libgl-xlib/Makefile.am @@ -35,9 +35,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/gallium/state_trackers/glx/xlib \ -I$(top_srcdir)/src/gallium/auxiliary \ -I$(top_srcdir)/src/gallium/winsys \ - -DGALLIUM_SOFTPIPE \ - -DGALLIUM_RBUG \ - -DGALLIUM_TRACE + -DGALLIUM_SOFTPIPE AM_CFLAGS = $(X11_INCLUDES) @@ -61,8 +59,6 @@ lib@GL_LIB@_la_LIBADD = \ $(top_builddir)/src/gallium/state_trackers/glx/xlib/libxlib.la \ $(top_builddir)/src/gallium/winsys/sw/xlib/libws_xlib.la \ $(top_builddir)/src/gallium/drivers/softpipe/libsoftpipe.la \ - $(top_builddir)/src/gallium/drivers/trace/libtrace.la \ - $(top_builddir)/src/gallium/drivers/rbug/librbug.la \ $(top_builddir)/src/mapi/glapi/libglapi.la \ $(top_builddir)/src/mesa/libmesagallium.la \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript index b94ef350b16..fb7a0ce50e3 100644 --- a/src/gallium/targets/libgl-xlib/SConscript +++ b/src/gallium/targets/libgl-xlib/SConscript @@ -42,8 +42,8 @@ sources = [ ] if True: - env.Append(CPPDEFINES = ['GALLIUM_TRACE', 'GALLIUM_RBUG', 'GALLIUM_SOFTPIPE']) - env.Prepend(LIBS = [trace, rbug, softpipe]) + env.Append(CPPDEFINES = ['GALLIUM_SOFTPIPE']) + env.Prepend(LIBS = [softpipe]) if env['llvm']: env.Append(CPPDEFINES = ['GALLIUM_LLVMPIPE']) diff --git a/src/gallium/targets/libgl-xlib/meson.build b/src/gallium/targets/libgl-xlib/meson.build index 6884c826203..3d197ba7193 100644 --- a/src/gallium/targets/libgl-xlib/meson.build +++ b/src/gallium/targets/libgl-xlib/meson.build @@ -24,8 +24,6 @@ gallium_xlib_c_args = [ '-DGALLIUM_SOFTPIPE', - '-DGALLIUM_RBUG', - '-DGALLIUME_TRACE', ] gallium_xlib_ld_args = [] gallium_xlib_link_with = [] @@ -50,7 +48,7 @@ libgl = shared_library( link_args : [ld_args_bsymbolic, ld_args_gc_sections, gallium_xlib_ld_args], link_depends : gallium_xlib_link_depends, link_with : [ - libxlib, libws_xlib, libtrace, librbug, libglapi_static, + libxlib, libws_xlib, libglapi_static, libgallium, libmesa_util, libmesa_gallium, gallium_xlib_link_with, ], dependencies : [dep_thread, dep_clock, dep_unwind, driver_swrast, driver_swr], diff --git a/src/gallium/targets/osmesa/Makefile.am b/src/gallium/targets/osmesa/Makefile.am index f8bee5ef673..dc4d49e1072 100644 --- a/src/gallium/targets/osmesa/Makefile.am +++ b/src/gallium/targets/osmesa/Makefile.am @@ -33,8 +33,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/gallium/drivers \ -I$(top_srcdir)/src/gallium/winsys \ -I$(top_srcdir)/src/gallium/auxiliary \ - -DGALLIUM_SOFTPIPE \ - -DGALLIUM_TRACE + -DGALLIUM_SOFTPIPE lib_LTLIBRARIES = lib@OSMESA_LIB@.la @@ -60,7 +59,6 @@ lib@OSMESA_LIB@_la_LIBADD = \ $(top_builddir)/src/mesa/libmesagallium.la \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ $(top_builddir)/src/gallium/winsys/sw/null/libws_null.la \ - $(top_builddir)/src/gallium/drivers/trace/libtrace.la \ $(top_builddir)/src/gallium/drivers/softpipe/libsoftpipe.la \ $(top_builddir)/src/gallium/state_trackers/osmesa/libosmesa.la \ $(top_builddir)/src/mapi/glapi/libglapi.la \ diff --git a/src/gallium/targets/osmesa/SConscript b/src/gallium/targets/osmesa/SConscript index ccf7d5170c4..f49f1fe538e 100644 --- a/src/gallium/targets/osmesa/SConscript +++ b/src/gallium/targets/osmesa/SConscript @@ -15,7 +15,6 @@ env.Prepend(LIBS = [ compiler, mesa, gallium, - trace, glsl, nir, spirv, @@ -23,7 +22,7 @@ env.Prepend(LIBS = [ softpipe ]) -env.Append(CPPDEFINES = ['GALLIUM_TRACE', 'GALLIUM_SOFTPIPE']) +env.Append(CPPDEFINES = ['GALLIUM_SOFTPIPE']) sources = ['target.c'] diff --git a/src/gallium/targets/osmesa/meson.build b/src/gallium/targets/osmesa/meson.build index e51c54f8bc4..b4ae8f4b6ec 100644 --- a/src/gallium/targets/osmesa/meson.build +++ b/src/gallium/targets/osmesa/meson.build @@ -35,7 +35,7 @@ endif libosmesa = shared_library( osmesa_lib_name, 'target.c', - c_args : [c_vis_args, '-DGALLIUM_TRACE'], + c_args : [c_vis_args], cpp_args : cpp_vis_args, link_args : [ld_args_gc_sections, osmesa_link_args], include_directories : [ @@ -45,8 +45,7 @@ libosmesa = shared_library( link_depends : osmesa_link_deps, link_whole : [libosmesa_st], link_with : [ - libmesa_gallium, libgallium, libglapi_static, libws_null, libtrace, - osmesa_link_with, + libmesa_gallium, libgallium, libglapi_static, libws_null, osmesa_link_with, ], dependencies : [ dep_selinux, dep_thread, dep_clock, dep_unwind, diff --git a/src/gallium/targets/pipe-loader/Makefile.am b/src/gallium/targets/pipe-loader/Makefile.am index bddc4e8b584..fa16e8535ff 100644 --- a/src/gallium/targets/pipe-loader/Makefile.am +++ b/src/gallium/targets/pipe-loader/Makefile.am @@ -31,9 +31,7 @@ AM_CPPFLAGS = \ -I$(top_builddir)/src/util \ $(GALLIUM_PIPE_LOADER_DEFINES) \ $(LIBDRM_CFLAGS) \ - $(VISIBILITY_CFLAGS) \ - -DGALLIUM_RBUG \ - -DGALLIUM_TRACE + $(VISIBILITY_CFLAGS) pipedir = $(libdir)/gallium-pipe pipe_LTLIBRARIES = @@ -57,8 +55,6 @@ PIPE_LIBS += \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ $(top_builddir)/src/compiler/nir/libnir.la \ $(top_builddir)/src/util/libmesautil.la \ - $(top_builddir)/src/gallium/drivers/rbug/librbug.la \ - $(top_builddir)/src/gallium/drivers/trace/libtrace.la \ $(GALLIUM_COMMON_LIB_DEPS) AM_LDFLAGS = \ diff --git a/src/gallium/targets/pipe-loader/meson.build b/src/gallium/targets/pipe-loader/meson.build index 7466d98f2d4..5a44102a69d 100644 --- a/src/gallium/targets/pipe-loader/meson.build +++ b/src/gallium/targets/pipe-loader/meson.build @@ -20,8 +20,8 @@ pipe_loader_link_args = [ld_args_gc_sections] pipe_loader_link_deps = [] -pipe_loader_link_with = [libgallium, libnir, libmesa_util, librbug, libtrace] -pipe_loader_comp_args = ['-DGALLIUM_RBUG', '-DGALLIUM_TRACE'] +pipe_loader_link_with = [libgallium, libnir, libmesa_util] +pipe_loader_comp_args = [] pipe_loader_incs = [ inc_include, inc_src, inc_util, inc_gallium, inc_gallium_drivers, inc_gallium_winsys, inc_gallium_aux, diff --git a/src/gallium/tests/unit/Makefile.am b/src/gallium/tests/unit/Makefile.am index c9bede75bed..9f1d3b98cde 100644 --- a/src/gallium/tests/unit/Makefile.am +++ b/src/gallium/tests/unit/Makefile.am @@ -14,7 +14,6 @@ AM_CPPFLAGS = \ LDADD = \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \ $(top_builddir)/src/util/libmesautil.la \ - $(top_builddir)/src/gallium/drivers/trace/libtrace.la \ $(top_builddir)/src/gallium/winsys/sw/null/libws_null.la \ $(top_builddir)/src/gallium/drivers/softpipe/libsoftpipe.la \ $(GALLIUM_COMMON_LIB_DEPS)