diff options
Diffstat (limited to 'src/gallium/auxiliary')
65 files changed, 1628 insertions, 615 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 0ac18426d97..452eceb7f4f 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -119,6 +119,7 @@ C_SOURCES = \ util/u_mm.c \ util/u_rect.c \ util/u_ringbuffer.c \ + util/u_sampler.c \ util/u_simple_shaders.c \ util/u_snprintf.c \ util/u_surface.c \ @@ -127,13 +128,15 @@ C_SOURCES = \ util/u_timed_winsys.c \ util/u_upload_mgr.c \ util/u_simple_screen.c \ - vl/vl_bitstream_parser.c \ - vl/vl_mpeg12_mc_renderer.c \ - vl/vl_compositor.c \ - vl/vl_csc.c \ - vl/vl_shader_build.c \ target-helpers/wrap_screen.c + # Disabling until pipe-video branch gets merged in + #vl/vl_bitstream_parser.c \ + #vl/vl_mpeg12_mc_renderer.c \ + #vl/vl_compositor.c \ + #vl/vl_csc.c \ + #vl/vl_shader_build.c \ + GALLIVM_SOURCES = \ gallivm/lp_bld_alpha.c \ gallivm/lp_bld_arit.c \ @@ -152,6 +155,7 @@ GALLIVM_SOURCES = \ gallivm/lp_bld_intr.c \ gallivm/lp_bld_logic.c \ gallivm/lp_bld_pack.c \ + gallivm/lp_bld_printf.c \ gallivm/lp_bld_sample.c \ gallivm/lp_bld_sample_soa.c \ gallivm/lp_bld_struct.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index b234b2f5f4e..d0785bce16b 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -162,6 +162,7 @@ source = [ 'util/u_mm.c', 'util/u_rect.c', 'util/u_ringbuffer.c', + 'util/u_sampler.c', 'util/u_simple_shaders.c', 'util/u_snprintf.c', 'util/u_surface.c', @@ -170,11 +171,12 @@ source = [ 'util/u_timed_winsys.c', 'util/u_upload_mgr.c', 'util/u_simple_screen.c', - 'vl/vl_bitstream_parser.c', - 'vl/vl_mpeg12_mc_renderer.c', - 'vl/vl_compositor.c', - 'vl/vl_csc.c', - 'vl/vl_shader_build.c', + # Disabling until pipe-video branch gets merged in + #'vl/vl_bitstream_parser.c', + #'vl/vl_mpeg12_mc_renderer.c', + #'vl/vl_compositor.c', + #'vl/vl_csc.c', + #'vl/vl_shader_build.c', 'target-helpers/wrap_screen.c', ] @@ -198,6 +200,7 @@ if drawllvm: 'gallivm/lp_bld_logic.c', 'gallivm/lp_bld_init.cpp', 'gallivm/lp_bld_pack.c', + 'gallivm/lp_bld_printf.c', 'gallivm/lp_bld_sample.c', 'gallivm/lp_bld_sample_soa.c', 'gallivm/lp_bld_struct.c', diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 6500891a10c..6fd4bd36428 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -37,6 +37,7 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_math.h" #include "util/u_memory.h" #include "tgsi/tgsi_parse.h" @@ -69,17 +70,17 @@ struct cso_context { unsigned nr_vertex_samplers_saved; void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; - uint nr_textures; + uint nr_fragment_sampler_views; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; - struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; - uint nr_vertex_textures; + uint nr_vertex_sampler_views; + struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; - uint nr_textures_saved; - struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_fragment_sampler_views_saved; + struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS]; - uint nr_vertex_textures_saved; - struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_vertex_sampler_views_saved; + struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS]; /** Current and saved state. * The saved state is used as a 1-deep stack. @@ -293,13 +294,13 @@ void cso_release_all( struct cso_context *ctx ) } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->textures[i], NULL); - pipe_texture_reference(&ctx->textures_saved[i], NULL); + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL); + pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL); + pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL); + pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL); } free_framebuffer_state(&ctx->fb); @@ -616,114 +617,6 @@ cso_restore_vertex_samplers(struct cso_context *ctx) } -enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, - uint count, - struct pipe_texture **textures ) -{ - uint i; - - ctx->nr_textures = count; - - for (i = 0; i < count; i++) - pipe_texture_reference(&ctx->textures[i], textures[i]); - for ( ; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&ctx->textures[i], NULL); - - ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures); - - return PIPE_OK; -} - -void cso_save_sampler_textures( struct cso_context *ctx ) -{ - uint i; - - ctx->nr_textures_saved = ctx->nr_textures; - for (i = 0; i < ctx->nr_textures; i++) { - assert(!ctx->textures_saved[i]); - pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]); - } -} - -void cso_restore_sampler_textures( struct cso_context *ctx ) -{ - uint i; - - ctx->nr_textures = ctx->nr_textures_saved; - - for (i = 0; i < ctx->nr_textures; i++) { - pipe_texture_reference(&ctx->textures[i], NULL); - ctx->textures[i] = ctx->textures_saved[i]; - ctx->textures_saved[i] = NULL; - } - for ( ; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&ctx->textures[i], NULL); - - ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); - - ctx->nr_textures_saved = 0; -} - - - -enum pipe_error -cso_set_vertex_sampler_textures(struct cso_context *ctx, - uint count, - struct pipe_texture **textures) -{ - uint i; - - ctx->nr_vertex_textures = count; - - for (i = 0; i < count; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], textures[i]); - } - for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - } - - ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures); - - return PIPE_OK; -} - -void -cso_save_vertex_sampler_textures(struct cso_context *ctx) -{ - uint i; - - ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures; - for (i = 0; i < ctx->nr_vertex_textures; i++) { - assert(!ctx->vertex_textures_saved[i]); - pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]); - } -} - -void -cso_restore_vertex_sampler_textures(struct cso_context *ctx) -{ - uint i; - - ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved; - - for (i = 0; i < ctx->nr_vertex_textures; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - ctx->vertex_textures[i] = ctx->vertex_textures_saved[i]; - ctx->vertex_textures_saved[i] = NULL; - } - for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - } - - ctx->pipe->set_vertex_sampler_textures(ctx->pipe, - ctx->nr_vertex_textures, - ctx->vertex_textures); - - ctx->nr_vertex_textures_saved = 0; -} - - - enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, const struct pipe_depth_stencil_alpha_state *templ) { @@ -1261,3 +1154,122 @@ void cso_restore_vertex_elements(struct cso_context *ctx) } ctx->velements_saved = NULL; } + +/* fragment sampler view state */ + +void +cso_set_fragment_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views) +{ + uint i; + + for (i = 0; i < count; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]); + } + for (; i < cso->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL); + } + + cso->pipe->set_fragment_sampler_views(cso->pipe, + MAX2(count, cso->nr_fragment_sampler_views), + cso->fragment_sampler_views); + + cso->nr_fragment_sampler_views = count; +} + +void +cso_save_fragment_sampler_views(struct cso_context *cso) +{ + uint i; + + cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views; + + for (i = 0; i < cso->nr_fragment_sampler_views; i++) { + assert(!cso->fragment_sampler_views_saved[i]); + + pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], + cso->fragment_sampler_views[i]); + } +} + +void +cso_restore_fragment_sampler_views(struct cso_context *cso) +{ + uint i; + + for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]); + pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL); + } + for (; i < cso->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL); + } + + cso->pipe->set_fragment_sampler_views(cso->pipe, + MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved), + cso->fragment_sampler_views); + + cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved; + cso->nr_fragment_sampler_views_saved = 0; +} + + +/* vertex sampler view state */ + +void +cso_set_vertex_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views) +{ + uint i; + + for (i = 0; i < count; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]); + } + for (; i < cso->nr_vertex_sampler_views; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL); + } + + cso->pipe->set_vertex_sampler_views(cso->pipe, + MAX2(count, cso->nr_vertex_sampler_views), + cso->vertex_sampler_views); + + cso->nr_vertex_sampler_views = count; +} + +void +cso_save_vertex_sampler_views(struct cso_context *cso) +{ + uint i; + + cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views; + + for (i = 0; i < cso->nr_vertex_sampler_views; i++) { + assert(!cso->vertex_sampler_views_saved[i]); + + pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], + cso->vertex_sampler_views[i]); + } +} + +void +cso_restore_vertex_sampler_views(struct cso_context *cso) +{ + uint i; + + for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]); + pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL); + } + for (; i < cso->nr_vertex_sampler_views; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL); + } + + cso->pipe->set_vertex_sampler_views(cso->pipe, + MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved), + cso->vertex_sampler_views); + + cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved; + cso->nr_vertex_sampler_views_saved = 0; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 9c16abd28dd..d6bcb1fe8f7 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -103,25 +103,6 @@ void cso_single_vertex_sampler_done(struct cso_context *cso); - -enum pipe_error 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 ); - - - -enum pipe_error -cso_set_vertex_sampler_textures(struct cso_context *cso, - uint count, - struct pipe_texture **textures); -void -cso_save_vertex_sampler_textures(struct cso_context *cso); -void -cso_restore_vertex_sampler_textures(struct cso_context *cso); - - enum pipe_error cso_set_vertex_elements(struct cso_context *ctx, unsigned count, const struct pipe_vertex_element *states); @@ -198,6 +179,34 @@ void cso_restore_clip(struct cso_context *cso); +/* fragment sampler view state */ + +void +cso_set_fragment_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views); + +void +cso_save_fragment_sampler_views(struct cso_context *cso); + +void +cso_restore_fragment_sampler_views(struct cso_context *cso); + + +/* vertex sampler view state */ + +void +cso_set_vertex_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views); + +void +cso_save_vertex_sampler_views(struct cso_context *cso); + +void +cso_restore_vertex_sampler_views(struct cso_context *cso); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 1c07ab13654..f4615064e65 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -40,6 +40,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" @@ -88,8 +89,9 @@ struct aaline_stage void *sampler_cso; struct pipe_texture *texture; + struct pipe_sampler_view *sampler_view; uint num_samplers; - uint num_textures; + uint num_sampler_views; /* @@ -98,7 +100,7 @@ struct aaline_stage struct aaline_fragment_shader *fs; struct { void *sampler[PIPE_MAX_SAMPLERS]; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; } state; /* @@ -111,8 +113,9 @@ struct aaline_stage void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); + void (*driver_set_sampler_views)(struct pipe_context *, + unsigned, + struct pipe_sampler_view **); struct pipe_context *pipe; }; @@ -394,6 +397,7 @@ aaline_create_texture(struct aaline_stage *aaline) struct pipe_context *pipe = aaline->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; + struct pipe_sampler_view viewTempl; uint level; memset(&texTemp, 0, sizeof(texTemp)); @@ -408,6 +412,16 @@ aaline_create_texture(struct aaline_stage *aaline) if (!aaline->texture) return FALSE; + u_sampler_view_default_template(&viewTempl, + aaline->texture, + aaline->texture->format); + aaline->sampler_view = pipe->create_sampler_view(pipe, + aaline->texture, + &viewTempl); + if (!aaline->sampler_view) { + return FALSE; + } + /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost * texels which are zero. Special case the 1x1 and 2x2 levels. @@ -669,16 +683,16 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); + num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers); num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; - pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], - aaline->texture); + pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit], + aaline->sampler_view); draw->suspend_flushing = TRUE; aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); + aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views); draw->suspend_flushing = FALSE; /* now really draw first line */ @@ -702,8 +716,9 @@ aaline_flush(struct draw_stage *stage, unsigned flags) aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, aaline->num_textures, - aaline->state.texture); + aaline->driver_set_sampler_views(pipe, + aaline->num_sampler_views, + aaline->state.sampler_views); draw->suspend_flushing = FALSE; draw->extra_shader_outputs.slot = 0; @@ -724,7 +739,7 @@ aaline_destroy(struct draw_stage *stage) uint i; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&aaline->state.texture[i], NULL); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); } if (aaline->sampler_cso) @@ -733,6 +748,10 @@ aaline_destroy(struct draw_stage *stage) if (aaline->texture) pipe_texture_reference(&aaline->texture, NULL); + if (aaline->sampler_view) { + pipe_sampler_view_reference(&aaline->sampler_view, NULL); + } + draw_free_temp_verts( stage ); FREE( stage ); @@ -844,23 +863,24 @@ aaline_bind_sampler_states(struct pipe_context *pipe, static void -aaline_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +aaline_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); uint i; /* save current */ for (i = 0; i < num; i++) { - pipe_texture_reference(&aaline->state.texture[i], texture[i]); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]); } for ( ; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&aaline->state.texture[i], NULL); + pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL); } - aaline->num_textures = num; + aaline->num_sampler_views = num; /* pass-through */ - aaline->driver_set_sampler_textures(aaline->pipe, num, texture); + aaline->driver_set_sampler_views(aaline->pipe, num, views); } @@ -898,7 +918,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) aaline->driver_delete_fs_state = pipe->delete_fs_state; aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; - aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; + aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views; /* override the driver's functions */ pipe->create_fs_state = aaline_create_fs_state; @@ -906,7 +926,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) pipe->delete_fs_state = aaline_delete_fs_state; pipe->bind_fragment_sampler_states = aaline_bind_sampler_states; - pipe->set_fragment_sampler_textures = aaline_set_sampler_textures; + pipe->set_fragment_sampler_views = aaline_set_sampler_views; /* Install once everything is known to be OK: */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 38c22bf4e94..794fd81d70f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -42,6 +42,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" @@ -75,8 +76,9 @@ struct pstip_stage void *sampler_cso; struct pipe_texture *texture; + struct pipe_sampler_view *sampler_view; uint num_samplers; - uint num_textures; + uint num_sampler_views; /* * Currently bound state @@ -84,7 +86,7 @@ struct pstip_stage struct pstip_fragment_shader *fs; struct { void *samplers[PIPE_MAX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; const struct pipe_poly_stipple *stipple; } state; @@ -98,8 +100,9 @@ struct pstip_stage void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); + void (*driver_set_sampler_views)(struct pipe_context *, + unsigned, + struct pipe_sampler_view **); void (*driver_set_polygon_stipple)(struct pipe_context *, const struct pipe_poly_stipple *); @@ -424,6 +427,7 @@ pstip_create_texture(struct pstip_stage *pstip) struct pipe_context *pipe = pstip->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; + struct pipe_sampler_view viewTempl; memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; @@ -437,6 +441,16 @@ pstip_create_texture(struct pstip_stage *pstip) if (pstip->texture == NULL) return FALSE; + u_sampler_view_default_template(&viewTempl, + pstip->texture, + pstip->texture->format); + pstip->sampler_view = pipe->create_sampler_view(pipe, + pstip->texture, + &viewTempl); + if (!pstip->sampler_view) { + return FALSE; + } + return TRUE; } @@ -515,19 +529,19 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); + num_samplers = MAX2(pstip->num_sampler_views, pstip->num_samplers); num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); /* plug in our sampler, texture */ pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; - pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], - pstip->texture); + pipe_sampler_view_reference(&pstip->state.sampler_views[pstip->fs->sampler_unit], + pstip->sampler_view); assert(num_samplers <= PIPE_MAX_SAMPLERS); draw->suspend_flushing = TRUE; pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); + pstip->driver_set_sampler_views(pipe, num_samplers, pstip->state.sampler_views); draw->suspend_flushing = FALSE; /* now really draw first triangle */ @@ -551,8 +565,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags) pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, pstip->num_textures, - pstip->state.textures); + pstip->driver_set_sampler_views(pipe, + pstip->num_sampler_views, + pstip->state.sampler_views); draw->suspend_flushing = FALSE; } @@ -571,13 +586,17 @@ pstip_destroy(struct draw_stage *stage) uint i; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&pstip->state.textures[i], NULL); + pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL); } pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); pipe_texture_reference(&pstip->texture, NULL); + if (pstip->sampler_view) { + pipe_sampler_view_reference(&pstip->sampler_view, NULL); + } + draw_free_temp_verts( stage ); FREE( stage ); } @@ -682,24 +701,25 @@ pstip_bind_sampler_states(struct pipe_context *pipe, static void -pstip_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +pstip_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); uint i; /* save current */ for (i = 0; i < num; i++) { - pipe_texture_reference(&pstip->state.textures[i], texture[i]); + pipe_sampler_view_reference(&pstip->state.sampler_views[i], views[i]); } for (; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&pstip->state.textures[i], NULL); + pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL); } - pstip->num_textures = num; + pstip->num_sampler_views = num; /* pass-through */ - pstip->driver_set_sampler_textures(pstip->pipe, num, texture); + pstip->driver_set_sampler_views(pstip->pipe, num, views); } @@ -756,7 +776,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->driver_delete_fs_state = pipe->delete_fs_state; pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; - pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; + pstip->driver_set_sampler_views = pipe->set_fragment_sampler_views; pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; /* override the driver's functions */ @@ -765,7 +785,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->delete_fs_state = pstip_delete_fs_state; pipe->bind_fragment_sampler_states = pstip_bind_sampler_states; - pipe->set_fragment_sampler_textures = pstip_set_sampler_textures; + pipe->set_fragment_sampler_views = pstip_set_sampler_views; pipe->set_polygon_stipple = pstip_set_polygon_stipple; return TRUE; diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 27099579618..1c7db0005a9 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -238,38 +238,15 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim ) unsigned output_format; unsigned src_offset = (vbuf->vinfo->attrib[i].src_index * 4 * sizeof(float) ); - switch (vbuf->vinfo->attrib[i].emit) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); + output_format = draw_translate_vinfo_format(vbuf->vinfo->attrib[i].emit); + emit_sz = draw_translate_vinfo_size(vbuf->vinfo->attrib[i].emit); + + /* doesn't handle EMIT_OMIT */ + assert(emit_sz != 0); + + if (vbuf->vinfo->attrib[i].emit == EMIT_1F_PSIZE) { src_buffer = 1; src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_A8R8G8B8_UNORM; - emit_sz = 4 * sizeof(ubyte); - break; - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; } hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL; diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index ae357b51226..a7917f54b04 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -86,40 +86,15 @@ void draw_pt_emit_prepare( struct pt_emit *emit, unsigned output_format; unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) ); + output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit); + emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit); - - switch (vinfo->attrib[i].emit) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); + /* doesn't handle EMIT_OMIT */ + assert(emit_sz != 0); + + if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) { src_buffer = 1; src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_A8R8G8B8_UNORM; - emit_sz = 4 * sizeof(ubyte); - break; - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; } hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 2a604470e9a..1994ddf2bcc 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -129,41 +129,16 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, unsigned input_offset = src->src_offset; unsigned output_format; - switch (vinfo->attrib[i].emit) { - case EMIT_4UB: - output_format = PIPE_FORMAT_R8G8B8A8_UNORM; - emit_sz = 4 * sizeof(unsigned char); - break; - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: + output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit); + emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit); + + if (vinfo->attrib[i].emit == EMIT_OMIT) + continue; + + if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) { input_format = PIPE_FORMAT_R32_FLOAT; input_buffer = draw->pt.nr_vertex_buffers; input_offset = 0; - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_OMIT: - continue; - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - continue; } key.element[i].type = TRANSLATE_ELEMENT_NORMAL; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 1aecb510777..389e2b105e5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -130,31 +130,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle, unsigned dst_offset = 0; for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - - switch (vinfo->attrib[i].emit) { - case EMIT_4F: - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - emit_sz = 1 * sizeof(float); - break; - case EMIT_4UB: - emit_sz = 4 * sizeof(ubyte); - break; - default: - assert(0); - break; - } + unsigned emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit); + + /* doesn't handle EMIT_OMIT */ + assert(emit_sz != 0); /* The elements in the key correspond to vertex shader output * numbers, not to positions in the hw vertex description -- diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index 3214213e445..a4f5e882c0a 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -48,30 +48,12 @@ draw_compute_vertex_size(struct vertex_info *vinfo) uint i; vinfo->size = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - switch (vinfo->attrib[i].emit) { - case EMIT_OMIT: - break; - case EMIT_4UB: - /* fall-through */ - case EMIT_1F_PSIZE: - /* fall-through */ - case EMIT_1F: - vinfo->size += 1; - break; - case EMIT_2F: - vinfo->size += 2; - break; - case EMIT_3F: - vinfo->size += 3; - break; - case EMIT_4F: - vinfo->size += 4; - break; - default: - assert(0); - } - } + for (i = 0; i < vinfo->num_attribs; i++) + vinfo->size += draw_translate_vinfo_size(vinfo->attrib[i].emit); + + assert(vinfo->size % 4 == 0); + /* in dwords */ + vinfo->size /= 4; } @@ -120,6 +102,13 @@ draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) debug_printf("%u ", *data++); debug_printf("%u ", *data++); break; + case EMIT_4UB_BGRA: + debug_printf("EMIT_4UB_BGRA:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; default: assert(0); } diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 8c3c7befbc7..ca272371267 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -54,7 +54,8 @@ enum attrib_emit { EMIT_2F, EMIT_3F, EMIT_4F, - EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */ + EMIT_4UB, /**< is RGBA like the rest */ + EMIT_4UB_BGRA }; @@ -141,9 +142,11 @@ void draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data); -static INLINE unsigned draw_translate_vinfo_format(unsigned format ) +static INLINE unsigned draw_translate_vinfo_format(enum attrib_emit emit) { - switch (format) { + switch (emit) { + case EMIT_OMIT: + return PIPE_FORMAT_NONE; case EMIT_1F: case EMIT_1F_PSIZE: return PIPE_FORMAT_R32_FLOAT; @@ -155,10 +158,36 @@ static INLINE unsigned draw_translate_vinfo_format(unsigned format ) return PIPE_FORMAT_R32G32B32A32_FLOAT; case EMIT_4UB: return PIPE_FORMAT_R8G8B8A8_UNORM; + case EMIT_4UB_BGRA: + return PIPE_FORMAT_B8G8R8A8_UNORM; default: + assert(!"unexpected format"); return PIPE_FORMAT_NONE; } } +static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit) +{ + switch (emit) { + case EMIT_OMIT: + return 0; + case EMIT_1F: + case EMIT_1F_PSIZE: + return 1 * sizeof(float); + case EMIT_2F: + return 2 * sizeof(float); + case EMIT_3F: + return 3 * sizeof(float); + case EMIT_4F: + return 4 * sizeof(float); + case EMIT_4UB: + return 4 * sizeof(unsigned char); + case EMIT_4UB_BGRA: + return 4 * sizeof(unsigned char); + default: + assert(!"unexpected format"); + return 0; + } +} #endif /* DRAW_VERTEX_H */ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index ece1ddde0cb..8f8bbe7cb88 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -401,13 +401,11 @@ static boolean emit_output( struct aos_compilation *cp, emit_store_R32G32B32A32(cp, ptr, dataXMM); break; case EMIT_4UB: - if (1) { - emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); - emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); - } - else { - emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); - } + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + break; + case EMIT_4UB_BGRA: + emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); break; default: AOS_ERROR(cp, "unhandled output format"); diff --git a/src/gallium/auxiliary/os/os_llvm.h b/src/gallium/auxiliary/gallivm/lp_bld.h index d5edfbfe923..70a4960f913 100644 --- a/src/gallium/auxiliary/os/os_llvm.h +++ b/src/gallium/auxiliary/gallivm/lp_bld.h @@ -31,8 +31,8 @@ */ -#ifndef OS_LLVM_H -#define OS_LLVM_H +#ifndef LP_BLD_H +#define LP_BLD_H #include <llvm-c/Core.h> @@ -40,8 +40,8 @@ /** Set version to 0 if missing to avoid #ifdef HAVE_LLVM everywhere */ #ifndef HAVE_LLVM -#define HAVE_LLVM 0x0 +#define HAVE_LLVM 0x0207 #endif -#endif /* OS_LLVM_H */ +#endif /* LP_BLD_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_alpha.h b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h index fe3cedcc48c..0f99fec65ed 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_alpha.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h @@ -35,7 +35,7 @@ #define LP_BLD_ALPHA_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct pipe_alpha_state; struct lp_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index 233a36669d4..8e8fcccf564 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -361,12 +361,12 @@ lp_build_mul_u8n(LLVMBuilderRef builder, LLVMValueRef c8; LLVMValueRef ab; - c8 = lp_build_int_const_scalar(i16_type, 8); + c8 = lp_build_const_int_vec(i16_type, 8); #if 0 /* a*b/255 ~= (a*(b + 1)) >> 256 */ - b = LLVMBuildAdd(builder, b, lp_build_int_const_scalar(i16_type, 1), ""); + b = LLVMBuildAdd(builder, b, lp_build_const_int_vec(i16_type, 1), ""); ab = LLVMBuildMul(builder, a, b, ""); #else @@ -374,7 +374,7 @@ lp_build_mul_u8n(LLVMBuilderRef builder, /* ab/255 ~= (ab + (ab >> 8) + 0x80) >> 8 */ ab = LLVMBuildMul(builder, a, b, ""); ab = LLVMBuildAdd(builder, ab, LLVMBuildLShr(builder, ab, c8, ""), ""); - ab = LLVMBuildAdd(builder, ab, lp_build_int_const_scalar(i16_type, 0x80), ""); + ab = LLVMBuildAdd(builder, ab, lp_build_const_int_vec(i16_type, 0x80), ""); #endif @@ -429,7 +429,7 @@ lp_build_mul(struct lp_build_context *bld, } if(type.fixed) - shift = lp_build_int_const_scalar(type, type.width/2); + shift = lp_build_const_int_vec(type, type.width/2); else shift = NULL; @@ -491,7 +491,7 @@ lp_build_mul_imm(struct lp_build_context *bld, * for Inf and NaN. */ unsigned mantissa = lp_mantissa(bld->type); - factor = lp_build_int_const_scalar(bld->type, (unsigned long long)shift << mantissa); + factor = lp_build_const_int_vec(bld->type, (unsigned long long)shift << mantissa); a = LLVMBuildBitCast(bld->builder, a, lp_build_int_vec_type(bld->type), ""); a = LLVMBuildAdd(bld->builder, a, factor, ""); a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(bld->type), ""); @@ -499,12 +499,12 @@ lp_build_mul_imm(struct lp_build_context *bld, #endif } else { - factor = lp_build_const_scalar(bld->type, shift); + factor = lp_build_const_vec(bld->type, shift); return LLVMBuildShl(bld->builder, a, factor, ""); } } - factor = lp_build_const_scalar(bld->type, (double)b); + factor = lp_build_const_vec(bld->type, (double)b); return lp_build_mul(bld, a, factor); } @@ -567,7 +567,7 @@ lp_build_lerp(struct lp_build_context *bld, * but it will be wrong for other uses. Basically we need a more * powerful lp_type, capable of further distinguishing the values * interpretation from the value storage. */ - res = LLVMBuildAnd(bld->builder, res, lp_build_int_const_scalar(bld->type, (1 << bld->type.width/2) - 1), ""); + res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(bld->type, (1 << bld->type.width/2) - 1), ""); return res; } @@ -689,7 +689,7 @@ lp_build_abs(struct lp_build_context *bld, /* vector of floats */ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); unsigned long long absMask = ~(1ULL << (type.width - 1)); - LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask)); + LLVMValueRef mask = lp_build_const_int_vec(type, ((unsigned long long) absMask)); a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); a = LLVMBuildAnd(bld->builder, a, mask, ""); a = LLVMBuildBitCast(bld->builder, a, vec_type, ""); @@ -751,7 +751,7 @@ lp_build_sgn(struct lp_build_context *bld, /* vector */ int_type = lp_build_int_vec_type(type); vec_type = lp_build_vec_type(type); - mask = lp_build_int_const_scalar(type, maskBit); + mask = lp_build_const_int_vec(type, maskBit); } /* Take the sign bit and add it to 1 constant */ @@ -763,7 +763,7 @@ lp_build_sgn(struct lp_build_context *bld, } else { - LLVMValueRef minus_one = lp_build_const_scalar(type, -1.0); + LLVMValueRef minus_one = lp_build_const_vec(type, -1.0); cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero); res = lp_build_select(bld, cond, bld->one, minus_one); } @@ -789,8 +789,8 @@ lp_build_set_sign(struct lp_build_context *bld, const struct lp_type type = bld->type; LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); LLVMTypeRef vec_type = lp_build_vec_type(type); - LLVMValueRef shift = lp_build_int_const_scalar(type, type.width - 1); - LLVMValueRef mask = lp_build_int_const_scalar(type, + LLVMValueRef shift = lp_build_const_int_vec(type, type.width - 1); + LLVMValueRef mask = lp_build_const_int_vec(type, ~((unsigned long long) 1 << (type.width - 1))); LLVMValueRef val, res; @@ -1034,7 +1034,7 @@ lp_build_iround(struct lp_build_context *bld, } else { LLVMTypeRef vec_type = lp_build_vec_type(type); - LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1)); + LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1)); LLVMValueRef sign; LLVMValueRef half; @@ -1043,7 +1043,7 @@ lp_build_iround(struct lp_build_context *bld, sign = LLVMBuildAnd(bld->builder, sign, mask, ""); /* sign * 0.5 */ - half = lp_build_const_scalar(type, 0.5); + half = lp_build_const_vec(type, 0.5); half = LLVMBuildBitCast(bld->builder, half, int_vec_type, ""); half = LLVMBuildOr(bld->builder, sign, half, ""); half = LLVMBuildBitCast(bld->builder, half, vec_type, ""); @@ -1086,18 +1086,18 @@ lp_build_ifloor(struct lp_build_context *bld, /* Take the sign bit and add it to 1 constant */ LLVMTypeRef vec_type = lp_build_vec_type(type); unsigned mantissa = lp_mantissa(type); - LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1)); + LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1)); LLVMValueRef sign; LLVMValueRef offset; /* sign = a < 0 ? ~0 : 0 */ sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); sign = LLVMBuildAnd(bld->builder, sign, mask, ""); - sign = LLVMBuildAShr(bld->builder, sign, lp_build_int_const_scalar(type, type.width - 1), ""); + sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), ""); lp_build_name(sign, "floor.sign"); /* offset = -0.99999(9)f */ - offset = lp_build_const_scalar(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa)); + offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa)); offset = LLVMConstBitCast(offset, int_vec_type); /* offset = a < 0 ? -0.99999(9)f : 0.0f */ @@ -1268,7 +1268,7 @@ lp_build_exp(struct lp_build_context *bld, LLVMValueRef x) { /* log2(e) = 1/log(2) */ - LLVMValueRef log2e = lp_build_const_scalar(bld->type, 1.4426950408889634); + LLVMValueRef log2e = lp_build_const_vec(bld->type, 1.4426950408889634); return lp_build_mul(bld, log2e, lp_build_exp2(bld, x)); } @@ -1282,7 +1282,7 @@ lp_build_log(struct lp_build_context *bld, LLVMValueRef x) { /* log(2) */ - LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529); + LLVMValueRef log2 = lp_build_const_vec(bld->type, 0.69314718055994529); return lp_build_mul(bld, log2, lp_build_exp2(bld, x)); } @@ -1318,7 +1318,7 @@ lp_build_polynomial(struct lp_build_context *bld, if (type.length == 1) coeff = LLVMConstReal(float_type, coeffs[i]); else - coeff = lp_build_const_scalar(type, coeffs[i]); + coeff = lp_build_const_vec(type, coeffs[i]); if(res) res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res)); @@ -1375,11 +1375,11 @@ lp_build_exp2_approx(struct lp_build_context *bld, assert(type.floating && type.width == 32); - x = lp_build_min(bld, x, lp_build_const_scalar(type, 129.0)); - x = lp_build_max(bld, x, lp_build_const_scalar(type, -126.99999)); + x = lp_build_min(bld, x, lp_build_const_vec(type, 129.0)); + x = lp_build_max(bld, x, lp_build_const_vec(type, -126.99999)); /* ipart = int(x - 0.5) */ - ipart = LLVMBuildSub(bld->builder, x, lp_build_const_scalar(type, 0.5f), ""); + ipart = LLVMBuildSub(bld->builder, x, lp_build_const_vec(type, 0.5f), ""); ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, ""); /* fpart = x - ipart */ @@ -1389,8 +1389,8 @@ lp_build_exp2_approx(struct lp_build_context *bld, if(p_exp2_int_part || p_exp2) { /* expipart = (float) (1 << ipart) */ - expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_int_const_scalar(type, 127), ""); - expipart = LLVMBuildShl(bld->builder, expipart, lp_build_int_const_scalar(type, 23), ""); + expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_const_int_vec(type, 127), ""); + expipart = LLVMBuildShl(bld->builder, expipart, lp_build_const_int_vec(type, 23), ""); expipart = LLVMBuildBitCast(bld->builder, expipart, vec_type, ""); } @@ -1456,8 +1456,8 @@ lp_build_log2_approx(struct lp_build_context *bld, LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); - LLVMValueRef expmask = lp_build_int_const_scalar(type, 0x7f800000); - LLVMValueRef mantmask = lp_build_int_const_scalar(type, 0x007fffff); + LLVMValueRef expmask = lp_build_const_int_vec(type, 0x7f800000); + LLVMValueRef mantmask = lp_build_const_int_vec(type, 0x007fffff); LLVMValueRef one = LLVMConstBitCast(bld->one, int_vec_type); LLVMValueRef i = NULL; @@ -1482,8 +1482,8 @@ lp_build_log2_approx(struct lp_build_context *bld, } if(p_floor_log2 || p_log2) { - logexp = LLVMBuildLShr(bld->builder, exp, lp_build_int_const_scalar(type, 23), ""); - logexp = LLVMBuildSub(bld->builder, logexp, lp_build_int_const_scalar(type, 127), ""); + logexp = LLVMBuildLShr(bld->builder, exp, lp_build_const_int_vec(type, 23), ""); + logexp = LLVMBuildSub(bld->builder, logexp, lp_build_const_int_vec(type, 127), ""); logexp = LLVMBuildSIToFP(bld->builder, logexp, vec_type, ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h index 7a10fe12209..31efa9921ce 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h @@ -37,7 +37,7 @@ #define LP_BLD_ARIT_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_blend.h b/src/gallium/auxiliary/gallivm/lp_bld_blend.h index 5a9e1c1fb2f..ebbdb1a604c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_blend.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_blend.h @@ -40,7 +40,7 @@ * for a standalone example. */ -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "pipe/p_format.h" diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c index 8a275fa72f3..57843e9a60c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_const.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c @@ -263,7 +263,7 @@ lp_build_one(struct lp_type type) if(type.sign) /* TODO: Unfortunately this caused "Tried to create a shift operation * on a non-integer type!" */ - vec = LLVMConstLShr(vec, lp_build_int_const_scalar(type, 1)); + vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1)); #endif return vec; @@ -283,8 +283,8 @@ lp_build_one(struct lp_type type) * Build constant-valued vector from a scalar value. */ LLVMValueRef -lp_build_const_scalar(struct lp_type type, - double val) +lp_build_const_vec(struct lp_type type, + double val) { LLVMTypeRef elem_type = lp_build_elem_type(type); LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; @@ -309,7 +309,7 @@ lp_build_const_scalar(struct lp_type type, LLVMValueRef -lp_build_int_const_scalar(struct lp_type type, +lp_build_const_int_vec(struct lp_type type, long long val) { LLVMTypeRef elem_type = lp_build_int_elem_type(type); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h index 40786361031..9ca2f0664eb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_const.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h @@ -37,9 +37,9 @@ #define LP_BLD_CONST_H -#include "os/os_llvm.h" +#include "pipe/p_compiler.h" +#include "gallivm/lp_bld.h" -#include <pipe/p_compiler.h> struct lp_type; @@ -85,13 +85,11 @@ lp_build_one(struct lp_type type); LLVMValueRef -lp_build_const_scalar(struct lp_type type, - double val); +lp_build_const_vec(struct lp_type type, double val); LLVMValueRef -lp_build_int_const_scalar(struct lp_type type, - long long val); +lp_build_const_int_vec(struct lp_type type, long long val); LLVMValueRef diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c index f77cf787213..3f7f2ebde9c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c @@ -114,13 +114,13 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, scale = (double)mask/ubound; bias = (double)((unsigned long long)1 << (mantissa - n)); - res = LLVMBuildMul(builder, src, lp_build_const_scalar(src_type, scale), ""); - res = LLVMBuildAdd(builder, res, lp_build_const_scalar(src_type, bias), ""); + res = LLVMBuildMul(builder, src, lp_build_const_vec(src_type, scale), ""); + res = LLVMBuildAdd(builder, res, lp_build_const_vec(src_type, bias), ""); res = LLVMBuildBitCast(builder, res, int_vec_type, ""); if(dst_width > n) { int shift = dst_width - n; - res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), ""); + res = LLVMBuildShl(builder, res, lp_build_const_int_vec(src_type, shift), ""); /* TODO: Fill in the empty lower bits for additional precision? */ /* YES: this fixes progs/trivial/tri-z-eq.c. @@ -130,21 +130,21 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, #if 0 { LLVMValueRef msb; - msb = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, dst_width - 1), ""); - msb = LLVMBuildShl(builder, msb, lp_build_int_const_scalar(src_type, shift), ""); - msb = LLVMBuildSub(builder, msb, lp_build_int_const_scalar(src_type, 1), ""); + msb = LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, dst_width - 1), ""); + msb = LLVMBuildShl(builder, msb, lp_build_const_int_vec(src_type, shift), ""); + msb = LLVMBuildSub(builder, msb, lp_build_const_int_vec(src_type, 1), ""); res = LLVMBuildOr(builder, res, msb, ""); } #elif 0 while(shift > 0) { - res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, n), ""), ""); + res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, n), ""), ""); shift -= n; n *= 2; } #endif } else - res = LLVMBuildAnd(builder, res, lp_build_int_const_scalar(src_type, mask), ""); + res = LLVMBuildAnd(builder, res, lp_build_const_int_vec(src_type, mask), ""); return res; } @@ -183,10 +183,10 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder, if(src_width > mantissa) { int shift = src_width - mantissa; - res = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(dst_type, shift), ""); + res = LLVMBuildLShr(builder, res, lp_build_const_int_vec(dst_type, shift), ""); } - bias_ = lp_build_const_scalar(dst_type, bias); + bias_ = lp_build_const_vec(dst_type, bias); res = LLVMBuildOr(builder, res, @@ -195,7 +195,7 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder, res = LLVMBuildBitCast(builder, res, vec_type, ""); res = LLVMBuildSub(builder, res, bias_, ""); - res = LLVMBuildMul(builder, res, lp_build_const_scalar(dst_type, scale), ""); + res = LLVMBuildMul(builder, res, lp_build_const_vec(dst_type, scale), ""); return res; } @@ -251,7 +251,7 @@ lp_build_conv(LLVMBuilderRef builder, if(dst_min == 0.0) thres = bld.zero; else - thres = lp_build_const_scalar(src_type, dst_min); + thres = lp_build_const_vec(src_type, dst_min); for(i = 0; i < num_tmps; ++i) tmp[i] = lp_build_max(&bld, tmp[i], thres); } @@ -260,7 +260,7 @@ lp_build_conv(LLVMBuilderRef builder, if(dst_max == 1.0) thres = bld.one; else - thres = lp_build_const_scalar(src_type, dst_max); + thres = lp_build_const_vec(src_type, dst_max); for(i = 0; i < num_tmps; ++i) tmp[i] = lp_build_min(&bld, tmp[i], thres); } @@ -288,7 +288,7 @@ lp_build_conv(LLVMBuilderRef builder, LLVMTypeRef tmp_vec_type; if (dst_scale != 1.0) { - LLVMValueRef scale = lp_build_const_scalar(tmp_type, dst_scale); + LLVMValueRef scale = lp_build_const_vec(tmp_type, dst_scale); for(i = 0; i < num_tmps; ++i) tmp[i] = LLVMBuildMul(builder, tmp[i], scale, ""); } @@ -315,7 +315,7 @@ lp_build_conv(LLVMBuilderRef builder, /* FIXME: compensate different offsets too */ if(src_shift > dst_shift) { - LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, src_shift - dst_shift); + LLVMValueRef shift = lp_build_const_int_vec(tmp_type, src_shift - dst_shift); for(i = 0; i < num_tmps; ++i) if(src_type.sign) tmp[i] = LLVMBuildAShr(builder, tmp[i], shift, ""); @@ -388,7 +388,7 @@ lp_build_conv(LLVMBuilderRef builder, } if (src_scale != 1.0) { - LLVMValueRef scale = lp_build_const_scalar(tmp_type, 1.0/src_scale); + LLVMValueRef scale = lp_build_const_vec(tmp_type, 1.0/src_scale); for(i = 0; i < num_tmps; ++i) tmp[i] = LLVMBuildMul(builder, tmp[i], scale, ""); } @@ -400,7 +400,7 @@ lp_build_conv(LLVMBuilderRef builder, /* FIXME: compensate different offsets too */ if(src_shift < dst_shift) { - LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, dst_shift - src_shift); + LLVMValueRef shift = lp_build_const_int_vec(tmp_type, dst_shift - src_shift); for(i = 0; i < num_tmps; ++i) tmp[i] = LLVMBuildShl(builder, tmp[i], shift, ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.h b/src/gallium/auxiliary/gallivm/lp_bld_conv.h index 78e8155ff73..628831c3ada 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.h @@ -37,7 +37,7 @@ #define LP_BLD_CONV_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h index 441ad94786f..7b010cbdb09 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h @@ -30,7 +30,7 @@ #define LP_BLD_DEBUG_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "pipe/p_compiler.h" #include "util/u_string.h" diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c index f08f8eb6d8b..4ce1a27a061 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_depth.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.c @@ -52,7 +52,14 @@ * Z31 Z32 Z41 Z42 Z33 Z34 Z43 Z44 ... * ... ... ... ... ... ... ... ... ... * - * FIXME: Code generate stencil test + * + * Stencil test: + * Two-sided stencil test is supported but probably not as efficient as + * it could be. Currently, we use if/then/else constructs to do the + * operations for front vs. back-facing polygons. We could probably do + * both the front and back arithmetic then use a Select() instruction to + * choose the result depending on polyon orientation. We'd have to + * measure performance both ways and see which is better. * * @author Jose Fonseca <[email protected]> */ @@ -61,11 +68,264 @@ #include "util/u_format.h" #include "lp_bld_type.h" +#include "lp_bld_arit.h" #include "lp_bld_const.h" #include "lp_bld_logic.h" #include "lp_bld_flow.h" #include "lp_bld_debug.h" #include "lp_bld_depth.h" +#include "lp_bld_swizzle.h" + + +/** Used to select fields from pipe_stencil_state */ +enum stencil_op { + S_FAIL_OP, + Z_FAIL_OP, + Z_PASS_OP +}; + + + +/** + * Do the stencil test comparison (compare FB stencil values against ref value). + * This will be used twice when generating two-sided stencil code. + * \param stencil the front/back stencil state + * \param stencilRef the stencil reference value, replicated as a vector + * \param stencilVals vector of stencil values from framebuffer + * \return vector mask of pass/fail values (~0 or 0) + */ +static LLVMValueRef +lp_build_stencil_test_single(struct lp_build_context *bld, + const struct pipe_stencil_state *stencil, + LLVMValueRef stencilRef, + LLVMValueRef stencilVals) +{ + const unsigned stencilMax = 255; /* XXX fix */ + struct lp_type type = bld->type; + LLVMValueRef res; + + assert(type.sign); + + assert(stencil->enabled); + + if (stencil->valuemask != stencilMax) { + /* compute stencilRef = stencilRef & valuemask */ + LLVMValueRef valuemask = lp_build_const_int_vec(type, stencil->valuemask); + stencilRef = LLVMBuildAnd(bld->builder, stencilRef, valuemask, ""); + /* compute stencilVals = stencilVals & valuemask */ + stencilVals = LLVMBuildAnd(bld->builder, stencilVals, valuemask, ""); + } + + res = lp_build_cmp(bld, stencil->func, stencilVals, stencilRef); + + return res; +} + + +/** + * Do the one or two-sided stencil test comparison. + * \sa lp_build_stencil_test_single + * \param face an integer indicating front (+) or back (-) facing polygon. + * If NULL, assume front-facing. + */ +static LLVMValueRef +lp_build_stencil_test(struct lp_build_context *bld, + const struct pipe_stencil_state stencil[2], + LLVMValueRef stencilRefs[2], + LLVMValueRef stencilVals, + LLVMValueRef face) +{ + LLVMValueRef res; + + assert(stencil[0].enabled); + + if (stencil[1].enabled && face) { + /* do two-sided test */ + struct lp_build_flow_context *flow_ctx; + struct lp_build_if_state if_ctx; + LLVMValueRef front_facing; + LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0); + LLVMValueRef result = bld->undef; + + flow_ctx = lp_build_flow_create(bld->builder); + lp_build_flow_scope_begin(flow_ctx); + + lp_build_flow_scope_declare(flow_ctx, &result); + + /* front_facing = face > 0.0 */ + front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, ""); + + lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing); + { + result = lp_build_stencil_test_single(bld, &stencil[0], + stencilRefs[0], stencilVals); + } + lp_build_else(&if_ctx); + { + result = lp_build_stencil_test_single(bld, &stencil[1], + stencilRefs[1], stencilVals); + } + lp_build_endif(&if_ctx); + + lp_build_flow_scope_end(flow_ctx); + lp_build_flow_destroy(flow_ctx); + + res = result; + } + else { + /* do single-side test */ + res = lp_build_stencil_test_single(bld, &stencil[0], + stencilRefs[0], stencilVals); + } + + return res; +} + + +/** + * Apply the stencil operator (add/sub/keep/etc) to the given vector + * of stencil values. + * \return new stencil values vector + */ +static LLVMValueRef +lp_build_stencil_op_single(struct lp_build_context *bld, + const struct pipe_stencil_state *stencil, + enum stencil_op op, + LLVMValueRef stencilRef, + LLVMValueRef stencilVals, + LLVMValueRef mask) + +{ + const unsigned stencilMax = 255; /* XXX fix */ + struct lp_type type = bld->type; + LLVMValueRef res; + LLVMValueRef max = lp_build_const_int_vec(type, stencilMax); + unsigned stencil_op; + + assert(type.sign); + + switch (op) { + case S_FAIL_OP: + stencil_op = stencil->fail_op; + break; + case Z_FAIL_OP: + stencil_op = stencil->zfail_op; + break; + case Z_PASS_OP: + stencil_op = stencil->zpass_op; + break; + default: + assert(0 && "Invalid stencil_op mode"); + stencil_op = PIPE_STENCIL_OP_KEEP; + } + + switch (stencil_op) { + case PIPE_STENCIL_OP_KEEP: + res = stencilVals; + /* we can return early for this case */ + return res; + case PIPE_STENCIL_OP_ZERO: + res = bld->zero; + break; + case PIPE_STENCIL_OP_REPLACE: + res = stencilRef; + break; + case PIPE_STENCIL_OP_INCR: + res = lp_build_add(bld, stencilVals, bld->one); + res = lp_build_min(bld, res, max); + break; + case PIPE_STENCIL_OP_DECR: + res = lp_build_sub(bld, stencilVals, bld->one); + res = lp_build_max(bld, res, bld->zero); + break; + case PIPE_STENCIL_OP_INCR_WRAP: + res = lp_build_add(bld, stencilVals, bld->one); + res = LLVMBuildAnd(bld->builder, res, max, ""); + break; + case PIPE_STENCIL_OP_DECR_WRAP: + res = lp_build_sub(bld, stencilVals, bld->one); + res = LLVMBuildAnd(bld->builder, res, max, ""); + break; + case PIPE_STENCIL_OP_INVERT: + res = LLVMBuildNot(bld->builder, stencilVals, ""); + res = LLVMBuildAnd(bld->builder, res, max, ""); + break; + default: + assert(0 && "bad stencil op mode"); + res = NULL; + } + + if (stencil->writemask != stencilMax) { + /* compute res = (res & mask) | (stencilVals & ~mask) */ + LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask); + LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask"); + LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1"); + LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2"); + res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2"); + } + + /* only the update the vector elements enabled by 'mask' */ + res = lp_build_select(bld, mask, res, stencilVals); + + return res; +} + + +/** + * Do the one or two-sided stencil test op/update. + */ +static LLVMValueRef +lp_build_stencil_op(struct lp_build_context *bld, + const struct pipe_stencil_state stencil[2], + enum stencil_op op, + LLVMValueRef stencilRefs[2], + LLVMValueRef stencilVals, + LLVMValueRef mask, + LLVMValueRef face) + +{ + assert(stencil[0].enabled); + + if (stencil[1].enabled && face) { + /* do two-sided op */ + struct lp_build_flow_context *flow_ctx; + struct lp_build_if_state if_ctx; + LLVMValueRef front_facing; + LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0); + LLVMValueRef result = bld->undef; + + flow_ctx = lp_build_flow_create(bld->builder); + lp_build_flow_scope_begin(flow_ctx); + + lp_build_flow_scope_declare(flow_ctx, &result); + + /* front_facing = face > 0.0 */ + front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, ""); + + lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing); + { + result = lp_build_stencil_op_single(bld, &stencil[0], op, + stencilRefs[0], stencilVals, mask); + } + lp_build_else(&if_ctx); + { + result = lp_build_stencil_op_single(bld, &stencil[1], op, + stencilRefs[1], stencilVals, mask); + } + lp_build_endif(&if_ctx); + + lp_build_flow_scope_end(flow_ctx); + lp_build_flow_destroy(flow_ctx); + + return result; + } + else { + /* do single-sided op */ + return lp_build_stencil_op_single(bld, &stencil[0], op, + stencilRefs[0], stencilVals, mask); + } +} + /** @@ -109,105 +369,303 @@ lp_depth_type(const struct util_format_description *format_desc, /** - * Depth test. + * Compute bitmask and bit shift to apply to the incoming fragment Z values + * and the Z buffer values needed before doing the Z comparison. + * + * Note that we leave the Z bits in the position that we find them + * in the Z buffer (typically 0xffffff00 or 0x00ffffff). That lets us + * get by with fewer bit twiddling steps. */ -void -lp_build_depth_test(LLVMBuilderRef builder, - const struct pipe_depth_state *state, - struct lp_type type, - const struct util_format_description *format_desc, - struct lp_build_mask_context *mask, - LLVMValueRef src, - LLVMValueRef dst_ptr) +static boolean +get_z_shift_and_mask(const struct util_format_description *format_desc, + unsigned *shift, unsigned *mask) { - struct lp_build_context bld; + const unsigned total_bits = format_desc->block.bits; unsigned z_swizzle; - LLVMValueRef dst; - LLVMValueRef z_bitmask = NULL; - LLVMValueRef test; - - if(!state->enabled) - return; - + int chan; + unsigned padding_left, padding_right; + assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); assert(format_desc->block.width == 1); assert(format_desc->block.height == 1); z_swizzle = format_desc->swizzle[0]; - if(z_swizzle == UTIL_FORMAT_SWIZZLE_NONE) - return; - /* Sanity checking */ - assert(z_swizzle < 4); - assert(format_desc->block.bits == type.width); - if(type.floating) { - assert(z_swizzle == 0); - assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_FLOAT); - assert(format_desc->channel[z_swizzle].size == format_desc->block.bits); + if (z_swizzle == UTIL_FORMAT_SWIZZLE_NONE) + return FALSE; + + padding_right = 0; + for (chan = 0; chan < z_swizzle; ++chan) + padding_right += format_desc->channel[chan].size; + + padding_left = + total_bits - (padding_right + format_desc->channel[z_swizzle].size); + + if (padding_left || padding_right) { + unsigned long long mask_left = (1ULL << (total_bits - padding_left)) - 1; + unsigned long long mask_right = (1ULL << (padding_right)) - 1; + *mask = mask_left ^ mask_right; } else { - assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED); - assert(format_desc->channel[z_swizzle].normalized); - assert(!type.fixed); - assert(!type.sign); - assert(type.norm); + *mask = 0xffffffff; + } + + *shift = padding_left; + + return TRUE; +} + + +/** + * Compute bitmask and bit shift to apply to the framebuffer pixel values + * to put the stencil bits in the least significant position. + * (i.e. 0x000000ff) + */ +static boolean +get_s_shift_and_mask(const struct util_format_description *format_desc, + unsigned *shift, unsigned *mask) +{ + unsigned s_swizzle; + int chan, sz; + + s_swizzle = format_desc->swizzle[1]; + + if (s_swizzle == UTIL_FORMAT_SWIZZLE_NONE) + return FALSE; + + *shift = 0; + for (chan = 0; chan < s_swizzle; chan++) + *shift += format_desc->channel[chan].size; + + sz = format_desc->channel[s_swizzle].size; + *mask = (1U << sz) - 1U; + + return TRUE; +} + + + +/** + * Generate code for performing depth and/or stencil tests. + * We operate on a vector of values (typically a 2x2 quad). + * + * \param depth the depth test state + * \param stencil the front/back stencil state + * \param type the data type of the fragment depth/stencil values + * \param format_desc description of the depth/stencil surface + * \param mask the alive/dead pixel mask for the quad (vector) + * \param stencil_refs the front/back stencil ref values (scalar) + * \param z_src the incoming depth/stencil values (a 2x2 quad) + * \param zs_dst_ptr pointer to depth/stencil values in framebuffer + * \param facing contains float value indicating front/back facing polygon + */ +void +lp_build_depth_stencil_test(LLVMBuilderRef builder, + const struct pipe_depth_state *depth, + const struct pipe_stencil_state stencil[2], + struct lp_type type, + const struct util_format_description *format_desc, + struct lp_build_mask_context *mask, + LLVMValueRef stencil_refs[2], + LLVMValueRef z_src, + LLVMValueRef zs_dst_ptr, + LLVMValueRef face) +{ + struct lp_build_context bld; + struct lp_build_context sbld; + struct lp_type s_type; + LLVMValueRef zs_dst, z_dst = NULL; + LLVMValueRef stencil_vals = NULL; + LLVMValueRef z_bitmask = NULL, stencil_shift = NULL; + LLVMValueRef z_pass = NULL, s_pass_mask = NULL; + LLVMValueRef orig_mask = mask->value; + + /* Sanity checking */ + { + const unsigned z_swizzle = format_desc->swizzle[0]; + const unsigned s_swizzle = format_desc->swizzle[1]; + + assert(z_swizzle != UTIL_FORMAT_SWIZZLE_NONE || + s_swizzle != UTIL_FORMAT_SWIZZLE_NONE); + + assert(depth->enabled || stencil[0].enabled); + + assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS); + assert(format_desc->block.width == 1); + assert(format_desc->block.height == 1); + + if (stencil[0].enabled) { + assert(format_desc->format == PIPE_FORMAT_Z24S8_UNORM || + format_desc->format == PIPE_FORMAT_S8Z24_UNORM); + } + + assert(z_swizzle < 4); + assert(format_desc->block.bits == type.width); + if (type.floating) { + assert(z_swizzle == 0); + assert(format_desc->channel[z_swizzle].type == + UTIL_FORMAT_TYPE_FLOAT); + assert(format_desc->channel[z_swizzle].size == + format_desc->block.bits); + } + else { + assert(format_desc->channel[z_swizzle].type == + UTIL_FORMAT_TYPE_UNSIGNED); + assert(format_desc->channel[z_swizzle].normalized); + assert(!type.fixed); + assert(!type.sign); + assert(type.norm); + } } - /* Setup build context */ + + /* Setup build context for Z vals */ lp_build_context_init(&bld, builder, type); - dst = LLVMBuildLoad(builder, dst_ptr, ""); + /* Setup build context for stencil vals */ + s_type = lp_type_int_vec(type.width); + lp_build_context_init(&sbld, builder, s_type); + + /* Load current z/stencil value from z/stencil buffer */ + zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, ""); + + lp_build_name(zs_dst, "zsbufval"); - lp_build_name(dst, "zsbuf"); - /* Align the source depth bits with the destination's, and mask out any - * stencil or padding bits from both */ - if(format_desc->channel[z_swizzle].size == format_desc->block.bits) { - assert(z_swizzle == 0); - /* nothing to do */ + /* Compute and apply the Z/stencil bitmasks and shifts. + */ + { + unsigned z_shift, z_mask; + unsigned s_shift, s_mask; + + if (get_z_shift_and_mask(format_desc, &z_shift, &z_mask)) { + if (z_shift) { + LLVMValueRef shift = lp_build_const_int_vec(type, z_shift); + z_src = LLVMBuildLShr(builder, z_src, shift, ""); + } + + if (z_mask != 0xffffffff) { + LLVMValueRef mask = lp_build_const_int_vec(type, z_mask); + z_src = LLVMBuildAnd(builder, z_src, mask, ""); + z_dst = LLVMBuildAnd(builder, zs_dst, mask, ""); + z_bitmask = mask; /* used below */ + } + else { + z_dst = zs_dst; + } + + lp_build_name(z_dst, "zsbuf.z"); + } + + if (get_s_shift_and_mask(format_desc, &s_shift, &s_mask)) { + if (s_shift) { + LLVMValueRef shift = lp_build_const_int_vec(type, s_shift); + stencil_vals = LLVMBuildLShr(builder, zs_dst, shift, ""); + stencil_shift = shift; /* used below */ + } + else { + stencil_vals = zs_dst; + } + + if (s_mask != 0xffffffff) { + LLVMValueRef mask = lp_build_const_int_vec(type, s_mask); + stencil_vals = LLVMBuildAnd(builder, stencil_vals, mask, ""); + } + + lp_build_name(stencil_vals, "stencil"); + } } - else { - unsigned padding_left; - unsigned padding_right; - unsigned chan; - - assert(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN); - assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED); - assert(format_desc->channel[z_swizzle].size <= format_desc->block.bits); - assert(format_desc->channel[z_swizzle].normalized); - - padding_right = 0; - for(chan = 0; chan < z_swizzle; ++chan) - padding_right += format_desc->channel[chan].size; - padding_left = format_desc->block.bits - - (padding_right + format_desc->channel[z_swizzle].size); - - if(padding_left || padding_right) { - const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1; - const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1; - z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right); + + + if (stencil[0].enabled) { + /* convert scalar stencil refs into vectors */ + stencil_refs[0] = lp_build_broadcast_scalar(&bld, stencil_refs[0]); + stencil_refs[1] = lp_build_broadcast_scalar(&bld, stencil_refs[1]); + + s_pass_mask = lp_build_stencil_test(&sbld, stencil, + stencil_refs, stencil_vals, face); + + /* apply stencil-fail operator */ + { + LLVMValueRef s_fail_mask = lp_build_andc(&bld, orig_mask, s_pass_mask); + stencil_vals = lp_build_stencil_op(&sbld, stencil, S_FAIL_OP, + stencil_refs, stencil_vals, + s_fail_mask, face); + } + } + + if (depth->enabled) { + /* compare src Z to dst Z, returning 'pass' mask */ + z_pass = lp_build_cmp(&bld, depth->func, z_src, z_dst); + + if (!stencil[0].enabled) { + /* We can potentially skip all remaining operations here, but only + * if stencil is disabled because we still need to update the stencil + * buffer values. Don't need to update Z buffer values. + */ + lp_build_mask_update(mask, z_pass); + } + + if (depth->writemask) { + if(z_bitmask) + z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, ""); + else + z_bitmask = mask->value; + + z_dst = lp_build_select(&bld, z_bitmask, z_src, z_dst); } - if(padding_left) - src = LLVMBuildLShr(builder, src, lp_build_int_const_scalar(type, padding_left), ""); - if(padding_right) - src = LLVMBuildAnd(builder, src, z_bitmask, ""); - if(padding_left || padding_right) - dst = LLVMBuildAnd(builder, dst, z_bitmask, ""); + if (stencil[0].enabled) { + /* update stencil buffer values according to z pass/fail result */ + LLVMValueRef z_fail_mask, z_pass_mask; + + /* apply Z-fail operator */ + z_fail_mask = lp_build_andc(&bld, orig_mask, z_pass); + stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_FAIL_OP, + stencil_refs, stencil_vals, + z_fail_mask, face); + + /* apply Z-pass operator */ + z_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, z_pass, ""); + stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP, + stencil_refs, stencil_vals, + z_pass_mask, face); + } + } + else { + /* No depth test: apply Z-pass operator to stencil buffer values which + * passed the stencil test. + */ + s_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, s_pass_mask, ""); + stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP, + stencil_refs, stencil_vals, + s_pass_mask, face); } - lp_build_name(dst, "zsbuf.z"); + /* The Z bits are already in the right place but we may need to shift the + * stencil bits before ORing Z with Stencil to make the final pixel value. + */ + if (stencil_vals && stencil_shift) + stencil_vals = LLVMBuildShl(bld.builder, stencil_vals, + stencil_shift, ""); - test = lp_build_cmp(&bld, state->func, src, dst); - lp_build_mask_update(mask, test); + /* Finally, merge/store the z/stencil values */ + if ((depth->enabled && depth->writemask) || + (stencil[0].enabled && stencil[0].writemask)) { - if(state->writemask) { - if(z_bitmask) - z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, ""); + if (z_dst && stencil_vals) + zs_dst = LLVMBuildOr(bld.builder, z_dst, stencil_vals, ""); + else if (z_dst) + zs_dst = z_dst; else - z_bitmask = mask->value; + zs_dst = stencil_vals; - dst = lp_build_select(&bld, z_bitmask, src, dst); - LLVMBuildStore(builder, dst, dst_ptr); + LLVMBuildStore(builder, zs_dst, zs_dst_ptr); } + + if (s_pass_mask) + lp_build_mask_update(mask, s_pass_mask); + + if (depth->enabled && stencil[0].enabled) + lp_build_mask_update(mask, z_pass); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.h b/src/gallium/auxiliary/gallivm/lp_bld_depth.h index 8be80024ae8..27dd46b625d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_depth.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.h @@ -36,7 +36,7 @@ #define LP_BLD_DEPTH_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct pipe_depth_state; @@ -51,13 +51,16 @@ lp_depth_type(const struct util_format_description *format_desc, void -lp_build_depth_test(LLVMBuilderRef builder, - const struct pipe_depth_state *state, - struct lp_type type, - const struct util_format_description *format_desc, - struct lp_build_mask_context *mask, - LLVMValueRef src, - LLVMValueRef dst_ptr); +lp_build_depth_stencil_test(LLVMBuilderRef builder, + const struct pipe_depth_state *depth, + const struct pipe_stencil_state stencil[2], + struct lp_type type, + const struct util_format_description *format_desc, + struct lp_build_mask_context *mask, + LLVMValueRef stencil_refs[2], + LLVMValueRef zs_src, + LLVMValueRef zs_dst_ptr, + LLVMValueRef facing); #endif /* !LP_BLD_DEPTH_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h index e1588365491..c2b50e1b602 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_flow.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h @@ -35,7 +35,7 @@ #define LP_BLD_FLOW_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h index 8972c0dc178..73ab6de3f21 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h @@ -34,7 +34,7 @@ * Pixel format helpers. */ -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "pipe/p_format.h" diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index abb27e4c328..45ee4b12ced 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -114,10 +114,10 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, case UTIL_FORMAT_TYPE_UNSIGNED: if(type.floating) { if(start) - input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), ""); + input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(type, start), ""); if(stop < format_desc->block.bits) { unsigned mask = ((unsigned long long)1 << width) - 1; - input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), ""); + input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(type, mask), ""); } if(format_desc->channel[chan].normalized) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_interp.c b/src/gallium/auxiliary/gallivm/lp_bld_interp.c index 2fc894017d8..09efb161217 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_interp.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.c @@ -289,17 +289,17 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index) /* top-right or bottom-right quad in block */ /* build x += xstep */ x = lp_build_add(&bld->base, x, - lp_build_const_scalar(bld->base.type, xstep)); + lp_build_const_vec(bld->base.type, xstep)); } if (quad_index == 2) { /* bottom-left quad in block */ /* build y += ystep */ y = lp_build_add(&bld->base, y, - lp_build_const_scalar(bld->base.type, ystep)); + lp_build_const_vec(bld->base.type, ystep)); /* build x -= xstep */ x = lp_build_sub(&bld->base, x, - lp_build_const_scalar(bld->base.type, xstep)); + lp_build_const_vec(bld->base.type, xstep)); } lp_build_name(x, "pos.x"); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_interp.h b/src/gallium/auxiliary/gallivm/lp_bld_interp.h index 177b5e943ee..a4937bbb048 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_interp.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.h @@ -41,7 +41,7 @@ #define LP_BLD_INTERP_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "tgsi/tgsi_exec.h" diff --git a/src/gallium/auxiliary/gallivm/lp_bld_intr.h b/src/gallium/auxiliary/gallivm/lp_bld_intr.h index 7d5506c7338..977f7673228 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_intr.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_intr.h @@ -37,7 +37,7 @@ #define LP_BLD_INTR_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" /** diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c index f3df3dd1388..a3b69701162 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c @@ -193,7 +193,7 @@ lp_build_compare(LLVMBuilderRef builder, if(table[func].gt && ((type.width == 8 && type.sign) || (type.width != 8 && !type.sign))) { - LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1)); + LLVMValueRef msb = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1)); a = LLVMBuildXor(builder, a, msb, ""); b = LLVMBuildXor(builder, b, msb, ""); } @@ -483,3 +483,13 @@ lp_build_alloca(struct lp_build_context *bld) return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), ""); } } + + +/** Return (a & ~b) */ +LLVMValueRef +lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) +{ + b = LLVMBuildNot(bld->builder, b, ""); + b = LLVMBuildAnd(bld->builder, a, b, ""); + return b; +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h index b54ec13b701..00a8c750196 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h @@ -37,7 +37,7 @@ #define LP_BLD_LOGIC_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */ @@ -79,4 +79,9 @@ lp_build_select_aos(struct lp_build_context *bld, LLVMValueRef lp_build_alloca(struct lp_build_context *bld); + +LLVMValueRef +lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b); + + #endif /* !LP_BLD_LOGIC_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c index 23398f41f99..2daa8a3b582 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c @@ -164,7 +164,7 @@ lp_build_unpack2(LLVMBuilderRef builder, if(dst_type.sign && src_type.sign) { /* Replicate the sign bit in the most significant bits */ - msb = LLVMBuildAShr(builder, src, lp_build_int_const_scalar(src_type, src_type.width - 1), ""); + msb = LLVMBuildAShr(builder, src, lp_build_const_int_vec(src_type, src_type.width - 1), ""); } else /* Most significant bits always zero */ @@ -361,7 +361,7 @@ lp_build_packs2(LLVMBuilderRef builder, if(clamp) { struct lp_build_context bld; unsigned dst_bits = dst_type.sign ? dst_type.width - 1 : dst_type.width; - LLVMValueRef dst_max = lp_build_int_const_scalar(src_type, ((unsigned long long)1 << dst_bits) - 1); + LLVMValueRef dst_max = lp_build_const_int_vec(src_type, ((unsigned long long)1 << dst_bits) - 1); lp_build_context_init(&bld, builder, src_type); lo = lp_build_min(&bld, lo, dst_max); hi = lp_build_min(&bld, hi, dst_max); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.h b/src/gallium/auxiliary/gallivm/lp_bld_pack.h index 346a17d5803..41adeed220c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_pack.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.h @@ -37,7 +37,7 @@ #define LP_BLD_PACK_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.c b/src/gallium/auxiliary/gallivm/lp_bld_printf.c new file mode 100644 index 00000000000..78c9ec778b6 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.c @@ -0,0 +1,113 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <stdio.h> + +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "lp_bld_printf.h" + + +static int +lp_get_printf_arg_count(const char *fmt) +{ + int count =0; + const char *p = fmt; + int c; + + while ((c = *p++)) { + if (c != '%') + continue; + switch (*p) { + case '\0': + continue; + case '%': + p++; + continue; + case '.': + if (p[1] == '*' && p[2] == 's') { + count += 2; + p += 3; + continue; + } + default: + count ++; + } + } + return count; +} + +LLVMValueRef +lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len) +{ + LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), len + 1), ""); + LLVMSetGlobalConstant(string, TRUE); + LLVMSetLinkage(string, LLVMInternalLinkage); + LLVMSetInitializer(string, LLVMConstString(str, len + 1, TRUE)); + return string; +} + + +/** + * lp_build_printf. + * + * Build printf call in LLVM IR. The output goes to stdout. + * The additional variable arguments need to have type + * LLVMValueRef. + */ +LLVMValueRef +lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...) +{ + va_list arglist; + int i = 0; + int argcount = lp_get_printf_arg_count(fmt); + LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); + LLVMValueRef params[50]; + LLVMValueRef fmtarg = lp_build_const_string_variable(module, fmt, strlen(fmt) + 1); + LLVMValueRef int0 = LLVMConstInt(LLVMInt32Type(), 0, 0); + LLVMValueRef index[2]; + LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf"); + + assert(Elements(params) >= argcount + 1); + + index[0] = index[1] = int0; + + if (!func_printf) { + LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntType(32), NULL, 0, 1); + func_printf = LLVMAddFunction(module, "printf", printf_type); + } + + params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, ""); + + va_start(arglist, fmt); + for (i = 1; i <= argcount; i++) + params[i] = va_arg(arglist, LLVMValueRef); + va_end(arglist); + + return LLVMBuildCall(builder, func_printf, params, argcount + 1, ""); +} + diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.h b/src/gallium/auxiliary/gallivm/lp_bld_printf.h new file mode 100644 index 00000000000..83bd8f1d557 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef LP_BLD_PRINTF_H +#define LP_BLD_PRINTF_H + + +#include "pipe/p_compiler.h" +#include "lp_bld.h" + +LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len); +LLVMValueRef lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...); + +#endif + diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index 2f74aa5e00a..bb76ad4c6bf 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -173,7 +173,7 @@ lp_build_sample_offset(struct lp_build_context *bld, LLVMValueRef x_stride; LLVMValueRef offset; - x_stride = lp_build_const_scalar(bld->type, format_desc->block.bits/8); + x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8); if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { LLVMValueRef x_lo, x_hi; @@ -195,9 +195,9 @@ lp_build_sample_offset(struct lp_build_context *bld, y_hi = LLVMBuildLShr(bld->builder, y, bld->one, ""); x_stride_lo = x_stride; - y_stride_lo = lp_build_const_scalar(bld->type, 2*format_desc->block.bits/8); + y_stride_lo = lp_build_const_vec(bld->type, 2*format_desc->block.bits/8); - x_stride_hi = lp_build_const_scalar(bld->type, 4*format_desc->block.bits/8); + x_stride_hi = lp_build_const_vec(bld->type, 4*format_desc->block.bits/8); y_stride_hi = LLVMBuildShl(bld->builder, y_stride, bld->one, ""); x_offset_lo = lp_build_mul(bld, x_lo, x_stride_lo); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 7f08bfaac1f..92f3c57435a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -36,7 +36,7 @@ #define LP_BLD_SAMPLE_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct pipe_texture; struct pipe_sampler_state; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 9741dbb389c..995c016b9dd 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -292,7 +292,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld, int chan; for (chan = 0; chan < 4; chan++) { LLVMValueRef border_chan = - lp_build_const_scalar(bld->texel_type, + lp_build_const_vec(bld->texel_type, bld->static_state->border_color[chan]); texel[chan] = lp_build_select(&bld->texel_bld, use_border, border_chan, texel[chan]); @@ -457,8 +457,8 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, struct lp_build_context *coord_bld = &bld->coord_bld; struct lp_build_context *int_coord_bld = &bld->int_coord_bld; struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld; - LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0); - LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5); + LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0); + LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5); LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length); LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one); LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one); @@ -512,7 +512,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, else { LLVMValueRef min, max; /* clamp to [0.5, length - 0.5] */ - min = lp_build_const_scalar(coord_bld->type, 0.5F); + min = lp_build_const_vec(coord_bld->type, 0.5F); max = lp_build_sub(coord_bld, length_f, min); coord = lp_build_clamp(coord_bld, coord, min, max); } @@ -533,7 +533,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, if (bld->static_state->normalized_coords) { /* min = -1.0 / (2 * length) = -0.5 / length */ min = lp_build_mul(coord_bld, - lp_build_const_scalar(coord_bld->type, -0.5F), + lp_build_const_vec(coord_bld->type, -0.5F), lp_build_rcp(coord_bld, length_f)); /* max = 1.0 - min */ max = lp_build_sub(coord_bld, coord_bld->one, min); @@ -545,7 +545,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, } else { /* clamp to [-0.5, length + 0.5] */ - min = lp_build_const_scalar(coord_bld->type, -0.5F); + min = lp_build_const_vec(coord_bld->type, -0.5F); max = lp_build_sub(coord_bld, length_f, min); coord = lp_build_clamp(coord_bld, coord, min, max); coord = lp_build_sub(coord_bld, coord, half); @@ -620,7 +620,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, LLVMValueRef min, max; /* min = -1.0 / (2 * length) = -0.5 / length */ min = lp_build_mul(coord_bld, - lp_build_const_scalar(coord_bld->type, -0.5F), + lp_build_const_vec(coord_bld->type, -0.5F), lp_build_rcp(coord_bld, length_f)); /* max = 1.0 - min */ max = lp_build_sub(coord_bld, coord_bld->one, min); @@ -665,7 +665,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, struct lp_build_context *coord_bld = &bld->coord_bld; struct lp_build_context *int_coord_bld = &bld->int_coord_bld; struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld; - LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0); + LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0); LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length); LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one); LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one); @@ -708,7 +708,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, } else { /* clamp to [0.5, length - 0.5] */ - min = lp_build_const_scalar(coord_bld->type, 0.5F); + min = lp_build_const_vec(coord_bld->type, 0.5F); max = lp_build_sub(coord_bld, length_f, min); } /* coord = clamp(coord, min, max) */ @@ -724,7 +724,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, if (bld->static_state->normalized_coords) { /* min = -1.0 / (2 * length) = -0.5 / length */ min = lp_build_mul(coord_bld, - lp_build_const_scalar(coord_bld->type, -0.5F), + lp_build_const_vec(coord_bld->type, -0.5F), lp_build_rcp(coord_bld, length_f)); /* max = length - min */ max = lp_build_sub(coord_bld, length_f, min); @@ -733,7 +733,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, } else { /* clamp to [-0.5, length + 0.5] */ - min = lp_build_const_scalar(coord_bld->type, -0.5F); + min = lp_build_const_vec(coord_bld->type, -0.5F); max = lp_build_sub(coord_bld, length_f, min); } /* coord = clamp(coord, min, max) */ @@ -1226,7 +1226,7 @@ static LLVMValueRef lp_build_cube_ima(struct lp_build_context *coord_bld, LLVMValueRef coord) { /* ima = -0.5 / abs(coord); */ - LLVMValueRef negHalf = lp_build_const_scalar(coord_bld->type, -0.5); + LLVMValueRef negHalf = lp_build_const_vec(coord_bld->type, -0.5); LLVMValueRef absCoord = lp_build_abs(coord_bld, coord); LLVMValueRef ima = lp_build_mul(coord_bld, negHalf, lp_build_rcp(coord_bld, absCoord)); @@ -1246,7 +1246,7 @@ lp_build_cube_coord(struct lp_build_context *coord_bld, LLVMValueRef coord, LLVMValueRef ima) { /* return negate(coord) * ima * sign + 0.5; */ - LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5); + LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5); LLVMValueRef res; assert(negate_coord == +1 || negate_coord == -1); @@ -1708,7 +1708,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder, LLVMValueRef packed, LLVMValueRef *rgba) { - LLVMValueRef mask = lp_build_int_const_scalar(dst_type, 0xff); + LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff); unsigned chan; /* Decode the input vector components */ @@ -1720,7 +1720,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder, input = packed; if(start) - input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(dst_type, start), ""); + input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(dst_type, start), ""); if(stop < 32) input = LLVMBuildAnd(builder, input, mask, ""); @@ -1782,17 +1782,17 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld, t = LLVMBuildFPToSI(builder, t, i32_vec_type, ""); /* subtract 0.5 (add -128) */ - i32_c128 = lp_build_int_const_scalar(i32.type, -128); + i32_c128 = lp_build_const_int_vec(i32.type, -128); s = LLVMBuildAdd(builder, s, i32_c128, ""); t = LLVMBuildAdd(builder, t, i32_c128, ""); /* compute floor (shift right 8) */ - i32_c8 = lp_build_int_const_scalar(i32.type, 8); + i32_c8 = lp_build_const_int_vec(i32.type, 8); s_ipart = LLVMBuildAShr(builder, s, i32_c8, ""); t_ipart = LLVMBuildAShr(builder, t, i32_c8, ""); /* compute fractional part (AND with 0xff) */ - i32_c255 = lp_build_int_const_scalar(i32.type, 255); + i32_c255 = lp_build_const_int_vec(i32.type, 255); s_fpart = LLVMBuildAnd(builder, s, i32_c255, ""); t_fpart = LLVMBuildAnd(builder, t, i32_c255, ""); @@ -1959,7 +1959,7 @@ lp_build_sample_compare(struct lp_build_sample_context *bld, } assert(res); - res = lp_build_mul(texel_bld, res, lp_build_const_scalar(texel_bld->type, 0.25)); + res = lp_build_mul(texel_bld, res, lp_build_const_vec(texel_bld->type, 0.25)); /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ for(chan = 0; chan < 3; ++chan) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.h b/src/gallium/auxiliary/gallivm/lp_bld_struct.h index 34478c10f51..147336edb4b 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_struct.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.h @@ -37,7 +37,7 @@ #define LP_BLD_STRUCT_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/Target.h> #include "util/u_debug.h" diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c index 64e81f7b1fe..278c838eaca 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c @@ -144,9 +144,9 @@ lp_build_broadcast_aos(struct lp_build_context *bld, #endif if(shift > 0) - tmp = LLVMBuildLShr(bld->builder, a, lp_build_int_const_scalar(type4, shift*type.width), ""); + tmp = LLVMBuildLShr(bld->builder, a, lp_build_const_int_vec(type4, shift*type.width), ""); if(shift < 0) - tmp = LLVMBuildShl(bld->builder, a, lp_build_int_const_scalar(type4, -shift*type.width), ""); + tmp = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type4, -shift*type.width), ""); assert(tmp); if(tmp) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h index 57b5cc079f2..138ca620e63 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h @@ -37,7 +37,7 @@ #define LP_BLD_SWIZZLE_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 0f2f8a65b10..63b938bfa98 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -35,7 +35,7 @@ #ifndef LP_BLD_TGSI_H #define LP_BLD_TGSI_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct tgsi_token; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 5ec59d636cb..8901e656aed 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -475,7 +475,7 @@ emit_store( break; case TGSI_SAT_MINUS_PLUS_ONE: - value = lp_build_max(&bld->base, value, lp_build_const_scalar(bld->base.type, -1.0)); + value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0)); value = lp_build_min(&bld->base, value, bld->base.one); break; @@ -651,32 +651,40 @@ emit_declaration( unsigned first = decl->Range.First; unsigned last = decl->Range.Last; unsigned idx, i; + LLVMBasicBlockRef current_block = + LLVMGetInsertBlock(bld->base.builder); + LLVMBasicBlockRef first_block = + LLVMGetEntryBasicBlock( + LLVMGetBasicBlockParent(current_block)); + LLVMValueRef first_inst = + LLVMGetFirstInstruction(first_block); + + /* we want alloca's to be the first instruction + * in the function so we need to rewind the builder + * to the very beginning */ + LLVMPositionBuilderBefore(bld->base.builder, + first_inst); for (idx = first; idx <= last; ++idx) { - boolean ok; - switch (decl->Declaration.File) { case TGSI_FILE_TEMPORARY: for (i = 0; i < NUM_CHANNELS; i++) bld->temps[idx][i] = lp_build_alloca(&bld->base); - ok = TRUE; break; case TGSI_FILE_OUTPUT: for (i = 0; i < NUM_CHANNELS; i++) bld->outputs[idx][i] = lp_build_alloca(&bld->base); - ok = TRUE; break; default: /* don't need to declare other vars */ - ok = TRUE; + break; } - - if (!ok) - return FALSE; } + LLVMPositionBuilderAtEnd(bld->base.builder, + current_block); return TRUE; } @@ -996,7 +1004,7 @@ emit_instruction( src0 = emit_fetch( bld, inst, 0, chan_index ); src1 = emit_fetch( bld, inst, 1, chan_index ); src2 = emit_fetch( bld, inst, 2, chan_index ); - tmp1 = lp_build_const_scalar(bld->base.type, 0.5); + tmp1 = lp_build_const_vec(bld->base.type, 0.5); tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1); dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 ); } @@ -1713,7 +1721,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, assert(num_immediates < LP_MAX_IMMEDIATES); for( i = 0; i < size; ++i ) bld.immediates[num_immediates][i] = - lp_build_const_scalar(type, parse.FullToken.FullImmediate.u[i].Float); + lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float); for( i = size; i < 4; ++i ) bld.immediates[num_immediates][i] = bld.base.undef; num_immediates++; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h index 5b351476ac2..cd59d2faa66 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_type.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h @@ -37,9 +37,9 @@ #define LP_BLD_TYPE_H -#include "os/os_llvm.h" +#include "pipe/p_compiler.h" +#include "gallivm/lp_bld.h" -#include <pipe/p_compiler.h> /** diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 86f9266c95f..0f2ae05daed 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -227,6 +227,8 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, pb_size size, const struct pb_desc *desc) { + void *map; + if(buf->base.base.size < size) return FALSE; @@ -239,6 +241,13 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, if(!pb_check_usage(desc->usage, buf->base.base.usage)) return FALSE; + + map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_DONTBLOCK); + if (!map) { + return FALSE; + } + + pb_unmap(buf->buffer); return TRUE; } diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index f675427d987..7595214bdf2 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -87,7 +87,7 @@ void x86_print_reg( struct x86_reg reg ) foo++; \ if (*foo) \ foo++; \ - debug_printf( "\n% 4x% 15s ", p->csr - p->store, foo ); \ + debug_printf( "\n%4x %14s ", p->csr - p->store, foo ); \ } while (0) #define DUMP_I( I ) do { \ diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index f7612d416a0..319b836ffb1 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -102,7 +102,7 @@ enum sse_cc { #define cc_Z cc_E #define cc_NZ cc_NE -/* Begin/end/retreive function creation: +/* Begin/end/retrieve function creation: */ @@ -311,8 +311,8 @@ void x87_fucom( struct x86_function *p, struct x86_reg arg ); -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity. Note - doesn't track explict +/* Retrieve a reference to one of the function arguments, taking into + * account any push/pop activity. Note - doesn't track explicit * manipulation of ESP by other instructions. */ struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index f918151daaa..0b468a9184e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -55,7 +55,7 @@ static boolean is_digit_alpha_underscore( const char *cur ) return is_digit( cur ) || is_alpha_underscore( cur ); } -static boolean uprcase( char c ) +static char uprcase( char c ) { if (c >= 'a' && c <= 'z') return c += 'A' - 'a'; @@ -76,7 +76,7 @@ streq_nocase_uprcase(const char *str1, str1++; str2++; } - return TRUE; + return *str1 == 0 && *str2 == 0; } static boolean str_match_no_case( const char **pcur, const char *str ) diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 4d0737ccd3d..cd95f85b63b 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -45,6 +45,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "util/u_surface.h" #include "util/u_rect.h" @@ -280,6 +281,7 @@ regions_overlap(int srcX0, int srcY0, void util_blit_pixels_writemask(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -290,7 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_texture *tex = NULL; + struct pipe_sampler_view *sampler_view = NULL; struct pipe_framebuffer_state fb; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); @@ -345,6 +347,8 @@ util_blit_pixels_writemask(struct blit_state *ctx, src->texture->last_level != 0) { struct pipe_texture texTemp; + struct pipe_texture *tex; + struct pipe_sampler_view sv_templ; struct pipe_surface *texSurf; const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); @@ -376,6 +380,14 @@ util_blit_pixels_writemask(struct blit_state *ctx, if (!tex) return; + u_sampler_view_default_template(&sv_templ, tex, tex->format); + + sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ); + if (!sampler_view) { + pipe_texture_reference(&tex, NULL); + return; + } + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); @@ -399,22 +411,25 @@ util_blit_pixels_writemask(struct blit_state *ctx, s1 = 1.0f; t0 = 0.0f; t1 = 1.0f; + + pipe_texture_reference(&tex, NULL); } else { - pipe_texture_reference(&tex, src->texture); - s0 = srcX0 / (float)tex->width0; - s1 = srcX1 / (float)tex->width0; - t0 = srcY0 / (float)tex->height0; - t1 = srcY1 / (float)tex->height0; + pipe_sampler_view_reference(&sampler_view, src_sampler_view); + s0 = srcX0 / (float)src->texture->width0; + s1 = srcX1 / (float)src->texture->width0; + t0 = srcY0 / (float)src->texture->height0; + t1 = srcY1 / (float)src->texture->height0; } + /* 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_fragment_sampler_views(ctx->cso); cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); @@ -447,7 +462,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_set_viewport(ctx->cso, &ctx->viewport); /* texture */ - cso_set_sampler_textures(ctx->cso, 1, &tex); + cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view); if (ctx->fs[writemask] == NULL) ctx->fs[writemask] = @@ -486,7 +501,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, 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_fragment_sampler_views(ctx->cso); cso_restore_viewport(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); @@ -494,13 +509,14 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); - pipe_texture_reference(&tex, NULL); + pipe_sampler_view_reference(&sampler_view, NULL); } void util_blit_pixels(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -508,7 +524,7 @@ util_blit_pixels(struct blit_state *ctx, int dstX1, int dstY1, float z, uint filter ) { - util_blit_pixels_writemask( ctx, src, + util_blit_pixels_writemask( ctx, src, src_sampler_view, srcX0, srcY0, srcX1, srcY1, dst, @@ -539,21 +555,23 @@ void util_blit_flush( struct blit_state *ctx ) */ void util_blit_pixels_tex(struct blit_state *ctx, - struct pipe_texture *tex, - int srcX0, int srcY0, - int srcX1, int srcY1, - struct pipe_surface *dst, - int dstX0, int dstY0, - int dstX1, int dstY1, - float z, uint filter) + struct pipe_sampler_view *src_sampler_view, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter) { struct pipe_framebuffer_state fb; float s0, t0, s1, t1; unsigned offset; + struct pipe_texture *tex = src_sampler_view->texture; assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); + assert(tex); assert(tex->width0 != 0); assert(tex->height0 != 0); @@ -572,7 +590,7 @@ util_blit_pixels_tex(struct blit_state *ctx, 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_fragment_sampler_views(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); @@ -604,7 +622,7 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_viewport(ctx->cso, &ctx->viewport); /* texture */ - cso_set_sampler_textures(ctx->cso, 1, &tex); + cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); /* shaders */ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]); @@ -638,7 +656,7 @@ util_blit_pixels_tex(struct blit_state *ctx, 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_fragment_sampler_views(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index a102021529e..1ebe65b4558 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -53,6 +53,7 @@ util_destroy_blit(struct blit_state *ctx); extern void util_blit_pixels(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -63,6 +64,7 @@ util_blit_pixels(struct blit_state *ctx, void util_blit_pixels_writemask(struct blit_state *ctx, struct pipe_surface *src, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, @@ -73,7 +75,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, extern void util_blit_pixels_tex(struct blit_state *ctx, - struct pipe_texture *tex, + struct pipe_sampler_view *src_sampler_view, int srcX0, int srcY0, int srcX1, int srcY1, struct pipe_surface *dst, diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 36d582491f3..1692987e8e3 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -45,6 +45,7 @@ #include "util/u_draw_quad.h" #include "util/u_pack_color.h" #include "util/u_rect.h" +#include "util/u_sampler.h" #include "util/u_simple_shaders.h" #include "util/u_texture.h" @@ -96,6 +97,8 @@ struct blitter_context_priv /* Rasterizer state. */ void *rs_state; + struct pipe_sampler_view *sampler_view; + /* Viewport state. */ struct pipe_viewport_state viewport; @@ -127,7 +130,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->blitter.saved_vs = INVALID_PTR; ctx->blitter.saved_velem_state = INVALID_PTR; ctx->blitter.saved_fb_state.nr_cbufs = ~0; - ctx->blitter.saved_num_textures = ~0; + ctx->blitter.saved_num_sampler_views = ~0; ctx->blitter.saved_num_sampler_states = ~0; /* blend state objects */ @@ -252,6 +255,10 @@ void util_blitter_destroy(struct blitter_context *blitter) if (ctx->sampler_state[i]) pipe->delete_sampler_state(pipe, ctx->sampler_state[i]); + if (ctx->sampler_view) { + pipe_sampler_view_reference(&ctx->sampler_view, NULL); + } + pipe_buffer_reference(&ctx->vbuf, NULL); FREE(ctx); } @@ -305,11 +312,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx) ctx->blitter.saved_num_sampler_states = ~0; } - if (ctx->blitter.saved_num_textures != ~0) { - pipe->set_fragment_sampler_textures(pipe, - ctx->blitter.saved_num_textures, - ctx->blitter.saved_textures); - ctx->blitter.saved_num_textures = ~0; + if (ctx->blitter.saved_num_sampler_views != ~0) { + pipe->set_fragment_sampler_views(pipe, + ctx->blitter.saved_num_sampler_views, + ctx->blitter.saved_sampler_views); + ctx->blitter.saved_num_sampler_views = ~0; } } @@ -621,9 +628,10 @@ static void util_blitter_do_copy(struct blitter_context *blitter, struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->pipe; struct pipe_framebuffer_state fb_state; + struct pipe_sampler_view viewTempl, *view; assert(blitter->saved_fb_state.nr_cbufs != ~0); - assert(blitter->saved_num_textures != ~0); + assert(blitter->saved_num_sampler_views != ~0); assert(blitter->saved_num_sampler_states != ~0); assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES); @@ -651,12 +659,24 @@ static void util_blitter_do_copy(struct blitter_context *blitter, fb_state.zsbuf = 0; } + u_sampler_view_default_template(&viewTempl, + src->texture, + src->texture->format); + view = pipe->create_sampler_view(pipe, + src->texture, + &viewTempl); + + if (ctx->sampler_view) { + pipe_sampler_view_reference(&ctx->sampler_view, NULL); + } + ctx->sampler_view = view; + pipe->bind_rasterizer_state(pipe, ctx->rs_state); pipe->bind_vs_state(pipe, ctx->vs_tex); pipe->bind_fragment_sampler_states(pipe, 1, blitter_get_sampler_state(ctx, src->level)); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); - pipe->set_fragment_sampler_textures(pipe, 1, &src->texture); + pipe->set_fragment_sampler_views(pipe, 1, &view); pipe->set_framebuffer_state(pipe, &fb_state); /* set texture coordinates */ diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index ecafdabafae..2ad7201a29d 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -53,10 +53,10 @@ struct blitter_context struct pipe_clip_state saved_clip; int saved_num_sampler_states; - void *saved_sampler_states[32]; + void *saved_sampler_states[PIPE_MAX_SAMPLERS]; - int saved_num_textures; - struct pipe_texture *saved_textures[32]; /* is 32 enough? */ + int saved_num_sampler_views; + struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; }; /** @@ -242,17 +242,17 @@ void util_blitter_save_fragment_sampler_states( num_sampler_states * sizeof(void *)); } -static INLINE -void util_blitter_save_fragment_sampler_textures( - struct blitter_context *blitter, - int num_textures, - struct pipe_texture **textures) +static INLINE void +util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, + int num_views, + struct pipe_sampler_view **views) { - assert(num_textures <= Elements(blitter->saved_textures)); + assert(num_views <= Elements(blitter->saved_sampler_views)); - blitter->saved_num_textures = num_textures; - memcpy(blitter->saved_textures, textures, - num_textures * sizeof(struct pipe_texture *)); + blitter->saved_num_sampler_views = num_views; + memcpy(blitter->saved_sampler_views, + views, + num_views * sizeof(struct pipe_sampler_view *)); } #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 96a0fa65507..d819bbbde1c 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -47,9 +47,9 @@ # - color space: rgb, yub, sz # # See also: -# - http://msdn.microsoft.com/en-us/library/ee416489.aspx (D3D9) -# - http://msdn.microsoft.com/en-us/library/ee415668.aspx (D3D9 -> D3D10) -# - http://msdn.microsoft.com/en-us/library/ee418116.aspx (D3D10) +# - http://msdn.microsoft.com/en-us/library/bb172558.aspx (D3D9) +# - http://msdn.microsoft.com/en-us/library/bb205073.aspx#mapping_texture_formats (D3D9 -> D3D10) +# - http://msdn.microsoft.com/en-us/library/bb173059.aspx (D3D10) # # Note that GL doesn't really specify the layout of internal formats. See # OpenGL 2.1 specification, Table 3.16, on the "Correspondence of sized @@ -63,6 +63,7 @@ PIPE_FORMAT_A8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, r PIPE_FORMAT_X8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb PIPE_FORMAT_A8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb PIPE_FORMAT_X8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzy1, rgb +PIPE_FORMAT_B5G5R5X1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyx1, rgb PIPE_FORMAT_B5G5R5A1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb PIPE_FORMAT_B4G4R4A4_UNORM , plain, 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb PIPE_FORMAT_B5G6R5_UNORM , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb @@ -109,14 +110,18 @@ PIPE_FORMAT_UYVY , subsampled, 2, 1, x32 , , , , xyz PIPE_FORMAT_YUYV , subsampled, 2, 1, x32 , , , , xyz1, yuv # Compressed formats -PIPE_FORMAT_DXT1_RGB , compressed, 4, 4, x64 , , , , xyz1, rgb -PIPE_FORMAT_DXT1_RGBA , compressed, 4, 4, x64 , , , , xyzw, rgb -PIPE_FORMAT_DXT3_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb -PIPE_FORMAT_DXT5_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb -PIPE_FORMAT_DXT1_SRGB , compressed, 4, 4, x64 , , , , xyz1, srgb -PIPE_FORMAT_DXT1_SRGBA , compressed, 4, 4, x64 , , , , xyzw, srgb -PIPE_FORMAT_DXT3_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb -PIPE_FORMAT_DXT5_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb +# - http://en.wikipedia.org/wiki/S3_Texture_Compression +# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt +# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt +# - http://msdn.microsoft.com/en-us/library/bb694531.aspx +PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb +PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb +PIPE_FORMAT_DXT3_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb +PIPE_FORMAT_DXT5_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb +PIPE_FORMAT_DXT1_SRGB , s3tc, 4, 4, x64 , , , , xyz1, srgb +PIPE_FORMAT_DXT1_SRGBA , s3tc, 4, 4, x64 , , , , xyzw, srgb +PIPE_FORMAT_DXT3_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb +PIPE_FORMAT_DXT5_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb # Straightforward D3D10-like formats (also used for # vertex buffer element description) diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index c08fdcafcc8..98d4b98ebb5 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -56,15 +56,23 @@ enum util_format_layout { * * This is for formats like YV12 where there is less than one sample per * pixel. - * - * XXX: This could actually b */ UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, /** - * An unspecified compression algorithm. + * S3 Texture Compression formats. + */ + UTIL_FORMAT_LAYOUT_S3TC = 4, + + /** + * Red-Green Texture Compression formats. + */ + UTIL_FORMAT_LAYOUT_RGTC = 5, + + /** + * Everything else that doesn't fit in any of the above layouts. */ - UTIL_FORMAT_LAYOUT_COMPRESSED = 4 + UTIL_FORMAT_LAYOUT_OTHER = 6 }; @@ -210,7 +218,7 @@ util_format_name(enum pipe_format format) } static INLINE boolean -util_format_is_compressed(enum pipe_format format) +util_format_is_s3tc(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); @@ -219,7 +227,7 @@ util_format_is_compressed(enum pipe_format format) return FALSE; } - return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE; + return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; } static INLINE boolean diff --git a/src/gallium/auxiliary/util/u_format_tests.c b/src/gallium/auxiliary/util/u_format_tests.c index 182a4740448..9d6debcd8c7 100644 --- a/src/gallium/auxiliary/util/u_format_tests.c +++ b/src/gallium/auxiliary/util/u_format_tests.c @@ -120,6 +120,13 @@ util_format_test_cases[] = * 16-bit rendertarget formats */ + {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}}, + {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}}, + {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}}, + {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x7c00), {1.0, 0.0, 0.0, 0.0}}, + {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x8000), {0.0, 0.0, 0.0, 1.0}}, + {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}}, + {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}}, {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}}, {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}}, diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 5c51b53d7bd..509d38754f5 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -938,6 +938,7 @@ format_to_type_comps(enum pipe_format pformat, *datatype = DTYPE_UBYTE; *comps = 4; return; + case PIPE_FORMAT_B5G5R5X1_UNORM: case PIPE_FORMAT_B5G5R5A1_UNORM: *datatype = DTYPE_USHORT_1_5_5_5_REV; *comps = 4; @@ -1460,7 +1461,7 @@ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx ) * Generate mipmap images. It's assumed all needed texture memory is * already allocated. * - * \param pt the texture to generate mipmap levels for + * \param psv the sampler view to the texture to generate mipmap levels for * \param face which cube face to generate mipmaps for (0 for non-cube maps) * \param baseLevel the first mipmap level to use as a src * \param lastLevel the last mipmap level to generate @@ -1469,12 +1470,13 @@ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx ) */ void util_gen_mipmap(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, + struct pipe_sampler_view *psv, uint face, uint baseLevel, uint lastLevel, uint filter) { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; + struct pipe_texture *pt = psv->texture; void *fs = (pt->target == PIPE_TEXTURE_CUBE) ? ctx->fsCube : ctx->fs2d; uint dstLevel; uint zslice = 0; @@ -1492,7 +1494,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, filter == PIPE_TEX_FILTER_NEAREST); /* check if we can render in the texture's format */ - if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D, + if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); return; @@ -1503,7 +1505,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, 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_fragment_sampler_views(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); @@ -1572,7 +1574,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); - cso_set_sampler_textures(ctx->cso, 1, &pt); + cso_set_fragment_sampler_views(ctx->cso, 1, &psv); /* quad coords in clip coords */ offset = set_vertex_data(ctx, @@ -1597,7 +1599,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, 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_fragment_sampler_views(ctx->cso); cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index 54608f9466d..35ac9daeaa2 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -59,7 +59,7 @@ util_gen_mipmap_flush( struct gen_mipmap_state *ctx ); extern void util_gen_mipmap(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, + struct pipe_sampler_view *psv, uint face, uint baseLevel, uint lastLevel, uint filter); diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index e7255e3baa8..e22ab188e11 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -120,6 +120,16 @@ pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex) *ptr = tex; } +static INLINE void +pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) +{ + struct pipe_sampler_view *old_view = *ptr; + + if (pipe_reference(&(*ptr)->reference, &view->reference)) + old_view->context->sampler_view_destroy(old_view->context, old_view); + *ptr = view; +} + /* * Convenience wrappers for screen buffer functions. diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 50f1b1670b6..c5fd7a6783e 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -92,6 +92,11 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); } return; + case PIPE_FORMAT_B5G5R5X1_UNORM: + { + uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); + } + return; case PIPE_FORMAT_B5G5R5A1_UNORM: { uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); @@ -216,6 +221,15 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc, *a = (ubyte) 0xff; } return; + case PIPE_FORMAT_B5G5R5X1_UNORM: + { + ushort p = uc->us; + *r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7)); + *g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7)); + *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7)); + *a = (ubyte) 0xff; + } + return; case PIPE_FORMAT_B5G5R5A1_UNORM: { ushort p = uc->us; @@ -361,6 +375,11 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); } return; + case PIPE_FORMAT_B5G5R5X1_UNORM: + { + uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); + } + return; case PIPE_FORMAT_B5G5R5A1_UNORM: { uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); diff --git a/src/gallium/auxiliary/util/u_sampler.c b/src/gallium/auxiliary/util/u_sampler.c new file mode 100644 index 00000000000..4d8f861ce49 --- /dev/null +++ b/src/gallium/auxiliary/util/u_sampler.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "u_format.h" +#include "u_sampler.h" + + +static void +default_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format, + unsigned expand_green_blue) +{ + /* XXX: Check if format is compatible with texture->format. + */ + + view->format = format; + view->first_level = 0; + view->last_level = texture->last_level; + view->swizzle_r = PIPE_SWIZZLE_RED; + view->swizzle_g = PIPE_SWIZZLE_GREEN; + view->swizzle_b = PIPE_SWIZZLE_BLUE; + view->swizzle_a = PIPE_SWIZZLE_ALPHA; + + /* Override default green and blue component expansion to the requested + * one. + * + * Gallium expands nonexistent components to (0,0,0,1), DX9 expands + * to (1,1,1,1). Since alpha is always expanded to 1, and red is + * always present, we only really care about green and blue + * components. + * + * To make it look less hackish, one would have to add + * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion + * and then override without exceptions or favoring one component + * over another. + */ + if (format != PIPE_FORMAT_A8_UNORM) { + const struct util_format_description *desc = util_format_description(format); + + assert(desc); + if (desc) { + if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) { + view->swizzle_g = expand_green_blue; + } + if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) { + view->swizzle_b = expand_green_blue; + } + } + } +} + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format) +{ + /* Expand to (0, 0, 0, 1) */ + default_template(view, + texture, + format, + PIPE_SWIZZLE_ZERO); +} + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format) +{ + /* Expand to (1, 1, 1, 1) */ + default_template(view, + texture, + format, + PIPE_SWIZZLE_ONE); +} diff --git a/src/gallium/auxiliary/util/u_sampler.h b/src/gallium/auxiliary/util/u_sampler.h new file mode 100644 index 00000000000..bdd061c851c --- /dev/null +++ b/src/gallium/auxiliary/util/u_sampler.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef U_SAMPLER_H +#define U_SAMPLER_H + + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format); + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, + const struct pipe_texture *texture, + enum pipe_format format); + + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* U_SAMPLER_H */ diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index e445895efc5..09b2382733d 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -295,6 +295,55 @@ r8g8b8a8_put_tile_rgba(unsigned *dst, } +/*** PIPE_FORMAT_B5G5R5X1_UNORM ***/ + +static void +x1r5g5b5_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = 1.0f; + } + p += dst_stride; + } +} + + +static void +x1r5g5b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b; + r = float_to_ubyte(pRow[0]); + g = float_to_ubyte(pRow[1]); + b = float_to_ubyte(pRow[2]); + r = r >> 3; /* 5 bits */ + g = g >> 3; /* 5 bits */ + b = b >> 3; /* 5 bits */ + *dst++ = (1 << 15) | (r << 10) | (g << 5) | b; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_B5G5R5A1_UNORM ***/ static void @@ -1174,6 +1223,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format, case PIPE_FORMAT_A8B8G8R8_UNORM: r8g8b8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; + case PIPE_FORMAT_B5G5R5X1_UNORM: + x1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + break; case PIPE_FORMAT_B5G5R5A1_UNORM: a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; @@ -1275,6 +1327,69 @@ pipe_get_tile_rgba(struct pipe_context *pipe, void +pipe_get_tile_swizzle(struct pipe_context *pipe, + struct pipe_transfer *pt, + uint x, + uint y, + uint w, + uint h, + uint swizzle_r, + uint swizzle_g, + uint swizzle_b, + uint swizzle_a, + enum pipe_format format, + float *p) +{ + unsigned dst_stride = w * 4; + void *packed; + uint i; + float rgba01[6]; + + if (pipe_clip_tile(x, y, &w, &h, pt)) { + return; + } + + packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); + if (!packed) { + return; + } + + if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { + assert((x & 1) == 0); + } + + pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0); + + pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride); + + FREE(packed); + + if (swizzle_r == PIPE_SWIZZLE_RED && + swizzle_g == PIPE_SWIZZLE_GREEN && + swizzle_b == PIPE_SWIZZLE_BLUE && + swizzle_a == PIPE_SWIZZLE_ALPHA) { + /* no-op, skip */ + return; + } + + rgba01[PIPE_SWIZZLE_ZERO] = 0.0f; + rgba01[PIPE_SWIZZLE_ONE] = 1.0f; + + for (i = 0; i < w * h; i++) { + rgba01[PIPE_SWIZZLE_RED] = p[0]; + rgba01[PIPE_SWIZZLE_GREEN] = p[1]; + rgba01[PIPE_SWIZZLE_BLUE] = p[2]; + rgba01[PIPE_SWIZZLE_ALPHA] = p[3]; + + *p++ = rgba01[swizzle_r]; + *p++ = rgba01[swizzle_g]; + *p++ = rgba01[swizzle_b]; + *p++ = rgba01[swizzle_a]; + } +} + + +void pipe_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *pt, uint x, uint y, uint w, uint h, @@ -1305,6 +1420,9 @@ pipe_put_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_A8B8G8R8_UNORM: r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); break; + case PIPE_FORMAT_B5G5R5X1_UNORM: + x1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; case PIPE_FORMAT_B5G5R5A1_UNORM: a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h index 8329087cfa6..1d8ce7d8cbc 100644 --- a/src/gallium/auxiliary/util/u_tile.h +++ b/src/gallium/auxiliary/util/u_tile.h @@ -75,6 +75,20 @@ pipe_get_tile_rgba(struct pipe_context *pipe, float *p); void +pipe_get_tile_swizzle(struct pipe_context *pipe, + struct pipe_transfer *pt, + uint x, + uint y, + uint w, + uint h, + uint swizzle_r, + uint swizzle_g, + uint swizzle_b, + uint swizzle_a, + enum pipe_format format, + float *p); + +void pipe_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *pt, uint x, uint y, uint w, uint h, |