#include "dd_pipe.h"
#include "tgsi/tgsi_parse.h"
+#include "util/u_inlines.h"
#include "util/u_memory.h"
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)
return pipe->begin_query(pipe, dd_query_unwrap(query));
}
-static void
+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;
- pipe->end_query(pipe, dd_query_unwrap(query));
+ return pipe->end_query(pipe, dd_query_unwrap(query));
}
static boolean
return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, 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 pipe_context *pipe = dd_context(_pipe)->pipe;
+
+ pipe->get_query_result_resource(pipe, dd_query_unwrap(query), wait,
+ result_type, index, resource, offset);
+}
+
+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,
- uint mode)
+ 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);
- dctx->render_cond.query = dd_query(query);
- dctx->render_cond.condition = condition;
- dctx->render_cond.mode = mode;
+ dstate->render_cond.query = dd_query(query);
+ dstate->render_cond.condition = condition;
+ dstate->render_cond.mode = mode;
}
struct pipe_context *pipe = dctx->pipe; \
struct dd_state *hstate = state; \
\
- dctx->shortname = hstate; \
+ dctx->draw_state.shortname = hstate; \
pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
}
DD_CSO_DELETE(sampler)
static void
-dd_context_bind_sampler_states(struct pipe_context *_pipe, unsigned shader,
+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->sampler_states[shader][start], states,
+ memcpy(&dctx->draw_state.sampler_states[shader][start], states,
sizeof(void*) * count);
if (states) {
* shaders
*/
-#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; \
- hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \
- return hstate; \
- } \
- \
+#define DD_SHADER_NOCREATE(NAME, name) \
static void \
dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
{ \
struct pipe_context *pipe = dctx->pipe; \
struct dd_state *hstate = state; \
\
- dctx->shaders[PIPE_SHADER_##NAME] = hstate; \
+ dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \
pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
} \
\
struct dd_state *hstate = state; \
\
pipe->delete_##name##_state(pipe, hstate->cso); \
- tgsi_free_tokens(hstate->state.shader.tokens); \
+ 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
struct dd_context *dctx = dd_context(_pipe); \
struct pipe_context *pipe = dctx->pipe; \
\
- dctx->name = deref; \
+ dctx->draw_state.name = deref; \
pipe->set_##name(pipe, ref); \
}
static void
dd_context_set_constant_buffer(struct pipe_context *_pipe,
- uint shader, uint index,
- struct pipe_constant_buffer *constant_buffer)
+ 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->constant_buffers[shader][index], constant_buffer,
- sizeof(*constant_buffer));
+ safe_memcpy(&dctx->draw_state.constant_buffers[shader][index],
+ constant_buffer, sizeof(*constant_buffer));
pipe->set_constant_buffer(pipe, shader, index, constant_buffer);
}
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
- safe_memcpy(&dctx->scissors[start_slot], states,
+ safe_memcpy(&dctx->draw_state.scissors[start_slot], states,
sizeof(*states) * num_scissors);
pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
}
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
- safe_memcpy(&dctx->viewports[start_slot], states,
+ safe_memcpy(&dctx->draw_state.viewports[start_slot], states,
sizeof(*states) * num_viewports);
pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
}
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
- memcpy(dctx->tess_default_levels, default_outer_level, sizeof(float) * 4);
- memcpy(dctx->tess_default_levels+4, default_inner_level, sizeof(float) * 2);
+ 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);
}
*/
static void
-dd_context_set_sampler_views(struct pipe_context *_pipe, unsigned shader,
+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->sampler_views[shader][start], views,
+ 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, unsigned shader,
+dd_context_set_shader_images(struct pipe_context *_pipe,
+ enum pipe_shader_type shader,
unsigned start, unsigned num,
- struct pipe_image_view *views)
+ const struct pipe_image_view *views)
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
- safe_memcpy(&dctx->shader_images[shader][start], views,
+ 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,
- struct pipe_shader_buffer *buffers)
+ const struct pipe_shader_buffer *buffers)
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
- safe_memcpy(&dctx->shader_buffers[shader][start], buffers,
+ 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);
}
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
- safe_memcpy(&dctx->vertex_buffers[start], buffers,
+ 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_index_buffer(struct pipe_context *_pipe,
- const struct pipe_index_buffer *ib)
-{
- struct dd_context *dctx = dd_context(_pipe);
- struct pipe_context *pipe = dctx->pipe;
-
- safe_memcpy(&dctx->index_buffer, ib, sizeof(*ib));
- pipe->set_index_buffer(pipe, ib);
-}
-
static void
dd_context_set_stream_output_targets(struct pipe_context *_pipe,
unsigned num_targets,
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
+ struct dd_draw_state *dstate = &dctx->draw_state;
- dctx->num_so_targets = num_targets;
- safe_memcpy(dctx->so_targets, tgs, sizeof(*tgs) * num_targets);
- safe_memcpy(dctx->so_offsets, offsets, sizeof(*offsets) * num_targets);
+ 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);
}
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
+ if (dctx->thread) {
+ mtx_lock(&dctx->mutex);
+ dctx->kill_thread = 1;
+ mtx_unlock(&dctx->mutex);
+ thrd_join(dctx->thread, NULL);
+ mtx_destroy(&dctx->mutex);
+ assert(!dctx->records);
+ }
+
+ if (dctx->fence) {
+ pipe->transfer_unmap(pipe, dctx->fence_transfer);
+ pipe_resource_reference(&dctx->fence, NULL);
+ }
pipe->destroy(pipe);
FREE(dctx);
}
}
static void
-dd_context_transfer_inline_write(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)
+dd_context_buffer_subdata(struct pipe_context *_pipe,
+ struct pipe_resource *resource,
+ unsigned usage, unsigned offset,
+ unsigned size, const void *data)
+{
+ struct pipe_context *pipe = dd_context(_pipe)->pipe;
+
+ pipe->buffer_subdata(pipe, resource, usage, offset, size, data);
+}
+
+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 pipe_context *pipe = dd_context(_pipe)->pipe;
- pipe->transfer_inline_write(pipe, resource, level, usage, box, data,
- stride, layer_stride);
+ pipe->texture_subdata(pipe, resource, level, usage, box, data,
+ stride, layer_stride);
}
*/
static void
-dd_context_texture_barrier(struct pipe_context *_pipe)
+dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags)
{
struct pipe_context *pipe = dd_context(_pipe)->pipe;
- pipe->texture_barrier(pipe);
+ pipe->texture_barrier(pipe, flags);
}
static void
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,
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)
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)
{
return NULL;
dctx = CALLOC_STRUCT(dd_context);
- if (!dctx) {
- pipe->destroy(pipe);
- return NULL;
- }
+ 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(get_query_result_resource);
+ CTX_INIT(set_active_query_state);
CTX_INIT(create_blend_state);
CTX_INIT(bind_blend_state);
CTX_INIT(delete_blend_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_shader_buffers);
CTX_INIT(set_shader_images);
CTX_INIT(set_vertex_buffers);
- CTX_INIT(set_index_buffer);
CTX_INIT(create_stream_output_target);
CTX_INIT(stream_output_target_destroy);
CTX_INIT(set_stream_output_targets);
CTX_INIT(transfer_map);
CTX_INIT(transfer_flush_region);
CTX_INIT(transfer_unmap);
- CTX_INIT(transfer_inline_write);
+ CTX_INIT(buffer_subdata);
+ CTX_INIT(texture_subdata);
CTX_INIT(texture_barrier);
CTX_INIT(memory_barrier);
+ CTX_INIT(resource_commit);
/* create_video_codec */
/* create_video_buffer */
- /* create_compute_state */
- /* bind_compute_state */
- /* delete_compute_state */
/* 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);
- dctx->sample_mask = ~0;
+ dctx->draw_state.sample_mask = ~0;
+
+ if (dscreen->mode == DD_DETECT_HANGS_PIPELINED) {
+ dctx->fence = pipe_buffer_create(dscreen->screen, PIPE_BIND_CUSTOM,
+ PIPE_USAGE_STAGING, 4);
+ if (!dctx->fence)
+ goto fail;
+
+ dctx->mapped_fence = pipe_buffer_map(pipe, dctx->fence,
+ PIPE_TRANSFER_READ_WRITE |
+ PIPE_TRANSFER_PERSISTENT |
+ PIPE_TRANSFER_COHERENT,
+ &dctx->fence_transfer);
+ if (!dctx->mapped_fence)
+ goto fail;
+
+ *dctx->mapped_fence = 0;
+
+ (void) mtx_init(&dctx->mutex, mtx_plain);
+ dctx->thread = u_thread_create(dd_thread_pipelined_hang_detect, dctx);
+ if (!dctx->thread) {
+ mtx_destroy(&dctx->mutex);
+ goto fail;
+ }
+ }
+
return &dctx->base;
+
+fail:
+ if (dctx) {
+ if (dctx->mapped_fence)
+ pipe_transfer_unmap(pipe, dctx->fence_transfer);
+ pipe_resource_reference(&dctx->fence, NULL);
+ FREE(dctx);
+ }
+ pipe->destroy(pipe);
+ return NULL;
}