From 21b668e11e3e0e84d476fea9b8d3198a610d71c8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 12 May 2010 14:38:20 +0100 Subject: [PATCH] rbug: Fix shaders --- src/gallium/drivers/rbug/rbug_context.c | 100 +++++++++++++++++++----- src/gallium/drivers/rbug/rbug_context.h | 1 + src/gallium/drivers/rbug/rbug_core.c | 54 ++++++++----- src/gallium/drivers/rbug/rbug_objects.c | 52 ++++++++++++ src/gallium/drivers/rbug/rbug_objects.h | 17 ++++ 5 files changed, 188 insertions(+), 36 deletions(-) diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index 0bc9b32ab90..158904d2344 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -29,6 +29,7 @@ #include "pipe/p_context.h" #include "util/u_memory.h" #include "util/u_inlines.h" +#include "util/u_simple_list.h" #include "rbug_context.h" #include "rbug_objects.h" @@ -318,70 +319,120 @@ rbug_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, static void * rbug_create_fs_state(struct pipe_context *_pipe, - const struct pipe_shader_state *fs) + const struct pipe_shader_state *state) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *result; - return pipe->create_fs_state(pipe, - fs); + result = pipe->create_fs_state(pipe, state); + 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) + void *_fs) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *fs; + fs = rbug_shader_unwrap(_fs); + rb_pipe->curr.fs = rbug_shader(_fs); pipe->bind_fs_state(pipe, fs); } static void rbug_delete_fs_state(struct pipe_context *_pipe, - void *fs) + void *_fs) { struct rbug_context *rb_pipe = rbug_context(_pipe); - struct pipe_context *pipe = rb_pipe->pipe; + struct rbug_shader *rb_shader = rbug_shader(_fs); - pipe->delete_fs_state(pipe, - fs); + rbug_shader_destroy(rb_pipe, rb_shader); } static void * rbug_create_vs_state(struct pipe_context *_pipe, - const struct pipe_shader_state *vs) + const struct pipe_shader_state *state) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *result; + + result = pipe->create_vs_state(pipe, state); + if (!result) + return NULL; - return pipe->create_vs_state(pipe, - vs); + return rbug_shader_create(rb_pipe, state, result, RBUG_SHADER_VERTEX); } static void rbug_bind_vs_state(struct pipe_context *_pipe, - void *vs) + void *_vs) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *vs; + vs = rbug_shader_unwrap(_vs); + rb_pipe->curr.vs = rbug_shader(_vs); pipe->bind_vs_state(pipe, vs); } static void rbug_delete_vs_state(struct pipe_context *_pipe, - void *vs) + void *_vs) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_shader *rb_shader = rbug_shader(_vs); + + rbug_shader_destroy(rb_pipe, rb_shader); +} + +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; + + result = pipe->create_gs_state(pipe, state); + 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; - pipe->delete_vs_state(pipe, - vs); + gs = rbug_shader_unwrap(_gs); + rb_pipe->curr.gs = rbug_shader(_gs); + pipe->bind_gs_state(pipe, + gs); } +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); + + rbug_shader_destroy(rb_pipe, rb_shader); +} static void * rbug_create_vertex_elements_state(struct pipe_context *_pipe, @@ -834,12 +885,20 @@ struct pipe_context * rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) { struct rbug_context *rb_pipe; - (void)rbug_screen(_screen); + struct rbug_screen *rb_screen = rbug_screen(_screen); + + if (!rb_screen) + return NULL; rb_pipe = CALLOC_STRUCT(rbug_context); - if (!rb_pipe) { + if (!rb_pipe) return NULL; - } + + pipe_mutex_init(rb_pipe->draw_mutex); + pipe_condvar_init(rb_pipe->draw_cond); + pipe_mutex_init(rb_pipe->call_mutex); + pipe_mutex_init(rb_pipe->list_mutex); + make_empty_list(&rb_pipe->shaders); rb_pipe->base.winsys = NULL; rb_pipe->base.screen = _screen; @@ -874,6 +933,9 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) 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; @@ -904,5 +966,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) rb_pipe->pipe = pipe; + rbug_screen_add_to_list(rb_screen, contexts, rb_pipe); + return &rb_pipe->base; } diff --git a/src/gallium/drivers/rbug/rbug_context.h b/src/gallium/drivers/rbug/rbug_context.h index 08ff050a9a3..ccba3c19254 100644 --- a/src/gallium/drivers/rbug/rbug_context.h +++ b/src/gallium/drivers/rbug/rbug_context.h @@ -48,6 +48,7 @@ struct rbug_context { struct { struct rbug_shader *fs; struct rbug_shader *vs; + struct rbug_shader *gs; struct rbug_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; unsigned num_sampler_views; diff --git a/src/gallium/drivers/rbug/rbug_core.c b/src/gallium/drivers/rbug/rbug_core.c index c0b1d97f460..13aa95a59b7 100644 --- a/src/gallium/drivers/rbug/rbug_core.c +++ b/src/gallium/drivers/rbug/rbug_core.c @@ -97,53 +97,71 @@ rbug_get_shader_locked(struct rbug_context *rb_context, rbug_shader_t shdr) static void * rbug_shader_create_locked(struct pipe_context *pipe, - struct rbug_shader *tr_shdr, + struct rbug_shader *rb_shader, struct tgsi_token *tokens) { void *state = NULL; struct pipe_shader_state pss = { 0 }; pss.tokens = tokens; -#if 0 - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: state = pipe->create_fs_state(pipe, &pss); - } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { + break; + case RBUG_SHADER_VERTEX: state = pipe->create_vs_state(pipe, &pss); - } else + break; + case RBUG_SHADER_GEOM: + state = pipe->create_gs_state(pipe, &pss); + break; + default: assert(0); -#endif + break; + } return state; } static void rbug_shader_bind_locked(struct pipe_context *pipe, - struct rbug_shader *tr_shdr, + struct rbug_shader *rb_shader, void *state) { -#if 0 - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: pipe->bind_fs_state(pipe, state); - } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { + break; + case RBUG_SHADER_VERTEX: pipe->bind_vs_state(pipe, state); - } else + break; + case RBUG_SHADER_GEOM: + pipe->bind_gs_state(pipe, state); + break; + default: assert(0); -#endif + break; + } } static void rbug_shader_delete_locked(struct pipe_context *pipe, - struct rbug_shader *tr_shdr, + struct rbug_shader *rb_shader, void *state) { -#if 0 - if (tr_shdr->type == TRACE_SHADER_FRAGMENT) { + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: pipe->delete_fs_state(pipe, state); - } else if (tr_shdr->type == TRACE_SHADER_VERTEX) { + break; + case RBUG_SHADER_VERTEX: pipe->delete_vs_state(pipe, state); - } else + break; + case RBUG_SHADER_GEOM: + pipe->delete_gs_state(pipe, state); + break; + default: assert(0); -#endif + break; + } } /************************************************ diff --git a/src/gallium/drivers/rbug/rbug_objects.c b/src/gallium/drivers/rbug/rbug_objects.c index 4f9b23263b9..d963baab417 100644 --- a/src/gallium/drivers/rbug/rbug_objects.c +++ b/src/gallium/drivers/rbug/rbug_objects.c @@ -29,6 +29,8 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" +#include "tgsi/tgsi_parse.h" + #include "rbug_screen.h" #include "rbug_objects.h" #include "rbug_context.h" @@ -193,3 +195,53 @@ rbug_transfer_destroy(struct rbug_context *rb_context, FREE(rb_transfer); } +void * +rbug_shader_create(struct rbug_context *rb_context, + const struct pipe_shader_state *state, + void *result, enum rbug_shader_type type) +{ + struct rbug_shader *rb_shader = CALLOC_STRUCT(rbug_shader); + + rb_shader->type = type; + rb_shader->shader = result; + rb_shader->tokens = tgsi_dup_tokens(state->tokens); + + /* works on context as well since its just a macro */ + rbug_screen_add_to_list(rb_context, shaders, rb_shader); + + return rb_shader; +} + +void +rbug_shader_destroy(struct rbug_context *rb_context, + struct rbug_shader *rb_shader) +{ + struct pipe_context *pipe = rb_context->pipe; + + /* works on context as well since its just a macro */ + rbug_screen_remove_from_list(rb_context, shaders, rb_shader); + + switch(rb_shader->type) { + case RBUG_SHADER_FRAGMENT: + if (rb_shader->replaced_shader) + pipe->delete_fs_state(pipe, rb_shader->replaced_shader); + pipe->delete_fs_state(pipe, rb_shader->shader); + break; + case RBUG_SHADER_VERTEX: + if (rb_shader->replaced_shader) + pipe->delete_vs_state(pipe, rb_shader->replaced_shader); + pipe->delete_vs_state(pipe, rb_shader->shader); + break; + case RBUG_SHADER_GEOM: + if (rb_shader->replaced_shader) + pipe->delete_gs_state(pipe, rb_shader->replaced_shader); + pipe->delete_gs_state(pipe, rb_shader->shader); + break; + default: + assert(0); + } + + FREE(rb_shader->replaced_tokens); + FREE(rb_shader->tokens); + FREE(rb_shader); +} diff --git a/src/gallium/drivers/rbug/rbug_objects.h b/src/gallium/drivers/rbug/rbug_objects.h index 7f48c01b577..49c128d3d1a 100644 --- a/src/gallium/drivers/rbug/rbug_objects.h +++ b/src/gallium/drivers/rbug/rbug_objects.h @@ -47,6 +47,13 @@ struct rbug_resource }; +enum rbug_shader_type +{ + RBUG_SHADER_GEOM, + RBUG_SHADER_VERTEX, + RBUG_SHADER_FRAGMENT, +}; + struct rbug_shader { struct rbug_list list; @@ -56,6 +63,7 @@ struct rbug_shader void *replaced_shader; void *replaced_tokens; + enum rbug_shader_type type; boolean disabled; }; @@ -205,5 +213,14 @@ 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 */ -- 2.30.2