diff options
author | Ben Skeggs <[email protected]> | 2008-03-21 00:11:25 +1100 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2008-03-21 00:11:25 +1100 |
commit | c7e9cb10937391c25a884fe62db91ea9b910d672 (patch) | |
tree | 42a854fef74df0d07421ebe466857260fe096e1a /src/gallium | |
parent | 62767cf2dd1006621ecd6023b15d65b5cff41dfa (diff) | |
parent | 122ed506f4b808503b230bade421018614dbe696 (diff) |
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/gallium')
22 files changed, 510 insertions, 179 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 294ac82281e..01fe2164478 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -52,11 +52,27 @@ struct cso_context { void *samplers[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; - void *blend; - void *depth_stencil; - void *rasterizer; - void *fragment_shader; - void *vertex_shader; + void *samplers_saved[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers_saved; + + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + uint nr_textures; + + struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_textures_saved; + + /** Current and saved state. + * The saved state is used as a 1-deep stack. + */ + void *blend, *blend_saved; + void *depth_stencil, *depth_stencil_saved; + void *rasterizer, *rasterizer_saved; + void *fragment_shader, *fragment_shader_saved; + void *vertex_shader, *vertex_shader_saved; + + struct pipe_framebuffer_state fb, fb_saved; + struct pipe_viewport_state vp, vp_saved; + struct pipe_blend_color blend_color; }; @@ -149,12 +165,23 @@ void cso_set_blend(struct cso_context *ctx, } } -void cso_unset_blend(struct cso_context *ctx) +void cso_save_blend(struct cso_context *ctx) +{ + assert(!ctx->blend_saved); + ctx->blend_saved = ctx->blend; +} + +void cso_restore_blend(struct cso_context *ctx) { - ctx->blend = NULL; + if (ctx->blend != ctx->blend_saved) { + ctx->blend = ctx->blend_saved; + ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved); + } + ctx->blend_saved = NULL; } + void cso_single_sampler(struct cso_context *ctx, unsigned idx, const struct pipe_sampler_state *templ) @@ -190,9 +217,11 @@ void cso_single_sampler_done( struct cso_context *ctx ) { unsigned i; - for (i = 0; i < 8; i++) - if (ctx->samplers[i] == NULL) + /* find highest non-null sampler */ + for (i = PIPE_MAX_SAMPLERS; i > 0; i--) { + if (ctx->samplers[i - 1] != NULL) break; + } ctx->nr_samplers = i; @@ -226,15 +255,50 @@ void cso_set_samplers( struct cso_context *ctx, cso_single_sampler_done( ctx ); } -void cso_unset_samplers( struct cso_context *ctx ) +void cso_save_samplers(struct cso_context *ctx) +{ + ctx->nr_samplers_saved = ctx->nr_samplers; + memcpy(ctx->samplers_saved, ctx->samplers, sizeof(ctx->samplers)); +} + +void cso_restore_samplers(struct cso_context *ctx) +{ + cso_set_samplers(ctx, ctx->nr_samplers_saved, + (const struct pipe_sampler_state **) ctx->samplers_saved); +} + + +void cso_set_sampler_textures( struct cso_context *ctx, + uint count, + struct pipe_texture **textures ) { uint i; - for (i = 0; i < ctx->nr_samplers; i++) - ctx->samplers[i] = NULL; + + ctx->nr_textures = count; + + for (i = 0; i < count; i++) + ctx->textures[i] = textures[i]; + for ( ; i < PIPE_MAX_SAMPLERS; i++) + ctx->textures[i] = NULL; + + ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); +} + +void cso_save_sampler_textures( struct cso_context *ctx ) +{ + ctx->nr_textures_saved = ctx->nr_textures; + memcpy(ctx->textures_saved, ctx->textures, sizeof(ctx->textures)); +} + +void cso_restore_sampler_textures( struct cso_context *ctx ) +{ + cso_set_sampler_textures(ctx, ctx->nr_textures_saved, ctx->textures_saved); + ctx->nr_textures_saved = 0; } + void cso_set_depth_stencil_alpha(struct cso_context *ctx, const struct pipe_depth_stencil_alpha_state *templ) { @@ -267,15 +331,25 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, } } -void cso_unset_depth_stencil_alpha(struct cso_context *ctx) +void cso_save_depth_stencil_alpha(struct cso_context *ctx) { - ctx->depth_stencil = NULL; + assert(!ctx->depth_stencil_saved); + ctx->depth_stencil_saved = ctx->depth_stencil; +} + +void cso_restore_depth_stencil_alpha(struct cso_context *ctx) +{ + 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->depth_stencil_saved = NULL; } void cso_set_rasterizer(struct cso_context *ctx, - const struct pipe_rasterizer_state *templ) + const struct pipe_rasterizer_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_rasterizer_state)); @@ -305,11 +379,20 @@ void cso_set_rasterizer(struct cso_context *ctx, } } -void cso_unset_rasterizer(struct cso_context *ctx) +void cso_save_rasterizer(struct cso_context *ctx) { - ctx->rasterizer = NULL; + assert(!ctx->rasterizer_saved); + ctx->rasterizer_saved = ctx->rasterizer; } +void cso_restore_rasterizer(struct cso_context *ctx) +{ + if (ctx->rasterizer != ctx->rasterizer_saved) { + ctx->rasterizer = ctx->rasterizer_saved; + ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved); + } + ctx->rasterizer_saved = NULL; +} void cso_set_fragment_shader(struct cso_context *ctx, @@ -343,12 +426,24 @@ void cso_set_fragment_shader(struct cso_context *ctx, } } -void cso_unset_fragment_shader(struct cso_context *ctx) +void cso_save_fragment_shader(struct cso_context *ctx) { - ctx->fragment_shader = NULL; + assert(!ctx->fragment_shader_saved); + ctx->fragment_shader_saved = ctx->fragment_shader; +} + +void cso_restore_fragment_shader(struct cso_context *ctx) +{ + assert(ctx->fragment_shader_saved); + if (ctx->fragment_shader_saved != ctx->fragment_shader) { + ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved); + ctx->fragment_shader = ctx->fragment_shader_saved; + } + ctx->fragment_shader_saved = NULL; } + void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -380,7 +475,78 @@ void cso_set_vertex_shader(struct cso_context *ctx, } } -void cso_unset_vertex_shader(struct cso_context *ctx) +void cso_save_vertex_shader(struct cso_context *ctx) +{ + assert(!ctx->vertex_shader_saved); + ctx->vertex_shader_saved = ctx->vertex_shader; +} + +void cso_restore_vertex_shader(struct cso_context *ctx) +{ + assert(ctx->vertex_shader_saved); + if (ctx->vertex_shader_saved != ctx->vertex_shader) { + ctx->pipe->bind_fs_state(ctx->pipe, ctx->vertex_shader_saved); + ctx->vertex_shader = ctx->vertex_shader_saved; + } + ctx->vertex_shader_saved = NULL; +} + + + +void cso_set_framebuffer(struct cso_context *ctx, + const struct pipe_framebuffer_state *fb) +{ + if (memcmp(&ctx->fb, fb, sizeof(*fb))) { + ctx->fb = *fb; + ctx->pipe->set_framebuffer_state(ctx->pipe, fb); + } +} + +void cso_save_framebuffer(struct cso_context *ctx) +{ + ctx->fb_saved = ctx->fb; +} + +void cso_restore_framebuffer(struct cso_context *ctx) +{ + if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) { + ctx->fb = ctx->fb_saved; + ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb); + } +} + + +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); + } +} + +void cso_save_viewport(struct cso_context *ctx) { - ctx->vertex_shader = NULL; + ctx->vp_saved = ctx->vp; +} + + +void cso_restore_viewport(struct cso_context *ctx) +{ + if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) { + ctx->vp = ctx->vp_saved; + ctx->pipe->set_viewport_state(ctx->pipe, &ctx->vp); + } +} + + + + +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); + } } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 6aa619abf56..665e8d99110 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -41,27 +41,36 @@ struct cso_context; struct cso_context *cso_create_context( struct pipe_context *pipe ); +void cso_destroy_context( struct cso_context *cso ); + + + void cso_set_blend( struct cso_context *cso, const struct pipe_blend_state *blend ); +void cso_save_blend(struct cso_context *cso); +void cso_restore_blend(struct cso_context *cso); + -void cso_unset_blend(struct cso_context *cso); void cso_set_depth_stencil_alpha( struct cso_context *cso, const struct pipe_depth_stencil_alpha_state *dsa ); +void cso_save_depth_stencil_alpha(struct cso_context *cso); +void cso_restore_depth_stencil_alpha(struct cso_context *cso); + -void cso_unset_depth_stencil_alpha( struct cso_context *cso ); void cso_set_rasterizer( struct cso_context *cso, const struct pipe_rasterizer_state *rasterizer ); +void cso_save_rasterizer(struct cso_context *cso); +void cso_restore_rasterizer(struct cso_context *cso); + -void cso_unset_rasterizer( struct cso_context *cso ); void cso_set_samplers( struct cso_context *cso, unsigned count, const struct pipe_sampler_state **states ); - -void cso_unset_samplers( struct cso_context *cso ); - +void cso_save_samplers(struct cso_context *cso); +void cso_restore_samplers(struct cso_context *cso); /* Alternate interface to support state trackers that like to modify * samplers one at a time: @@ -73,6 +82,15 @@ void cso_single_sampler( struct cso_context *cso, void cso_single_sampler_done( struct cso_context *cso ); + +void cso_set_sampler_textures( struct cso_context *cso, + uint count, + struct pipe_texture **textures ); +void cso_save_sampler_textures( struct cso_context *cso ); +void cso_restore_sampler_textures( struct cso_context *cso ); + + + /* These aren't really sensible -- most of the time the api provides * object semantics for shaders anyway, and the cases where it doesn't * (eg mesa's internall-generated texenv programs), it will be up to @@ -80,15 +98,32 @@ void cso_single_sampler_done( struct cso_context *cso ); */ void cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +void cso_save_fragment_shader(struct cso_context *cso); +void cso_restore_fragment_shader(struct cso_context *cso); + -void cso_unset_fragment_shader( struct cso_context *cso ); void cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +void cso_save_vertex_shader(struct cso_context *cso); +void cso_restore_vertex_shader(struct cso_context *cso); -void cso_unset_vertex_shader( struct cso_context *cso ); -void cso_destroy_context( struct cso_context *cso ); + +void cso_set_framebuffer(struct cso_context *cso, + const struct pipe_framebuffer_state *fb); +void cso_save_framebuffer(struct cso_context *cso); +void cso_restore_framebuffer(struct cso_context *cso); + + +void cso_set_viewport(struct cso_context *cso, + const struct pipe_viewport_state *vp); +void cso_save_viewport(struct cso_context *cso); +void cso_restore_viewport(struct cso_context *cso); + + +void cso_set_blend_color(struct cso_context *cso, + const struct pipe_blend_color *bc); #ifdef __cplusplus diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index f2b983374e6..b4fa6bd9670 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -410,6 +410,7 @@ aaline_create_texture(struct aaline_stage *aaline) /* unmap */ pipe_surface_unmap(surface); pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); } } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 09d542002f0..9d154a68381 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -374,7 +374,7 @@ pstip_update_texture(struct pstip_stage *pstip) /* unmap */ pipe_surface_unmap(surface); pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture); + pipe->texture_update(pipe, pstip->texture, 0, 0x1); } diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index bb84e8096d2..bd3a0221eaa 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -52,6 +52,9 @@ rpl_EngDebugPrint(const char *format, ...) } int rpl_vsnprintf(char *, size_t, const char *, va_list); +int rpl_snprintf(char *str, size_t size, const char *format, ...); +#define vsnprintf rpl_vsnprintf +#define snprintf rpl_snprintf #endif @@ -181,3 +184,59 @@ void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_lis if(mask & what) debug_vprintf(format, ap); } + + +const char * +debug_dump_enum(const struct debug_named_value *names, + unsigned long value) +{ + static char rest[256]; + + while(names->name) { + if(names->value == value) + return names->name; + ++names; + } + + snprintf(rest, sizeof(rest), "0x%08x", value); + return rest; +} + + +const char * +debug_dump_flags(const struct debug_named_value *names, + unsigned long value) +{ + static char output[4096]; + static char rest[256]; + int first = 1; + + output[0] = '\0'; + + while(names->name) { + if((names->value & value) == names->value) { + if (!first) + strncat(output, "|", sizeof(output)); + else + first = 0; + strncat(output, names->name, sizeof(output)); + value &= ~names->value; + } + ++names; + } + + if (value) { + if (!first) + strncat(output, "|", sizeof(output)); + else + first = 0; + + snprintf(rest, sizeof(rest), "0x%08x", value); + strncat(output, rest, sizeof(output)); + } + + if(first) + return "0"; + + return output; +} diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 4b4ab8185f2..d05dae3af8f 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -45,15 +45,18 @@ #include "util/u_blit.h" #include "util/u_simple_shaders.h" +#include "cso_cache/cso_context.h" + struct blit_state { struct pipe_context *pipe; + struct cso_context *cso; - void *blend; - void *depthstencil; - void *rasterizer; - void *samplers[2]; /* one for linear, one for nearest sampling */ + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; /*struct pipe_viewport_state viewport;*/ struct pipe_sampler_state *vs; @@ -66,56 +69,44 @@ struct blit_state * Intended to be created once and re-used for many blit() calls. */ struct blit_state * -util_create_blit(struct pipe_context *pipe) +util_create_blit(struct pipe_context *pipe, struct cso_context *cso) { - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state depthstencil; - struct pipe_rasterizer_state rasterizer; struct blit_state *ctx; - struct pipe_sampler_state sampler; ctx = CALLOC_STRUCT(blit_state); if (!ctx) return NULL; ctx->pipe = pipe; + ctx->cso = cso; - /* we don't use blending, but need to set valid values */ - memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; - ctx->blend = pipe->create_blend_state(pipe, &blend); + /* disabled blending/masking */ + memset(&ctx->blend, 0, sizeof(ctx->blend)); + ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.colormask = PIPE_MASK_RGBA; - /* depth/stencil/alpha */ - memset(&depthstencil, 0, sizeof(depthstencil)); - ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + /* no-op depth/stencil/alpha */ + memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); /* rasterizer */ - memset(&rasterizer, 0, sizeof(rasterizer)); - rasterizer.front_winding = PIPE_WINDING_CW; - rasterizer.cull_mode = PIPE_WINDING_NONE; - rasterizer.bypass_clipping = 1; /* bypasses viewport too */ - /*rasterizer.bypass_vs = 1;*/ - ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer); + memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); + ctx->rasterizer.front_winding = PIPE_WINDING_CW; + ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; + ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + /*ctx->rasterizer.bypass_vs = 1;*/ /* samplers */ - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - sampler.normalized_coords = 1; - ctx->samplers[0] = pipe->create_sampler_state(pipe, &sampler); - - sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR; - ctx->samplers[1] = pipe->create_sampler_state(pipe, &sampler); - + memset(&ctx->sampler, 0, sizeof(ctx->sampler)); + ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + ctx->sampler.min_img_filter = 0; /* set later */ + ctx->sampler.mag_img_filter = 0; /* set later */ + ctx->sampler.normalized_coords = 1; #if 0 /* viewport */ @@ -153,12 +144,6 @@ util_destroy_blit(struct blit_state *ctx) { struct pipe_context *pipe = ctx->pipe; - pipe->delete_blend_state(pipe, ctx->blend); - pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->delete_rasterizer_state(pipe, ctx->rasterizer); - pipe->delete_sampler_state(pipe, ctx->samplers[0]); - pipe->delete_sampler_state(pipe, ctx->samplers[1]); - pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); @@ -236,17 +221,24 @@ util_blit_pixels(struct blit_state *ctx, src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ - /* drawing dest */ - memset(&fb, 0, sizeof(fb)); - fb.num_cbufs = 1; - fb.cbufs[0] = dst; - pipe->set_framebuffer_state(pipe, &fb); + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_sampler_textures(ctx->cso); + cso_save_framebuffer(ctx->cso); + + /* set misc state we care about */ + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); /* sampler */ - if (filter == PIPE_TEX_MIPFILTER_NEAREST) - pipe->bind_sampler_states(pipe, 1, &ctx->samplers[0]); - else - pipe->bind_sampler_states(pipe, 1, &ctx->samplers[1]); + ctx->sampler.min_img_filter = filter; + ctx->sampler.mag_img_filter = filter; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + cso_single_sampler_done(ctx->cso); /* texture */ pipe->set_sampler_textures(pipe, 1, &tex); @@ -255,22 +247,29 @@ util_blit_pixels(struct blit_state *ctx, pipe->bind_fs_state(pipe, ctx->fs); pipe->bind_vs_state(pipe, ctx->vs); - /* misc state */ - pipe->bind_blend_state(pipe, ctx->blend); - pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->bind_rasterizer_state(pipe, ctx->rasterizer); + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.num_cbufs = 1; + fb.cbufs[0] = dst; + cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z); - - /* unbind */ - pipe->set_sampler_textures(pipe, 0, NULL); - pipe->bind_sampler_states(pipe, 0, NULL); - - /* free stuff */ + util_draw_texquad(pipe, + (float)dstX0, + (float)dstY0, + (float)dstX1, + (float)dstY1, z); + + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_sampler_textures(ctx->cso); + cso_restore_framebuffer(ctx->cso); + + /* free the texture */ pipe_surface_reference(&texSurf, NULL); screen->texture_release(screen, &tex); - - /* Note: caller must restore pipe/gallium state at this time */ } diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index a349be99ad8..61f1d9bb32a 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -30,15 +30,16 @@ #define U_BLIT_H + struct pipe_context; struct pipe_surface; +struct cso_context; struct blit_state; - extern struct blit_state * -util_create_blit(struct pipe_context *pipe); +util_create_blit(struct pipe_context *pipe, struct cso_context *cso); extern void diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index e18f8ab72ac..028b180a777 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -49,14 +49,18 @@ #include "tgsi/util/tgsi_dump.h" #include "tgsi/util/tgsi_parse.h" +#include "cso_cache/cso_context.h" + struct gen_mipmap_state { struct pipe_context *pipe; + struct cso_context *cso; - void *blend; - void *depthstencil; - void *rasterizer; + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; /*struct pipe_viewport_state viewport;*/ struct pipe_sampler_state *vs; struct pipe_sampler_state *fs; @@ -675,11 +679,9 @@ fallback_gen_mipmap(struct gen_mipmap_state *ctx, * generate a mipmap. */ struct gen_mipmap_state * -util_create_gen_mipmap(struct pipe_context *pipe) +util_create_gen_mipmap(struct pipe_context *pipe, + struct cso_context *cso) { - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state depthstencil; - struct pipe_rasterizer_state rasterizer; struct gen_mipmap_state *ctx; ctx = CALLOC_STRUCT(gen_mipmap_state); @@ -687,27 +689,36 @@ util_create_gen_mipmap(struct pipe_context *pipe) return NULL; ctx->pipe = pipe; + ctx->cso = cso; - /* we don't use blending, but need to set valid values */ - memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; - ctx->blend = pipe->create_blend_state(pipe, &blend); + /* disabled blending/masking */ + memset(&ctx->blend, 0, sizeof(ctx->blend)); + ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.colormask = PIPE_MASK_RGBA; - /* depth/stencil/alpha */ - memset(&depthstencil, 0, sizeof(depthstencil)); - ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + /* no-op depth/stencil/alpha */ + memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); /* rasterizer */ - memset(&rasterizer, 0, sizeof(rasterizer)); - rasterizer.front_winding = PIPE_WINDING_CW; - rasterizer.cull_mode = PIPE_WINDING_NONE; - rasterizer.bypass_clipping = 1; /* bypasses viewport too */ - //rasterizer.bypass_vs = 1; - ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer); + memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); + ctx->rasterizer.front_winding = PIPE_WINDING_CW; + ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; + ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + /*ctx->rasterizer.bypass_vs = 1;*/ + + /* sampler state */ + memset(&ctx->sampler, 0, sizeof(ctx->sampler)); + ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; + ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + ctx->sampler.normalized_coords = 1; + #if 0 /* viewport */ @@ -745,9 +756,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) { struct pipe_context *pipe = ctx->pipe; - pipe->delete_blend_state(pipe, ctx->blend); - pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->delete_rasterizer_state(pipe, ctx->rasterizer); pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); @@ -792,8 +800,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; - struct pipe_sampler_state sampler; - void *sampler_cso; uint dstLevel; uint zslice = 0; @@ -803,30 +809,29 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, return; } - /* init framebuffer state */ - memset(&fb, 0, sizeof(fb)); - fb.num_cbufs = 1; - - /* sampler state */ - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.normalized_coords = 1; + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_sampler_textures(ctx->cso); + cso_save_framebuffer(ctx->cso); /* bind our state */ - pipe->bind_blend_state(pipe, ctx->blend); - pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->bind_rasterizer_state(pipe, ctx->rasterizer); + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + pipe->bind_vs_state(pipe, ctx->vs); pipe->bind_fs_state(pipe, ctx->fs); #if 0 pipe->set_viewport_state(pipe, &ctx->viewport); #endif + /* init framebuffer state */ + memset(&fb, 0, sizeof(fb)); + fb.num_cbufs = 1; + /* * XXX for small mipmap levels, it may be faster to use the software * fallback path... @@ -838,7 +843,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * Setup framebuffer / dest surface */ fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); - pipe->set_framebuffer_state(pipe, &fb); + cso_set_framebuffer(ctx->cso, &fb); /* * Setup sampler state @@ -847,11 +852,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * has trouble with min clamping so we also set the lod_bias to * try to work around that. */ - sampler.min_lod = sampler.max_lod = (float) srcLevel; - sampler.lod_bias = (float) srcLevel; - sampler_cso = pipe->create_sampler_state(pipe, &sampler); - pipe->bind_sampler_states(pipe, 1, &sampler_cso); - + ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; + ctx->sampler.lod_bias = (float) srcLevel; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + cso_single_sampler_done(ctx->cso); #if 0 simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); #endif @@ -868,10 +872,15 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->flush(pipe, PIPE_FLUSH_WAIT); - /*pipe->texture_update(pipe, pt); not really needed */ - - pipe->delete_sampler_state(pipe, sampler_cso); + /* need to signal that the texture has changed _after_ rendering to it */ + pipe->texture_update(pipe, pt, face, (1 << dstLevel)); } - /* Note: caller must restore pipe/gallium state at this time */ + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_sampler_textures(ctx->cso); + cso_restore_framebuffer(ctx->cso); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index 80496140a24..eeabf3bf075 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -31,11 +31,15 @@ #include "pipe/p_state.h" +struct pipe_context; +struct pipe_texture; +struct cso_context; + struct gen_mipmap_state; extern struct gen_mipmap_state * -util_create_gen_mipmap(struct pipe_context *pipe); +util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso); extern void diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 0bfb9e1b4ae..8b0f7fca4b1 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -248,7 +248,7 @@ handle_table_get_next_handle(struct handle_table *ht, unsigned index; for(index = handle; index < ht->size; ++index) { - if(!ht->objects[index]) + if(ht->objects[index]) return index + 1; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index e235421107e..9c694e136d8 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -134,7 +134,8 @@ cell_texture_release_screen(struct pipe_screen *screen, static void -cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, + uint face, uint levelsMask) { /* XXX TO DO: re-tile the texture data ... */ diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index ef5adff550e..c39e747705b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -542,7 +542,8 @@ i915_texture_release_screen(struct pipe_screen *screen, static void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, + uint face, uint levelsMask) { /* no-op? */ } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index b24ac87c378..b580f98204c 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -358,7 +358,8 @@ brw_texture_release_screen(struct pipe_screen *screen, static void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, + uint face, uint levelsMask) { /* no-op? */ } diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 19e6cfaf02e..31d7062dcc0 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -84,6 +84,8 @@ struct softpipe_context { unsigned num_samplers; unsigned num_textures; + uint fb_width, fb_height; + /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 7aa9cf8e851..f2d6043e2ed 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -485,7 +485,7 @@ setup_fragcoord_coeff(struct setup_stage *setup, uint slot) /*Y*/ if (setup->softpipe->rasterizer->origin_lower_left) { /* y=0=bottom */ - const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height; + const int winHeight = setup->softpipe->fb_height; setup->coef[slot].a0[1] = (float) (winHeight - 1); setup->coef[slot].dady[1] = -1.0; } diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index 8660432259c..9a39249576b 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -25,7 +25,7 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad) int y0, y1; uint stipple0, stipple1; if (softpipe->rasterizer->origin_lower_left) { - y0 = softpipe->framebuffer.cbufs[0]->height - 1 - quad->y0; + y0 = softpipe->fb_height - 1 - quad->y0; y1 = y0 - 1; } else { diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 82cb31ece73..53b2056b8a6 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -171,17 +171,8 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe) static void compute_cliprect(struct softpipe_context *sp) { - unsigned surfWidth, surfHeight; - - if (sp->framebuffer.num_cbufs > 0) { - surfWidth = sp->framebuffer.cbufs[0]->width; - surfHeight = sp->framebuffer.cbufs[0]->height; - } - else { - /* no surface? */ - surfWidth = sp->scissor.maxx; - surfHeight = sp->scissor.maxy; - } + uint surfWidth = sp->fb_width; + uint surfHeight = sp->fb_height; if (sp->rasterizer->scissor) { /* clip to scissor rect */ diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index 124b18b7081..2f556844644 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -48,6 +48,9 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, struct softpipe_context *sp = softpipe_context(pipe); uint i; + /* updated below */ + sp->fb_width = sp->fb_height = 0; + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { /* check if changing cbuf */ if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { @@ -60,6 +63,10 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); } + if (fb->cbufs[i]) { + sp->fb_width = fb->cbufs[i]->width; + sp->fb_height = fb->cbufs[i]->height; + } } sp->framebuffer.num_cbufs = fb->num_cbufs; @@ -74,6 +81,11 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); + + if (!sp->fb_width && fb->zsbuf) { + sp->fb_width = fb->zsbuf->width; + sp->fb_height = fb->zsbuf->height; + } } #if 0 diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 64bf353aa4a..a98b3b1a4a8 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -174,7 +174,8 @@ softpipe_get_tex_surface_screen(struct pipe_screen *screen, static void softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture) + struct pipe_texture *texture, + uint face, uint levelsMask) { struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 4caf2dd3fc9..19f71887e7e 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -156,6 +156,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, if (tc->surface_map) { /*assert(tc->surface != ps);*/ pipe_surface_unmap(tc->surface); + tc->surface_map = NULL; } pipe_surface_reference(&tc->surface, ps); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index b64948f0f3b..a3824601be9 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -192,12 +192,10 @@ struct pipe_context { /** * Called when texture data is changed. - * Note: we could pass some hints about which mip levels or cube faces - * have changed... - * XXX this may go away - could pass a 'write' flag to get_tex_surface() */ void (*texture_update)(struct pipe_context *pipe, - struct pipe_texture *texture); + struct pipe_texture *texture, + uint face, uint dirtyLevelsMask); diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index f3dfa062161..e924c1ef606 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -168,6 +168,55 @@ void debug_mask_vprintf(uint32_t uuid, #endif +/** + * Used by debug_dump_enum and debug_dump_flags to describe symbols. + */ +struct debug_named_value +{ + const char *name; + unsigned long value; +}; + + +/** + * Some C pre-processor magic to simplify creating named values. + * + * Example: + * @code + * static const debug_named_value my_names[] = { + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), + * DEBUG_NAMED_VALUE_END + * }; + * + * ... + * debug_printf("%s = %s\n", + * name, + * debug_dump_enum(my_names, my_value)); + * ... + * @endcode + */ +#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol} +#define DEBUG_NAMED_VALUE_END {NULL, 0} + + +/** + * Convert a enum value to a string. + */ +const char * +debug_dump_enum(const struct debug_named_value *names, + unsigned long value); + + +/** + * Convert binary flags value to a string. + */ +const char * +debug_dump_flags(const struct debug_named_value *names, + unsigned long value); + + #ifdef __cplusplus } #endif |