which also simplifies the build scripts.
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
## 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
# 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',
])
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 \
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 \
--- /dev/null
+/**************************************************************************
+ *
+ * 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;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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 <inttypes.h>
+
+
+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);
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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_ */
--- /dev/null
+/**************************************************************************
+ *
+ * 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_ */
--- /dev/null
+/**************************************************************************
+ *
+ * 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 <ctype.h>
+#include <stdio.h>
+
+
+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=\"[<timeout in ms>] [(always|apitrace <call#)] [flush] [transfers] [verbose]\"");
+ puts(" GALLIUM_DDEBUG_SKIP=[count]");
+ puts("");
+ puts("Dump context and driver information of draw calls into");
+ puts("$HOME/"DD_DIR"/. By default, watch for GPU hangs and only dump information");
+ puts("about draw calls related to the hang.");
+ puts("");
+ puts("<timeout in ms>");
+ 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 <call#>");
+ 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;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#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 */
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <errno.h>
+#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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <errno.h>
+#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;
+}
--- /dev/null
+ 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 <jfonseca@vmware.com>
+Jakob Bornecrantz <jakob@vmware.com>
--- /dev/null
+/**************************************************************************
+ *
+ * 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;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+/**************************************************************************
+ *
+ * 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 <errno.h>
+
+#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);
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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);
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+/**************************************************************************
+ *
+ * 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;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+ 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 <jfonseca@vmware.com>
+Jakob Bornecrantz <jakob@vmware.com>
--- /dev/null
+/**************************************************************************
+ *
+ * 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);
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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_ */
--- /dev/null
+/**************************************************************************
+ *
+ * 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 <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#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("</");
+ trace_dump_writes(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("</trace>\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("<?xml version='1.0' encoding='UTF-8'?>\n");
+ trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n");
+ trace_dump_writes("<trace version='0.1'>\n");
+
+ /* Many applications don't exit cleanly, others may create and destroy a
+ * screen multiple times, so we only write </trace> 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("<call no=\'");
+ trace_dump_writef("%lu", call_no);
+ trace_dump_writes("\' class=\'");
+ trace_dump_escape(klass);
+ trace_dump_writes("\' method=\'");
+ trace_dump_escape(method);
+ 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("<bool>%c</bool>", value ? '1' : '0');
+}
+
+void trace_dump_int(long long int value)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writef("<int>%lli</int>", value);
+}
+
+void trace_dump_uint(long long unsigned value)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writef("<uint>%llu</uint>", value);
+}
+
+void trace_dump_float(double value)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writef("<float>%g</float>", 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("<bytes>");
+ 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("</bytes>");
+}
+
+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("<string>");
+ trace_dump_escape(str);
+ trace_dump_writes("</string>");
+}
+
+void trace_dump_enum(const char *value)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("<enum>");
+ trace_dump_escape(value);
+ trace_dump_writes("</enum>");
+}
+
+void trace_dump_array_begin(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("<array>");
+}
+
+void trace_dump_array_end(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("</array>");
+}
+
+void trace_dump_elem_begin(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("<elem>");
+}
+
+void trace_dump_elem_end(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("</elem>");
+}
+
+void trace_dump_struct_begin(const char *name)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writef("<struct name='%s'>", name);
+}
+
+void trace_dump_struct_end(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("</struct>");
+}
+
+void trace_dump_member_begin(const char *name)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writef("<member name='%s'>", name);
+}
+
+void trace_dump_member_end(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("</member>");
+}
+
+void trace_dump_null(void)
+{
+ if (!dumping)
+ return;
+
+ trace_dump_writes("<null/>");
+}
+
+void trace_dump_ptr(const void *value)
+{
+ if (!dumping)
+ return;
+
+ if(value)
+ trace_dump_writef("<ptr>0x%08lx</ptr>", (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();
+ }
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+/**************************************************************************
+ *
+ * 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_ */
--- /dev/null
+/**************************************************************************
+ *
+ * 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();
+}
+
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+/**************************************************************************
+ *
+ * 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 */
--- /dev/null
+/**************************************************************************
+ *
+ * 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;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * 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_ */
--- /dev/null
+/**************************************************************************
+ *
+ * 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);
+}
+
--- /dev/null
+/**************************************************************************
+ *
+ * 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_ */
--- /dev/null
+<?xml version="1.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.
+
+!-->
+
+<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="html" />
+
+ <xsl:strip-space elements="*" />
+
+ <xsl:template match="/trace">
+ <html>
+ <head>
+ <title>Gallium Trace</title>
+ </head>
+ <style>
+ body {
+ font-family: verdana, sans-serif;
+ font-size: 11px;
+ font-weight: normal;
+ text-align : left;
+ }
+
+ .fun {
+ font-weight: bold;
+ }
+
+ .var {
+ font-style: italic;
+ }
+
+ .typ {
+ display: none;
+ }
+
+ .lit {
+ color: #0000ff;
+ }
+
+ .ptr {
+ color: #008000;
+ }
+ </style>
+ <body>
+ <ol class="calls">
+ <xsl:apply-templates/>
+ </ol>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="call">
+ <li>
+ <xsl:attribute name="value">
+ <xsl:apply-templates select="@no"/>
+ </xsl:attribute>
+ <span class="fun">
+ <xsl:value-of select="@class"/>
+ <xsl:text>::</xsl:text>
+ <xsl:value-of select="@method"/>
+ </span>
+ <xsl:text>(</xsl:text>
+ <xsl:apply-templates select="arg"/>
+ <xsl:text>)</xsl:text>
+ <xsl:apply-templates select="ret"/>
+ </li>
+ </xsl:template>
+
+ <xsl:template match="arg|member">
+ <xsl:apply-templates select="@name"/>
+ <xsl:text> = </xsl:text>
+ <xsl:apply-templates />
+ <xsl:if test="position() != last()">
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="ret">
+ <xsl:text> = </xsl:text>
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="bool|int|uint|float|enum">
+ <span class="lit">
+ <xsl:value-of select="text()"/>
+ </span>
+ </xsl:template>
+
+ <xsl:template match="bytes">
+ <span class="lit">
+ <xsl:text>...</xsl:text>
+ </span>
+ </xsl:template>
+
+ <xsl:template match="string">
+ <span class="lit">
+ <xsl:text>"</xsl:text>
+ <xsl:call-template name="break">
+ <xsl:with-param name="text" select="text()"/>
+ </xsl:call-template>
+ <xsl:text>"</xsl:text>
+ </span>
+ </xsl:template>
+
+ <xsl:template match="array|struct">
+ <xsl:text>{</xsl:text>
+ <xsl:apply-templates />
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="elem">
+ <xsl:apply-templates />
+ <xsl:if test="position() != last()">
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="null">
+ <span class="ptr">
+ <xsl:text>NULL</xsl:text>
+ </span>
+ </xsl:template>
+
+ <xsl:template match="ptr">
+ <span class="ptr">
+ <xsl:value-of select="text()"/>
+ </span>
+ </xsl:template>
+
+ <xsl:template match="@name">
+ <span class="var">
+ <xsl:value-of select="."/>
+ </span>
+ </xsl:template>
+
+ <xsl:template name="break">
+ <xsl:param name="text" select="."/>
+ <xsl:choose>
+ <xsl:when test="contains($text, '
')">
+ <xsl:value-of select="substring-before($text, '
')"/>
+ <br/>
+ <xsl:call-template name="break">
+ <xsl:with-param name="text" select="substring-after($text, '
')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="replace">
+ <xsl:param name="text"/>
+ <xsl:param name="from"/>
+ <xsl:param name="to"/>
+ <xsl:choose>
+ <xsl:when test="contains($text,$from)">
+ <xsl:value-of select="concat(substring-before($text,$from),$to)"/>
+ <xsl:call-template name="replace">
+ <xsl:with-param name="text" select="substring-after($text,$from)"/>
+ <xsl:with-param name="from" select="$from"/>
+ <xsl:with-param name="to" select="$to"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$text"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:transform>
'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',
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:
/* 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
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);
+++ /dev/null
-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
+++ /dev/null
-C_SOURCES := \
- dd_context.c \
- dd_draw.c \
- dd_pipe.h \
- dd_public.h \
- dd_screen.c \
- dd_util.h
+++ /dev/null
-/**************************************************************************
- *
- * 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;
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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 <inttypes.h>
-
-
-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);
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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_ */
+++ /dev/null
-/**************************************************************************
- *
- * 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_ */
+++ /dev/null
-/**************************************************************************
- *
- * 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 <ctype.h>
-#include <stdio.h>
-
-
-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=\"[<timeout in ms>] [(always|apitrace <call#)] [flush] [transfers] [verbose]\"");
- puts(" GALLIUM_DDEBUG_SKIP=[count]");
- puts("");
- puts("Dump context and driver information of draw calls into");
- puts("$HOME/"DD_DIR"/. By default, watch for GPU hangs and only dump information");
- puts("about draw calls related to the hang.");
- puts("");
- puts("<timeout in ms>");
- 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 <call#>");
- 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;
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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 <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#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 */
+++ /dev/null
-# 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,
-)
+++ /dev/null
-################################################################################
-
-# 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
+++ /dev/null
-C_SOURCES := \
- noop_pipe.c \
- noop_public.h \
- noop_state.c
+++ /dev/null
-#######################################################################
-# SConscript for noop convenience library
-
-Import('*')
-
-env = env.Clone()
-
-noop = env.ConvenienceLibrary(
- target = 'noop',
- source = env.ParseSourceList('Makefile.sources', 'C_SOURCES')
- ) + extra
-
-Export('noop')
+++ /dev/null
-# 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,
-)
+++ /dev/null
-/*
- * 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 <stdio.h>
-#include <errno.h>
-#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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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 <stdio.h>
-#include <errno.h>
-#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;
-}
#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"
#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: */
+++ /dev/null
-# 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
+++ /dev/null
-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
+++ /dev/null
- 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 <jfonseca@vmware.com>
-Jakob Bornecrantz <jakob@vmware.com>
+++ /dev/null
-Import('*')
-
-env = env.Clone()
-
-rbug = env.ConvenienceLibrary(
- target = 'rbug',
- source = env.ParseSourceList('Makefile.sources', 'C_SOURCES')
- )
-
-env.Alias('rbug', rbug)
-
-Export('rbug')
+++ /dev/null
-# 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,
-)
+++ /dev/null
-/**************************************************************************
- *
- * 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;
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-/**************************************************************************
- *
- * 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 <errno.h>
-
-#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);
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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);
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-/**************************************************************************
- *
- * 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;
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
- 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 <jfonseca@vmware.com>
-Jakob Bornecrantz <jakob@vmware.com>
+++ /dev/null
-Import('*')
-
-env = env.Clone()
-
-env.MSVC2013Compat()
-
-trace = env.ConvenienceLibrary(
- target = 'trace',
- source = env.ParseSourceList('Makefile.sources', 'C_SOURCES')
- )
-
-env.Alias('trace', trace)
-
-Export('trace')
+++ /dev/null
-# 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,
-)
+++ /dev/null
-/**************************************************************************
- *
- * 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);
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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_ */
+++ /dev/null
-/**************************************************************************
- *
- * 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 <jfonseca@vmware.com>
- */
-
-#include "pipe/p_config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#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("</");
- trace_dump_writes(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("</trace>\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("<?xml version='1.0' encoding='UTF-8'?>\n");
- trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n");
- trace_dump_writes("<trace version='0.1'>\n");
-
- /* Many applications don't exit cleanly, others may create and destroy a
- * screen multiple times, so we only write </trace> 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("<call no=\'");
- trace_dump_writef("%lu", call_no);
- trace_dump_writes("\' class=\'");
- trace_dump_escape(klass);
- trace_dump_writes("\' method=\'");
- trace_dump_escape(method);
- 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("<bool>%c</bool>", value ? '1' : '0');
-}
-
-void trace_dump_int(long long int value)
-{
- if (!dumping)
- return;
-
- trace_dump_writef("<int>%lli</int>", value);
-}
-
-void trace_dump_uint(long long unsigned value)
-{
- if (!dumping)
- return;
-
- trace_dump_writef("<uint>%llu</uint>", value);
-}
-
-void trace_dump_float(double value)
-{
- if (!dumping)
- return;
-
- trace_dump_writef("<float>%g</float>", 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("<bytes>");
- 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("</bytes>");
-}
-
-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("<string>");
- trace_dump_escape(str);
- trace_dump_writes("</string>");
-}
-
-void trace_dump_enum(const char *value)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("<enum>");
- trace_dump_escape(value);
- trace_dump_writes("</enum>");
-}
-
-void trace_dump_array_begin(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("<array>");
-}
-
-void trace_dump_array_end(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("</array>");
-}
-
-void trace_dump_elem_begin(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("<elem>");
-}
-
-void trace_dump_elem_end(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("</elem>");
-}
-
-void trace_dump_struct_begin(const char *name)
-{
- if (!dumping)
- return;
-
- trace_dump_writef("<struct name='%s'>", name);
-}
-
-void trace_dump_struct_end(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("</struct>");
-}
-
-void trace_dump_member_begin(const char *name)
-{
- if (!dumping)
- return;
-
- trace_dump_writef("<member name='%s'>", name);
-}
-
-void trace_dump_member_end(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("</member>");
-}
-
-void trace_dump_null(void)
-{
- if (!dumping)
- return;
-
- trace_dump_writes("<null/>");
-}
-
-void trace_dump_ptr(const void *value)
-{
- if (!dumping)
- return;
-
- if(value)
- trace_dump_writef("<ptr>0x%08lx</ptr>", (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();
- }
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-/**************************************************************************
- *
- * 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_ */
+++ /dev/null
-/**************************************************************************
- *
- * 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();
-}
-
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-/**************************************************************************
- *
- * 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 */
+++ /dev/null
-/**************************************************************************
- *
- * 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;
-}
+++ /dev/null
-/**************************************************************************
- *
- * 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_ */
+++ /dev/null
-/**************************************************************************
- *
- * 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);
-}
-
+++ /dev/null
-/**************************************************************************
- *
- * 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_ */
+++ /dev/null
-<?xml version="1.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.
-
-!-->
-
-<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
- <xsl:output method="html" />
-
- <xsl:strip-space elements="*" />
-
- <xsl:template match="/trace">
- <html>
- <head>
- <title>Gallium Trace</title>
- </head>
- <style>
- body {
- font-family: verdana, sans-serif;
- font-size: 11px;
- font-weight: normal;
- text-align : left;
- }
-
- .fun {
- font-weight: bold;
- }
-
- .var {
- font-style: italic;
- }
-
- .typ {
- display: none;
- }
-
- .lit {
- color: #0000ff;
- }
-
- .ptr {
- color: #008000;
- }
- </style>
- <body>
- <ol class="calls">
- <xsl:apply-templates/>
- </ol>
- </body>
- </html>
- </xsl:template>
-
- <xsl:template match="call">
- <li>
- <xsl:attribute name="value">
- <xsl:apply-templates select="@no"/>
- </xsl:attribute>
- <span class="fun">
- <xsl:value-of select="@class"/>
- <xsl:text>::</xsl:text>
- <xsl:value-of select="@method"/>
- </span>
- <xsl:text>(</xsl:text>
- <xsl:apply-templates select="arg"/>
- <xsl:text>)</xsl:text>
- <xsl:apply-templates select="ret"/>
- </li>
- </xsl:template>
-
- <xsl:template match="arg|member">
- <xsl:apply-templates select="@name"/>
- <xsl:text> = </xsl:text>
- <xsl:apply-templates />
- <xsl:if test="position() != last()">
- <xsl:text>, </xsl:text>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ret">
- <xsl:text> = </xsl:text>
- <xsl:apply-templates />
- </xsl:template>
-
- <xsl:template match="bool|int|uint|float|enum">
- <span class="lit">
- <xsl:value-of select="text()"/>
- </span>
- </xsl:template>
-
- <xsl:template match="bytes">
- <span class="lit">
- <xsl:text>...</xsl:text>
- </span>
- </xsl:template>
-
- <xsl:template match="string">
- <span class="lit">
- <xsl:text>"</xsl:text>
- <xsl:call-template name="break">
- <xsl:with-param name="text" select="text()"/>
- </xsl:call-template>
- <xsl:text>"</xsl:text>
- </span>
- </xsl:template>
-
- <xsl:template match="array|struct">
- <xsl:text>{</xsl:text>
- <xsl:apply-templates />
- <xsl:text>}</xsl:text>
- </xsl:template>
-
- <xsl:template match="elem">
- <xsl:apply-templates />
- <xsl:if test="position() != last()">
- <xsl:text>, </xsl:text>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="null">
- <span class="ptr">
- <xsl:text>NULL</xsl:text>
- </span>
- </xsl:template>
-
- <xsl:template match="ptr">
- <span class="ptr">
- <xsl:value-of select="text()"/>
- </span>
- </xsl:template>
-
- <xsl:template match="@name">
- <span class="var">
- <xsl:value-of select="."/>
- </span>
- </xsl:template>
-
- <xsl:template name="break">
- <xsl:param name="text" select="."/>
- <xsl:choose>
- <xsl:when test="contains($text, '
')">
- <xsl:value-of select="substring-before($text, '
')"/>
- <br/>
- <xsl:call-template name="break">
- <xsl:with-param name="text" select="substring-after($text, '
')"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$text"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="replace">
- <xsl:param name="text"/>
- <xsl:param name="from"/>
- <xsl:param name="to"/>
- <xsl:choose>
- <xsl:when test="contains($text,$from)">
- <xsl:value-of select="concat(substring-before($text,$from),$to)"/>
- <xsl:call-template name="replace">
- <xsl:with-param name="text" select="substring-after($text,$from)"/>
- <xsl:with-param name="from" select="$from"/>
- <xsl:with-param name="to" select="$to"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$text"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
-</xsl:transform>
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')
-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
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,
],
$(VISIBILITY_CFLAGS)
AM_CPPFLAGS = \
- $(DEFINES) \
- -DGALLIUM_DDEBUG \
- -DGALLIUM_RBUG \
- -DGALLIUM_TRACE
+ $(DEFINES)
ninedir = $(D3D_DRIVER_INSTALL_DIR)
nine_LTLIBRARIES = d3dadapter9.la
$(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)
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 = []
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 : [
$(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
$(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) \
'#/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])
# 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 = []
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,
]
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')
'#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')
env.Prepend(LIBS = [
ws_haiku,
st_haiku,
- trace,
- rbug,
mesautil,
compiler,
mesa,
if True:
env.Append(CPPDEFINES = [
'GALLIUM_SOFTPIPE',
- 'GALLIUM_RBUG',
- 'GALLIUM_TRACE',
])
env.Prepend(LIBS = [softpipe])
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 : [
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
-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)
$(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 \
]
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'])
gallium_xlib_c_args = [
'-DGALLIUM_SOFTPIPE',
- '-DGALLIUM_RBUG',
- '-DGALLIUME_TRACE',
]
gallium_xlib_ld_args = []
gallium_xlib_link_with = []
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],
-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
$(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 \
compiler,
mesa,
gallium,
- trace,
glsl,
nir,
spirv,
softpipe
])
-env.Append(CPPDEFINES = ['GALLIUM_TRACE', 'GALLIUM_SOFTPIPE'])
+env.Append(CPPDEFINES = ['GALLIUM_SOFTPIPE'])
sources = ['target.c']
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 : [
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,
-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 =
$(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 = \
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,
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)