/**
* @file
- *
+ *
* Wrap the cso cache & hash mechanisms in a simplified
* pipe-driver-specific interface.
*
boolean has_geometry_shader;
boolean has_streamout;
- struct sampler_info fragment_samplers;
- struct sampler_info vertex_samplers;
+ struct sampler_info samplers[PIPE_SHADER_TYPES];
- uint nr_vertex_buffers;
- struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_buffer aux_vertex_buffer_current;
+ struct pipe_vertex_buffer aux_vertex_buffer_saved;
+ unsigned aux_vertex_buffer_index;
- uint nr_vertex_buffers_saved;
- struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS];
+ struct pipe_constant_buffer aux_constbuf_current[PIPE_SHADER_TYPES];
+ struct pipe_constant_buffer aux_constbuf_saved[PIPE_SHADER_TYPES];
unsigned nr_so_targets;
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
void *blend, *blend_saved;
void *depth_stencil, *depth_stencil_saved;
void *rasterizer, *rasterizer_saved;
- void *fragment_shader, *fragment_shader_saved, *geometry_shader;
- void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
+ void *fragment_shader, *fragment_shader_saved;
+ void *vertex_shader, *vertex_shader_saved;
+ void *geometry_shader, *geometry_shader_saved;
void *velements, *velements_saved;
+ struct pipe_query *render_condition, *render_condition_saved;
+ uint render_condition_mode, render_condition_mode_saved;
struct pipe_clip_state clip;
struct pipe_clip_state clip_saved;
struct pipe_framebuffer_state fb, fb_saved;
struct pipe_viewport_state vp, vp_saved;
struct pipe_blend_color blend_color;
- unsigned sample_mask;
+ unsigned sample_mask, sample_mask_saved;
struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
};
static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state)
{
- struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state;
+ struct cso_depth_stencil_alpha *cso =
+ (struct cso_depth_stencil_alpha *)state;
if (ctx->depth_stencil == cso->data)
return FALSE;
switch (type) {
case CSO_BLEND:
return delete_blend_state(ctx, state);
- break;
case CSO_SAMPLER:
return delete_sampler_state(ctx, state);
- break;
case CSO_DEPTH_STENCIL_ALPHA:
return delete_depth_stencil_state(ctx, state);
- break;
case CSO_RASTERIZER:
return delete_rasterizer_state(ctx, state);
- break;
case CSO_VELEMENTS:
return delete_vertex_elements(ctx, state);
- break;
default:
assert(0);
FREE(state);
return FALSE;
}
-static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
- int max_size, void *user_data)
+static INLINE void
+sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
+ int max_size, void *user_data)
{
struct cso_context *ctx = (struct cso_context *)user_data;
/* if we're approach the maximum size, remove fourth of the entries
}
}
+static void cso_init_vbuf(struct cso_context *cso)
+{
+ struct u_vbuf_caps caps;
+
+ u_vbuf_get_caps(cso->pipe->screen, &caps);
+
+ /* Install u_vbuf if there is anything unsupported. */
+ if (!caps.buffer_offset_unaligned ||
+ !caps.buffer_stride_unaligned ||
+ !caps.velem_src_offset_unaligned ||
+ !caps.format_fixed32 ||
+ !caps.format_float16 ||
+ !caps.format_float64 ||
+ !caps.format_norm32 ||
+ !caps.format_scaled32 ||
+ !caps.user_vertex_buffers) {
+ cso->vbuf = u_vbuf_create(cso->pipe, &caps,
+ cso->aux_vertex_buffer_index);
+ }
+}
struct cso_context *cso_create_context( struct pipe_context *pipe )
{
if (ctx == NULL)
goto out;
- assert(PIPE_MAX_SAMPLERS == PIPE_MAX_VERTEX_SAMPLERS);
-
ctx->cache = cso_cache_create();
if (ctx->cache == NULL)
goto out;
ctx);
ctx->pipe = pipe;
+ ctx->sample_mask_saved = ~0;
+
+ ctx->aux_vertex_buffer_index = 0; /* 0 for now */
+
+ cso_init_vbuf(ctx);
/* Enable for testing: */
if (0) cso_set_maximum_cache_size( ctx->cache, 4 );
return ctx;
out:
- cso_destroy_context( ctx );
+ cso_destroy_context( ctx );
return NULL;
}
-void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf)
-{
- ctx->vbuf = vbuf;
-}
-
/**
* Prior to context destruction, this function unbinds all state objects.
*/
void cso_release_all( struct cso_context *ctx )
{
- unsigned i;
- struct sampler_info *info;
+ unsigned i, shader;
if (ctx->pipe) {
ctx->pipe->bind_blend_state( ctx->pipe, NULL );
}
/* free fragment samplers, views */
- info = &ctx->fragment_samplers;
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_sampler_view_reference(&info->views[i], NULL);
- pipe_sampler_view_reference(&info->views_saved[i], NULL);
- }
-
- /* free vertex samplers, views */
- info = &ctx->vertex_samplers;
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_sampler_view_reference(&info->views[i], NULL);
- pipe_sampler_view_reference(&info->views_saved[i], NULL);
+ for (shader = 0; shader < Elements(ctx->samplers); shader++) {
+ struct sampler_info *info = &ctx->samplers[shader];
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ pipe_sampler_view_reference(&info->views[i], NULL);
+ pipe_sampler_view_reference(&info->views_saved[i], NULL);
+ }
}
util_unreference_framebuffer_state(&ctx->fb);
util_unreference_framebuffer_state(&ctx->fb_saved);
- util_copy_vertex_buffers(ctx->vertex_buffers,
- &ctx->nr_vertex_buffers,
- NULL, 0);
- util_copy_vertex_buffers(ctx->vertex_buffers_saved,
- &ctx->nr_vertex_buffers_saved,
- NULL, 0);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer, NULL);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, NULL);
+
+ for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+ pipe_resource_reference(&ctx->aux_constbuf_current[i].buffer, NULL);
+ pipe_resource_reference(&ctx->aux_constbuf_saved[i].buffer, NULL);
+ }
for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
pipe_so_target_reference(&ctx->so_targets[i], NULL);
void cso_destroy_context( struct cso_context *ctx )
{
if (ctx) {
+ if (ctx->vbuf)
+ u_vbuf_destroy(ctx->vbuf);
FREE( ctx );
}
}
struct cso_hash_iter iter;
void *handle;
- key_size = templ->independent_blend_enable ? sizeof(struct pipe_blend_state) :
- (char *)&(templ->rt[1]) - (char *)templ;
+ key_size = templ->independent_blend_enable ?
+ sizeof(struct pipe_blend_state) :
+ (char *)&(templ->rt[1]) - (char *)templ;
hash_key = cso_construct_key((void*)templ, key_size);
- iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND, (void*)templ, key_size);
+ iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND,
+ (void*)templ, key_size);
if (cso_hash_iter_is_null(iter)) {
struct cso_blend *cso = MALLOC(sizeof(struct cso_blend));
-enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
- const struct pipe_depth_stencil_alpha_state *templ)
+enum pipe_error
+cso_set_depth_stencil_alpha(struct cso_context *ctx,
+ const struct pipe_depth_stencil_alpha_state *templ)
{
unsigned key_size = sizeof(struct pipe_depth_stencil_alpha_state);
unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
- hash_key,
+ hash_key,
CSO_DEPTH_STENCIL_ALPHA,
(void*)templ, key_size);
void *handle;
if (cso_hash_iter_is_null(iter)) {
- struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha));
+ struct cso_depth_stencil_alpha *cso =
+ MALLOC(sizeof(struct cso_depth_stencil_alpha));
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
memcpy(&cso->state, templ, sizeof(*templ));
- cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state);
- cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state;
+ cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe,
+ &cso->state);
+ cso->delete_state =
+ (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state;
cso->context = ctx->pipe;
- iter = cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso);
+ iter = cso_insert_state(ctx->cache, hash_key,
+ CSO_DEPTH_STENCIL_ALPHA, cso);
if (cso_hash_iter_is_null(iter)) {
FREE(cso);
return PIPE_ERROR_OUT_OF_MEMORY;
handle = cso->data;
}
else {
- handle = ((struct cso_depth_stencil_alpha *)cso_hash_iter_data(iter))->data;
+ handle = ((struct cso_depth_stencil_alpha *)
+ cso_hash_iter_data(iter))->data;
}
if (ctx->depth_stencil != handle) {
{
if (ctx->depth_stencil != ctx->depth_stencil_saved) {
ctx->depth_stencil = ctx->depth_stencil_saved;
- ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->depth_stencil_saved);
+ ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe,
+ ctx->depth_stencil_saved);
}
ctx->depth_stencil_saved = NULL;
}
unsigned key_size = sizeof(struct pipe_rasterizer_state);
unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
- hash_key, CSO_RASTERIZER,
+ hash_key,
+ CSO_RASTERIZER,
(void*)templ, key_size);
void *handle = NULL;
memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state);
- cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state;
+ cso->delete_state =
+ (cso_state_callback)ctx->pipe->delete_rasterizer_state;
cso->context = ctx->pipe;
iter = cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso);
}
-
-enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx,
- void *handle )
+void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle )
{
if (ctx->fragment_shader != handle) {
ctx->fragment_shader = handle;
ctx->pipe->bind_fs_state(ctx->pipe, handle);
}
- return PIPE_OK;
}
void cso_delete_fragment_shader(struct cso_context *ctx, void *handle )
}
-enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx,
- void *handle )
+void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle)
{
if (ctx->vertex_shader != handle) {
ctx->vertex_shader = handle;
ctx->pipe->bind_vs_state(ctx->pipe, handle);
}
- return PIPE_OK;
}
void cso_delete_vertex_shader(struct cso_context *ctx, void *handle )
}
-enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
- const struct pipe_framebuffer_state *fb)
+void cso_set_framebuffer(struct cso_context *ctx,
+ const struct pipe_framebuffer_state *fb)
{
if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
util_copy_framebuffer_state(&ctx->fb, fb);
ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
}
- return PIPE_OK;
}
void cso_save_framebuffer(struct cso_context *ctx)
}
-enum pipe_error cso_set_viewport(struct cso_context *ctx,
- const struct pipe_viewport_state *vp)
+void cso_set_viewport(struct cso_context *ctx,
+ const struct pipe_viewport_state *vp)
{
if (memcmp(&ctx->vp, vp, sizeof(*vp))) {
ctx->vp = *vp;
ctx->pipe->set_viewport_state(ctx->pipe, vp);
}
- return PIPE_OK;
}
void cso_save_viewport(struct cso_context *ctx)
}
-enum pipe_error cso_set_blend_color(struct cso_context *ctx,
- const struct pipe_blend_color *bc)
+void cso_set_blend_color(struct cso_context *ctx,
+ const struct pipe_blend_color *bc)
{
if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) {
ctx->blend_color = *bc;
ctx->pipe->set_blend_color(ctx->pipe, bc);
}
- return PIPE_OK;
}
-enum pipe_error cso_set_sample_mask(struct cso_context *ctx,
- unsigned sample_mask)
+void cso_set_sample_mask(struct cso_context *ctx, unsigned sample_mask)
{
if (ctx->sample_mask != sample_mask) {
ctx->sample_mask = sample_mask;
ctx->pipe->set_sample_mask(ctx->pipe, sample_mask);
}
- return PIPE_OK;
}
-enum pipe_error cso_set_stencil_ref(struct cso_context *ctx,
- const struct pipe_stencil_ref *sr)
+void cso_save_sample_mask(struct cso_context *ctx)
+{
+ ctx->sample_mask_saved = ctx->sample_mask;
+}
+
+void cso_restore_sample_mask(struct cso_context *ctx)
+{
+ cso_set_sample_mask(ctx, ctx->sample_mask_saved);
+}
+
+void cso_set_stencil_ref(struct cso_context *ctx,
+ const struct pipe_stencil_ref *sr)
{
if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) {
ctx->stencil_ref = *sr;
ctx->pipe->set_stencil_ref(ctx->pipe, sr);
}
- return PIPE_OK;
}
void cso_save_stencil_ref(struct cso_context *ctx)
void cso_restore_stencil_ref(struct cso_context *ctx)
{
- if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved, sizeof(ctx->stencil_ref))) {
+ if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved,
+ sizeof(ctx->stencil_ref))) {
ctx->stencil_ref = ctx->stencil_ref_saved;
ctx->pipe->set_stencil_ref(ctx->pipe, &ctx->stencil_ref);
}
}
-enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
- void *handle)
+void cso_set_render_condition(struct cso_context *ctx,
+ struct pipe_query *query, uint mode)
+{
+ struct pipe_context *pipe = ctx->pipe;
+
+ if (ctx->render_condition != query || ctx->render_condition_mode != mode) {
+ pipe->render_condition(pipe, query, mode);
+ ctx->render_condition = query;
+ ctx->render_condition_mode = mode;
+ }
+}
+
+void cso_save_render_condition(struct cso_context *ctx)
+{
+ ctx->render_condition_saved = ctx->render_condition;
+ ctx->render_condition_mode_saved = ctx->render_condition_mode;
+}
+
+void cso_restore_render_condition(struct cso_context *ctx)
+{
+ cso_set_render_condition(ctx, ctx->render_condition_saved,
+ ctx->render_condition_mode_saved);
+}
+
+void cso_set_geometry_shader_handle(struct cso_context *ctx, void *handle)
{
assert(ctx->has_geometry_shader || !handle);
ctx->geometry_shader = handle;
ctx->pipe->bind_gs_state(ctx->pipe, handle);
}
- return PIPE_OK;
}
void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
}
}
-enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
- unsigned count,
- const struct pipe_vertex_element *states)
+enum pipe_error
+cso_set_vertex_elements(struct cso_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *states)
{
struct u_vbuf *vbuf = ctx->vbuf;
unsigned key_size, hash_key;
return PIPE_OK;
}
- /* need to include the count into the stored state data too.
- Otherwise first few count pipe_vertex_elements could be identical even if count
- is different, and there's no guarantee the hash would be different in that
- case neither */
+ /* Need to include the count into the stored state data too.
+ * Otherwise first few count pipe_vertex_elements could be identical
+ * even if count is different, and there's no guarantee the hash would
+ * be different in that case neither.
+ */
key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
velems_state.count = count;
- memcpy(velems_state.velems, states, sizeof(struct pipe_vertex_element) * count);
+ memcpy(velems_state.velems, states,
+ sizeof(struct pipe_vertex_element) * count);
hash_key = cso_construct_key((void*)&velems_state, key_size);
- iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)&velems_state, key_size);
+ iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS,
+ (void*)&velems_state, key_size);
if (cso_hash_iter_is_null(iter)) {
struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
return PIPE_ERROR_OUT_OF_MEMORY;
memcpy(&cso->state, &velems_state, key_size);
- cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state.velems[0]);
- cso->delete_state = (cso_state_callback)ctx->pipe->delete_vertex_elements_state;
+ cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count,
+ &cso->state.velems[0]);
+ cso->delete_state =
+ (cso_state_callback) ctx->pipe->delete_vertex_elements_state;
cso->context = ctx->pipe;
iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
/* vertex buffers */
void cso_set_vertex_buffers(struct cso_context *ctx,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
- u_vbuf_set_vertex_buffers(vbuf, count, buffers);
+ u_vbuf_set_vertex_buffers(vbuf, start_slot, count, buffers);
return;
}
- if (count != ctx->nr_vertex_buffers ||
- memcmp(buffers, ctx->vertex_buffers,
- sizeof(struct pipe_vertex_buffer) * count) != 0) {
- util_copy_vertex_buffers(ctx->vertex_buffers, &ctx->nr_vertex_buffers,
- buffers, count);
- ctx->pipe->set_vertex_buffers(ctx->pipe, count, buffers);
+ /* Save what's in the auxiliary slot, so that we can save and restore it
+ * for meta ops. */
+ if (start_slot <= ctx->aux_vertex_buffer_index &&
+ start_slot+count > ctx->aux_vertex_buffer_index) {
+ if (buffers) {
+ const struct pipe_vertex_buffer *vb =
+ buffers + (ctx->aux_vertex_buffer_index - start_slot);
+
+ pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer,
+ vb->buffer);
+ memcpy(&ctx->aux_vertex_buffer_current, vb,
+ sizeof(struct pipe_vertex_buffer));
+ }
+ else {
+ pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer,
+ NULL);
+ ctx->aux_vertex_buffer_current.user_buffer = NULL;
+ }
}
+
+ ctx->pipe->set_vertex_buffers(ctx->pipe, start_slot, count, buffers);
}
-void cso_save_vertex_buffers(struct cso_context *ctx)
+void cso_save_aux_vertex_buffer_slot(struct cso_context *ctx)
{
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
- u_vbuf_save_vertex_buffers(vbuf);
+ u_vbuf_save_aux_vertex_buffer_slot(vbuf);
return;
}
- util_copy_vertex_buffers(ctx->vertex_buffers_saved,
- &ctx->nr_vertex_buffers_saved,
- ctx->vertex_buffers,
- ctx->nr_vertex_buffers);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer,
+ ctx->aux_vertex_buffer_current.buffer);
+ memcpy(&ctx->aux_vertex_buffer_saved, &ctx->aux_vertex_buffer_current,
+ sizeof(struct pipe_vertex_buffer));
}
-void cso_restore_vertex_buffers(struct cso_context *ctx)
+void cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx)
{
- unsigned i;
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
- u_vbuf_restore_vertex_buffers(vbuf);
+ u_vbuf_restore_aux_vertex_buffer_slot(vbuf);
return;
}
- util_copy_vertex_buffers(ctx->vertex_buffers,
- &ctx->nr_vertex_buffers,
- ctx->vertex_buffers_saved,
- ctx->nr_vertex_buffers_saved);
-
- for (i = 0; i < ctx->nr_vertex_buffers_saved; i++) {
- pipe_resource_reference(&ctx->vertex_buffers_saved[i].buffer, NULL);
- }
- ctx->nr_vertex_buffers_saved = 0;
+ cso_set_vertex_buffers(ctx, ctx->aux_vertex_buffer_index, 1,
+ &ctx->aux_vertex_buffer_saved);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, NULL);
+}
- ctx->pipe->set_vertex_buffers(ctx->pipe, ctx->nr_vertex_buffers,
- ctx->vertex_buffers);
+unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx)
+{
+ return ctx->aux_vertex_buffer_index;
}
memcpy(&cso->state, templ, sizeof(*templ));
cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
- cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
+ cso->delete_state =
+ (cso_state_callback) ctx->pipe->delete_sampler_state;
cso->context = ctx->pipe;
iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
enum pipe_error
cso_single_sampler(struct cso_context *ctx,
+ unsigned shader_stage,
unsigned idx,
const struct pipe_sampler_state *templ)
{
- return single_sampler(ctx, &ctx->fragment_samplers, idx, templ);
-}
-
-enum pipe_error
-cso_single_vertex_sampler(struct cso_context *ctx,
- unsigned idx,
- const struct pipe_sampler_state *templ)
-{
- return single_sampler(ctx, &ctx->vertex_samplers, idx, templ);
+ return single_sampler(ctx, &ctx->samplers[shader_stage], idx, templ);
}
static void
-single_sampler_done(struct cso_context *ctx,
- struct sampler_info *info)
+single_sampler_done(struct cso_context *ctx, unsigned shader_stage)
{
+ struct sampler_info *info = &ctx->samplers[shader_stage];
unsigned i;
/* find highest non-null sampler */
if (info->hw.nr_samplers != info->nr_samplers ||
memcmp(info->hw.samplers,
info->samplers,
- info->nr_samplers * sizeof(void *)) != 0)
+ info->nr_samplers * sizeof(void *)) != 0)
{
memcpy(info->hw.samplers,
info->samplers,
info->nr_samplers * sizeof(void *));
info->hw.nr_samplers = info->nr_samplers;
- if (info == &ctx->fragment_samplers) {
+ switch (shader_stage) {
+ case PIPE_SHADER_FRAGMENT:
ctx->pipe->bind_fragment_sampler_states(ctx->pipe,
info->nr_samplers,
info->samplers);
- }
- else if (info == &ctx->vertex_samplers) {
+ break;
+ case PIPE_SHADER_VERTEX:
ctx->pipe->bind_vertex_sampler_states(ctx->pipe,
info->nr_samplers,
info->samplers);
- }
- else {
- assert(0);
+ break;
+ case PIPE_SHADER_GEOMETRY:
+ ctx->pipe->bind_geometry_sampler_states(ctx->pipe,
+ info->nr_samplers,
+ info->samplers);
+ break;
+ default:
+ assert(!"bad shader type in single_sampler_done()");
}
}
}
void
-cso_single_sampler_done( struct cso_context *ctx )
-{
- single_sampler_done(ctx, &ctx->fragment_samplers);
-}
-
-void
-cso_single_vertex_sampler_done(struct cso_context *ctx)
+cso_single_sampler_done(struct cso_context *ctx, unsigned shader_stage)
{
- single_sampler_done(ctx, &ctx->vertex_samplers);
+ single_sampler_done(ctx, shader_stage);
}
* last one. Done to always try to set as many samplers
* as possible.
*/
-static enum pipe_error
-set_samplers(struct cso_context *ctx,
- struct sampler_info *info,
- unsigned nr,
- const struct pipe_sampler_state **templates)
+enum pipe_error
+cso_set_samplers(struct cso_context *ctx,
+ unsigned shader_stage,
+ unsigned nr,
+ const struct pipe_sampler_state **templates)
{
+ struct sampler_info *info = &ctx->samplers[shader_stage];
unsigned i;
enum pipe_error temp, error = PIPE_OK;
error = temp;
}
- single_sampler_done(ctx, info);
+ single_sampler_done(ctx, shader_stage);
return error;
}
-enum pipe_error
-cso_set_samplers(struct cso_context *ctx,
- unsigned nr,
- const struct pipe_sampler_state **templates)
-{
- return set_samplers(ctx, &ctx->fragment_samplers, nr, templates);
-}
-
-enum pipe_error
-cso_set_vertex_samplers(struct cso_context *ctx,
- unsigned nr,
- const struct pipe_sampler_state **templates)
-{
- return set_samplers(ctx, &ctx->vertex_samplers, nr, templates);
-}
-
-
-
-static void
-save_samplers(struct cso_context *ctx, struct sampler_info *info)
+void
+cso_save_samplers(struct cso_context *ctx, unsigned shader_stage)
{
+ struct sampler_info *info = &ctx->samplers[shader_stage];
info->nr_samplers_saved = info->nr_samplers;
memcpy(info->samplers_saved, info->samplers, sizeof(info->samplers));
}
-void
-cso_save_samplers(struct cso_context *ctx)
-{
- save_samplers(ctx, &ctx->fragment_samplers);
-}
void
-cso_save_vertex_samplers(struct cso_context *ctx)
-{
- save_samplers(ctx, &ctx->vertex_samplers);
-}
-
-
-
-static void
-restore_samplers(struct cso_context *ctx, struct sampler_info *info)
+cso_restore_samplers(struct cso_context *ctx, unsigned shader_stage)
{
+ struct sampler_info *info = &ctx->samplers[shader_stage];
info->nr_samplers = info->nr_samplers_saved;
memcpy(info->samplers, info->samplers_saved, sizeof(info->samplers));
- single_sampler_done(ctx, info);
+ single_sampler_done(ctx, shader_stage);
}
-void
-cso_restore_samplers(struct cso_context *ctx)
-{
- restore_samplers(ctx, &ctx->fragment_samplers);
-}
void
-cso_restore_vertex_samplers(struct cso_context *ctx)
+cso_set_sampler_views(struct cso_context *ctx,
+ unsigned shader_stage,
+ unsigned count,
+ struct pipe_sampler_view **views)
{
- restore_samplers(ctx, &ctx->vertex_samplers);
-}
-
-
-
-static void
-set_sampler_views(struct cso_context *ctx,
- struct sampler_info *info,
- void (*set_views)(struct pipe_context *,
- unsigned num_views,
- struct pipe_sampler_view **),
- uint count,
- struct pipe_sampler_view **views)
-{
- uint i;
+ struct sampler_info *info = &ctx->samplers[shader_stage];
+ unsigned i;
/* reference new views */
for (i = 0; i < count; i++) {
info->nr_views = count;
/* bind the new sampler views */
- set_views(ctx->pipe, count, info->views);
+ switch (shader_stage) {
+ case PIPE_SHADER_FRAGMENT:
+ ctx->pipe->set_fragment_sampler_views(ctx->pipe, count, info->views);
+ break;
+ case PIPE_SHADER_VERTEX:
+ ctx->pipe->set_vertex_sampler_views(ctx->pipe, count, info->views);
+ break;
+ case PIPE_SHADER_GEOMETRY:
+ ctx->pipe->set_geometry_sampler_views(ctx->pipe, count, info->views);
+ break;
+ default:
+ assert(!"bad shader type in cso_set_sampler_views()");
+ }
}
-void
-cso_set_fragment_sampler_views(struct cso_context *ctx,
- uint count,
- struct pipe_sampler_view **views)
-{
- set_sampler_views(ctx, &ctx->fragment_samplers,
- ctx->pipe->set_fragment_sampler_views,
- count, views);
-}
void
-cso_set_vertex_sampler_views(struct cso_context *ctx,
- uint count,
- struct pipe_sampler_view **views)
-{
- set_sampler_views(ctx, &ctx->vertex_samplers,
- ctx->pipe->set_vertex_sampler_views,
- count, views);
-}
-
-
-
-static void
-save_sampler_views(struct cso_context *ctx,
- struct sampler_info *info)
+cso_save_sampler_views(struct cso_context *ctx, unsigned shader_stage)
{
- uint i;
+ struct sampler_info *info = &ctx->samplers[shader_stage];
+ unsigned i;
info->nr_views_saved = info->nr_views;
}
}
-void
-cso_save_fragment_sampler_views(struct cso_context *ctx)
-{
- save_sampler_views(ctx, &ctx->fragment_samplers);
-}
void
-cso_save_vertex_sampler_views(struct cso_context *ctx)
-{
- save_sampler_views(ctx, &ctx->vertex_samplers);
-}
-
-
-static void
-restore_sampler_views(struct cso_context *ctx,
- struct sampler_info *info,
- void (*set_views)(struct pipe_context *,
- unsigned num_views,
- struct pipe_sampler_view **))
+cso_restore_sampler_views(struct cso_context *ctx, unsigned shader_stage)
{
- uint i;
+ struct sampler_info *info = &ctx->samplers[shader_stage];
+ unsigned i, nr_saved = info->nr_views_saved;
- for (i = 0; i < info->nr_views_saved; i++) {
+ for (i = 0; i < nr_saved; i++) {
pipe_sampler_view_reference(&info->views[i], NULL);
/* move the reference from one pointer to another */
info->views[i] = info->views_saved[i];
}
/* bind the old/saved sampler views */
- set_views(ctx->pipe, info->nr_views_saved, info->views);
+ switch (shader_stage) {
+ case PIPE_SHADER_FRAGMENT:
+ ctx->pipe->set_fragment_sampler_views(ctx->pipe, nr_saved, info->views);
+ break;
+ case PIPE_SHADER_VERTEX:
+ ctx->pipe->set_vertex_sampler_views(ctx->pipe, nr_saved, info->views);
+ break;
+ case PIPE_SHADER_GEOMETRY:
+ ctx->pipe->set_geometry_sampler_views(ctx->pipe, nr_saved, info->views);
+ break;
+ default:
+ assert(!"bad shader type in cso_restore_sampler_views()");
+ }
- info->nr_views = info->nr_views_saved;
+ info->nr_views = nr_saved;
info->nr_views_saved = 0;
}
-void
-cso_restore_fragment_sampler_views(struct cso_context *ctx)
-{
- restore_sampler_views(ctx, &ctx->fragment_samplers,
- ctx->pipe->set_fragment_sampler_views);
-}
-
-void
-cso_restore_vertex_sampler_views(struct cso_context *ctx)
-{
- restore_sampler_views(ctx, &ctx->vertex_samplers,
- ctx->pipe->set_vertex_sampler_views);
-}
-
void
cso_set_stream_outputs(struct cso_context *ctx,
ctx->nr_so_targets_saved = 0;
}
+/* constant buffers */
+
+void
+cso_set_constant_buffer(struct cso_context *cso, unsigned shader_stage,
+ unsigned index, struct pipe_constant_buffer *cb)
+{
+ struct pipe_context *pipe = cso->pipe;
+
+ pipe->set_constant_buffer(pipe, shader_stage, index, cb);
+
+ if (index == 0) {
+ util_copy_constant_buffer(&cso->aux_constbuf_current[shader_stage], cb);
+ }
+}
+
+void
+cso_set_constant_buffer_resource(struct cso_context *cso,
+ unsigned shader_stage,
+ unsigned index,
+ struct pipe_resource *buffer)
+{
+ if (buffer) {
+ struct pipe_constant_buffer cb;
+ cb.buffer = buffer;
+ cb.buffer_offset = 0;
+ cb.buffer_size = buffer->width0;
+ cb.user_buffer = NULL;
+ cso_set_constant_buffer(cso, shader_stage, index, &cb);
+ } else {
+ cso_set_constant_buffer(cso, shader_stage, index, NULL);
+ }
+}
+
+void
+cso_save_constant_buffer_slot0(struct cso_context *cso,
+ unsigned shader_stage)
+{
+ util_copy_constant_buffer(&cso->aux_constbuf_saved[shader_stage],
+ &cso->aux_constbuf_current[shader_stage]);
+}
+
+void
+cso_restore_constant_buffer_slot0(struct cso_context *cso,
+ unsigned shader_stage)
+{
+ cso_set_constant_buffer(cso, shader_stage, 0,
+ &cso->aux_constbuf_saved[shader_stage]);
+ pipe_resource_reference(&cso->aux_constbuf_saved[shader_stage].buffer,
+ NULL);
+}
+
/* drawing */
void