diff options
Diffstat (limited to 'src')
203 files changed, 4031 insertions, 2874 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 4f13b3e2bad..b6f7b883224 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -50,20 +50,35 @@ struct cso_context { struct { void *samplers[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; + + void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned nr_vertex_samplers; } hw; void *samplers[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; + void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned nr_vertex_samplers; + unsigned nr_samplers_saved; void *samplers_saved[PIPE_MAX_SAMPLERS]; + unsigned nr_vertex_samplers_saved; + void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; uint nr_textures; + struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; + uint nr_vertex_textures; + uint nr_textures_saved; struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_vertex_textures_saved; + struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS]; + /** Current and saved state. * The saved state is used as a 1-deep stack. */ @@ -244,7 +259,8 @@ void cso_release_all( struct cso_context *ctx ) if (ctx->pipe) { ctx->pipe->bind_blend_state( ctx->pipe, NULL ); ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL ); - ctx->pipe->bind_sampler_states( ctx->pipe, 0, NULL ); + ctx->pipe->bind_fragment_sampler_states( ctx->pipe, 0, NULL ); + ctx->pipe->bind_vertex_sampler_states(ctx->pipe, 0, NULL); ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL ); ctx->pipe->bind_fs_state( ctx->pipe, NULL ); ctx->pipe->bind_vs_state( ctx->pipe, NULL ); @@ -255,6 +271,11 @@ void cso_release_all( struct cso_context *ctx ) pipe_texture_reference(&ctx->textures_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); + } + free_framebuffer_state(&ctx->fb); free_framebuffer_state(&ctx->fb_saved); @@ -378,6 +399,46 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, return PIPE_OK; } +enum pipe_error +cso_single_vertex_sampler(struct cso_context *ctx, + unsigned idx, + const struct pipe_sampler_state *templ) +{ + void *handle = NULL; + + if (templ != NULL) { + unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_SAMPLER, + (void*)templ); + + if (cso_hash_iter_is_null(iter)) { + struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + + memcpy(&cso->state, templ, sizeof(*templ)); + cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + + handle = cso->data; + } + else { + handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data; + } + } + + ctx->vertex_samplers[idx] = handle; + return PIPE_OK; +} + void cso_single_sampler_done( struct cso_context *ctx ) { unsigned i; @@ -398,7 +459,36 @@ void cso_single_sampler_done( struct cso_context *ctx ) memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *)); ctx->hw.nr_samplers = ctx->nr_samplers; - ctx->pipe->bind_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers); + ctx->pipe->bind_fragment_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers); + } +} + +void +cso_single_vertex_sampler_done(struct cso_context *ctx) +{ + unsigned i; + + /* find highest non-null sampler */ + for (i = PIPE_MAX_VERTEX_SAMPLERS; i > 0; i--) { + if (ctx->vertex_samplers[i - 1] != NULL) + break; + } + + ctx->nr_vertex_samplers = i; + + if (ctx->hw.nr_vertex_samplers != ctx->nr_vertex_samplers || + memcmp(ctx->hw.vertex_samplers, + ctx->vertex_samplers, + ctx->nr_vertex_samplers * sizeof(void *)) != 0) + { + memcpy(ctx->hw.vertex_samplers, + ctx->vertex_samplers, + ctx->nr_vertex_samplers * sizeof(void *)); + ctx->hw.nr_vertex_samplers = ctx->nr_vertex_samplers; + + ctx->pipe->bind_vertex_sampler_states(ctx->pipe, + ctx->nr_vertex_samplers, + ctx->vertex_samplers); } } @@ -447,6 +537,21 @@ void cso_restore_samplers(struct cso_context *ctx) cso_single_sampler_done( ctx ); } +void +cso_save_vertex_samplers(struct cso_context *ctx) +{ + ctx->nr_vertex_samplers_saved = ctx->nr_vertex_samplers; + memcpy(ctx->vertex_samplers_saved, ctx->vertex_samplers, sizeof(ctx->vertex_samplers)); +} + +void +cso_restore_vertex_samplers(struct cso_context *ctx) +{ + ctx->nr_vertex_samplers = ctx->nr_vertex_samplers_saved; + memcpy(ctx->vertex_samplers, ctx->vertex_samplers_saved, sizeof(ctx->vertex_samplers)); + cso_single_vertex_sampler_done(ctx); +} + enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, uint count, @@ -461,7 +566,7 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, for ( ; i < PIPE_MAX_SAMPLERS; i++) pipe_texture_reference(&ctx->textures[i], NULL); - ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); + ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures); return PIPE_OK; } @@ -491,13 +596,71 @@ void cso_restore_sampler_textures( struct cso_context *ctx ) for ( ; i < PIPE_MAX_SAMPLERS; i++) pipe_texture_reference(&ctx->textures[i], NULL); - ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); + 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) { diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 69630e98bae..e5b92177cfd 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -84,6 +84,20 @@ enum pipe_error cso_single_sampler( struct cso_context *cso, void cso_single_sampler_done( struct cso_context *cso ); +void +cso_save_vertex_samplers(struct cso_context *cso); + +void +cso_restore_vertex_samplers(struct cso_context *cso); + +enum pipe_error +cso_single_vertex_sampler(struct cso_context *cso, + unsigned nr, + const struct pipe_sampler_state *states); + +void +cso_single_vertex_sampler_done(struct cso_context *cso); + enum pipe_error cso_set_sampler_textures( struct cso_context *cso, @@ -94,6 +108,17 @@ 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); + + + /* These aren't really sensible -- most of the time the api provides * object semantics for shaders anyway, and the cases where it doesn't * (eg mesa's internall-generated texenv programs), it will be up to diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 3bb96161224..8ccd527b3af 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -399,9 +399,9 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.target = PIPE_TEXTURE_2D; texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = MAX_TEXTURE_LEVEL; - texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; - texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; - texTemp.depth[0] = 1; + texTemp.width0 = 1 << MAX_TEXTURE_LEVEL; + texTemp.height0 = 1 << MAX_TEXTURE_LEVEL; + texTemp.depth0 = 1; pf_get_block(texTemp.format, &texTemp.block); aaline->texture = screen->texture_create(screen, &texTemp); @@ -414,11 +414,11 @@ aaline_create_texture(struct aaline_stage *aaline) */ for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { struct pipe_transfer *transfer; - const uint size = aaline->texture->width[level]; + const uint size = u_minify(aaline->texture->width0, level); ubyte *data; uint i, j; - assert(aaline->texture->width[level] == aaline->texture->height[level]); + assert(aaline->texture->width0 == aaline->texture->height0); /* This texture is new, no need to flush. */ @@ -897,16 +897,16 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) aaline->driver_bind_fs_state = pipe->bind_fs_state; aaline->driver_delete_fs_state = pipe->delete_fs_state; - aaline->driver_bind_sampler_states = pipe->bind_sampler_states; - aaline->driver_set_sampler_textures = pipe->set_sampler_textures; + aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; + aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; /* override the driver's functions */ pipe->create_fs_state = aaline_create_fs_state; pipe->bind_fs_state = aaline_bind_fs_state; pipe->delete_fs_state = aaline_delete_fs_state; - pipe->bind_sampler_states = aaline_bind_sampler_states; - pipe->set_sampler_textures = aaline_set_sampler_textures; + pipe->bind_fragment_sampler_states = aaline_bind_sampler_states; + pipe->set_fragment_sampler_textures = aaline_set_sampler_textures; /* 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 45317227a8d..a500edd7fee 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -428,9 +428,9 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.target = PIPE_TEXTURE_2D; texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = 0; - texTemp.width[0] = 32; - texTemp.height[0] = 32; - texTemp.depth[0] = 1; + texTemp.width0 = 32; + texTemp.height0 = 32; + texTemp.depth0 = 1; pf_get_block(texTemp.format, &texTemp.block); pstip->texture = screen->texture_create(screen, &texTemp); @@ -755,8 +755,8 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->driver_bind_fs_state = pipe->bind_fs_state; pstip->driver_delete_fs_state = pipe->delete_fs_state; - pstip->driver_bind_sampler_states = pipe->bind_sampler_states; - pstip->driver_set_sampler_textures = pipe->set_sampler_textures; + pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; + pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; /* override the driver's functions */ @@ -764,8 +764,8 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->bind_fs_state = pstip_bind_fs_state; pipe->delete_fs_state = pstip_delete_fs_state; - pipe->bind_sampler_states = pstip_bind_sampler_states; - pipe->set_sampler_textures = pstip_set_sampler_textures; + pipe->bind_fragment_sampler_states = pstip_bind_sampler_states; + pipe->set_fragment_sampler_textures = pstip_set_sampler_textures; pipe->set_polygon_stipple = pstip_set_polygon_stipple; return TRUE; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index d3f179ced18..757c4874545 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -346,7 +346,8 @@ vcache_check_run( struct draw_pt_front_end *frontend, vcache->fetch_max, draw_count); - if (max_index == 0xffffffff || + if (max_index >= DRAW_PIPE_MAX_VERTICES || + fetch_count >= UNDEFINED_VERTEX_ID || fetch_count > draw_count) { if (0) debug_printf("fail\n"); goto fail; diff --git a/src/gallium/auxiliary/rbug/README b/src/gallium/auxiliary/rbug/README index 33d76371de4..d984067893c 100644 --- a/src/gallium/auxiliary/rbug/README +++ b/src/gallium/auxiliary/rbug/README @@ -16,6 +16,10 @@ for information about applications look in: progs/rbug/README +for a GUI see: + + http://cgit.freedesktop.org/mesa/rbug-gui + -- Jakob Bornecrantz <[email protected]> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 6cd23b37be6..22984c32320 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -501,7 +501,7 @@ micro_ddy( dst->f[0] = dst->f[1] = dst->f[2] = - dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT]; + dst->f[3] = src->f[TILE_BOTTOM_LEFT] - src->f[TILE_TOP_LEFT]; } static void @@ -3213,7 +3213,28 @@ exec_instruction( break; case TGSI_OPCODE_ENDSUB: - /* no-op */ + /* + * XXX: This really should be a no-op. We should never reach this opcode. + */ + + assert(mach->CallStackTop > 0); + mach->CallStackTop--; + + mach->CondStackTop = mach->CallStack[mach->CallStackTop].CondStackTop; + mach->CondMask = mach->CondStack[mach->CondStackTop]; + + mach->LoopStackTop = mach->CallStack[mach->CallStackTop].LoopStackTop; + mach->LoopMask = mach->LoopStack[mach->LoopStackTop]; + + mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop; + mach->ContMask = mach->ContStack[mach->ContStackTop]; + + assert(mach->FuncStackTop > 0); + mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; + + *pc = mach->CallStack[mach->CallStackTop].ReturnAddr; + + UPDATE_EXEC_MASK(mach); break; case TGSI_OPCODE_NOP: @@ -3343,5 +3364,10 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) } #endif + assert(mach->CondStackTop == 0); + assert(mach->LoopStackTop == 0); + assert(mach->ContStackTop == 0); + assert(mach->CallStackTop == 0); + return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index 8bd1f31e9ce..b5d1faa897a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -34,7 +34,7 @@ typedef uint reg_flag; #define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8) -#define MAX_REGISTERS 256 +#define MAX_REGISTERS 1024 #define MAX_REG_FLAGS ((MAX_REGISTERS + BITS_IN_REG_FLAG - 1) / BITS_IN_REG_FLAG) struct sanity_check_ctx diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 7d860e89c1d..080bdb5145a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -349,6 +349,7 @@ struct ureg_src ureg_DECL_constant(struct ureg_program *ureg, i = ureg->nr_constant_ranges++; ureg->constant_range[i].first = index; ureg->constant_range[i].last = index; + goto out; } /* Collapse all ranges down to one: diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 50386425995..5372df57352 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -354,9 +354,9 @@ util_blit_pixels_writemask(struct blit_state *ctx, texTemp.target = PIPE_TEXTURE_2D; texTemp.format = src->format; texTemp.last_level = 0; - texTemp.width[0] = srcW; - texTemp.height[0] = srcH; - texTemp.depth[0] = 1; + texTemp.width0 = srcW; + texTemp.height0 = srcH; + texTemp.depth0 = 1; pf_get_block(src->format, &texTemp.block); tex = screen->texture_create(screen, &texTemp); @@ -389,10 +389,10 @@ util_blit_pixels_writemask(struct blit_state *ctx, } else { pipe_texture_reference(&tex, src->texture); - s0 = srcX0 / (float)tex->width[0]; - s1 = srcX1 / (float)tex->width[0]; - t0 = srcY0 / (float)tex->height[0]; - t1 = srcY1 / (float)tex->height[0]; + s0 = srcX0 / (float)tex->width0; + s1 = srcX1 / (float)tex->width0; + t0 = srcY0 / (float)tex->height0; + t1 = srcY1 / (float)tex->height0; } @@ -518,13 +518,13 @@ util_blit_pixels_tex(struct blit_state *ctx, assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); - assert(tex->width[0] != 0); - assert(tex->height[0] != 0); + assert(tex->width0 != 0); + assert(tex->height0 != 0); - s0 = srcX0 / (float)tex->width[0]; - s1 = srcX1 / (float)tex->width[0]; - t0 = srcY0 / (float)tex->height[0]; - t1 = srcY1 / (float)tex->height[0]; + s0 = srcX0 / (float)tex->width0; + s1 = srcX1 / (float)tex->width0; + t0 = srcY0 / (float)tex->height0; + t1 = srcY1 / (float)tex->height0; assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, PIPE_TEXTURE_2D, diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index f1bf94f17dd..b9cc2aa716e 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -97,3 +97,13 @@ PIPE_FORMAT_B8G8R8A8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyxw, PIPE_FORMAT_B8G8R8X8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyx1, srgb PIPE_FORMAT_X8UB8UG8SR8S_NORM , arith , 1, 1, sn8 , sn8 , un8 , x8 , 1zyx, rgb PIPE_FORMAT_B6UG5SR5S_NORM , arith , 1, 1, sn5 , sn5 , un6 , , xyz1, rgb +PIPE_FORMAT_YCBCR , yuv , 2, 1, x32 , , , , xyz1, yuv +PIPE_FORMAT_YCBCR_REV , yuv , 2, 1, x32 , , , , xyz1, yuv +PIPE_FORMAT_DXT1_RGBA , dxt , 4, 4, x64 , , , , xyzw, rgb +PIPE_FORMAT_DXT1_RGB , dxt , 4, 4, x64 , , , , xyz1, rgb +PIPE_FORMAT_DXT3_RGBA , dxt , 4, 4, x128, , , , xyzw, rgb +PIPE_FORMAT_DXT5_RGBA , dxt , 4, 4, x128, , , , xyzw, rgb +PIPE_FORMAT_DXT1_SRGBA , dxt , 4, 4, x64 , , , , xyzw, srgb +PIPE_FORMAT_DXT1_SRGB , dxt , 4, 4, x64 , , , , xyz1, srgb +PIPE_FORMAT_DXT3_SRGBA , dxt , 4, 4, x128, , , , xyzw, srgb +PIPE_FORMAT_DXT5_SRGBA , dxt , 4, 4, x128, , , , xyzw, srgb diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index aa823aa218b..f67f1e458d4 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -45,6 +45,7 @@ #include "util/u_draw_quad.h" #include "util/u_gen_mipmap.h" #include "util/u_simple_shaders.h" +#include "util/u_math.h" #include "cso_cache/cso_context.h" @@ -1125,12 +1126,12 @@ make_1d_mipmap(struct gen_mipmap_state *ctx, srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel)); dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel)); srcMap = (ubyte *) screen->transfer_map(screen, srcTrans); dstMap = (ubyte *) screen->transfer_map(screen, dstTrans); @@ -1168,12 +1169,12 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel)); dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel)); srcMap = (ubyte *) screen->transfer_map(screen, srcTrans); dstMap = (ubyte *) screen->transfer_map(screen, dstTrans); @@ -1213,12 +1214,12 @@ make_3d_mipmap(struct gen_mipmap_state *ctx, srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel)); dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel)); srcMap = (ubyte *) screen->transfer_map(screen, srcTrans); dstMap = (ubyte *) screen->transfer_map(screen, dstTrans); @@ -1575,8 +1576,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * Setup framebuffer / dest surface */ fb.cbufs[0] = surf; - fb.width = pt->width[dstLevel]; - fb.height = pt->height[dstLevel]; + fb.width = u_minify(pt->width0, dstLevel); + fb.height = u_minify(pt->height0, dstLevel); cso_set_framebuffer(ctx->cso, &fb); /* @@ -1597,8 +1598,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, offset = set_vertex_data(ctx, pt->target, face, - (float) pt->width[dstLevel], - (float) pt->height[dstLevel]); + (float) u_minify(pt->width0, dstLevel), + (float) u_minify(pt->height0, dstLevel)); util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index 9ed1ab6d8ee..a5cd6574c0e 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -499,11 +499,15 @@ util_bitcount(unsigned n) #if defined(PIPE_CC_GCC) return __builtin_popcount(n); #else - /* XXX there are more clever ways of doing this */ + /* K&R classic bitcount. + * + * For each iteration, clear the LSB from the bitfield. + * Requires only one iteration per set bit, instead of + * one iteration per bit less than highest set bit. + */ unsigned bits = 0; - while (n) { - bits += (n & 1); - n = n >> 1; + for (bits; n; bits++) { + n &= n - 1; } return bits; #endif @@ -511,6 +515,23 @@ util_bitcount(unsigned n) /** + * Reverse byte order of a 32 bit word. + */ +static INLINE uint32_t +util_bswap32(uint32_t n) +{ +#if defined(PIPE_CC_GCC) + return __builtin_bswap32(n); +#else + return (n >> 24) | + ((n >> 8) & 0x0000ff00) | + ((n << 8) & 0x00ff0000) | + (n << 24); +#endif +} + + +/** * Clamp X to [MIN, MAX]. * This is a macro to allow float, int, uint, etc. types. */ @@ -530,9 +551,9 @@ align(int value, int alignment) } static INLINE unsigned -minify(unsigned value) +u_minify(unsigned value, unsigned levels) { - return MAX2(1, value >> 1); + return MAX2(1, value >> levels); } #ifndef COPY_4V diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c index 4b75d4ba1d0..82f83702d1e 100644 --- a/src/gallium/auxiliary/util/u_mm.c +++ b/src/gallium/auxiliary/util/u_mm.c @@ -39,13 +39,20 @@ u_mmDumpMemInfo(const struct mem_block *heap) } else { const struct mem_block *p; + int total_used = 0, total_free = 0; for (p = heap->next; p != heap; p = p->next) { debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, p->free ? 'F':'.', p->reserved ? 'R':'.'); + if (p->free) + total_free += p->size; + else + total_used += p->size; } + debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n", + total_used + total_free, total_used, total_free); debug_printf("\nFree list:\n"); for (p = heap->next_free; p != heap; p = p->next_free) { diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 85e443204e3..de8c266db83 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -79,9 +79,9 @@ util_create_rgba_surface(struct pipe_screen *screen, templ.target = target; templ.format = format; templ.last_level = 0; - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; pf_get_block(format, &templ.block); templ.tex_usage = usage; diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 70ac3f28313..fc2a1c59a6b 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -453,8 +453,8 @@ void vl_compositor_render(struct vl_compositor *compositor, assert(dst_area); assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME); - compositor->fb_state.width = dst_surface->width[0]; - compositor->fb_state.height = dst_surface->height[0]; + compositor->fb_state.width = dst_surface->width0; + compositor->fb_state.height = dst_surface->height0; compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface ( compositor->pipe->screen, @@ -477,8 +477,8 @@ void vl_compositor_render(struct vl_compositor *compositor, compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state); compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport); compositor->pipe->set_scissor_state(compositor->pipe, &compositor->scissor); - compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler); - compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface); + compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler); + compositor->pipe->set_fragment_sampler_textures(compositor->pipe, 1, &src_surface); compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader); compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs); @@ -502,12 +502,12 @@ void vl_compositor_render(struct vl_compositor *compositor, vs_consts->dst_trans.z = 0; vs_consts->dst_trans.w = 0; - vs_consts->src_scale.x = src_area->w / (float)src_surface->width[0]; - vs_consts->src_scale.y = src_area->h / (float)src_surface->height[0]; + vs_consts->src_scale.x = src_area->w / (float)src_surface->width0; + vs_consts->src_scale.y = src_area->h / (float)src_surface->height0; vs_consts->src_scale.z = 1; vs_consts->src_scale.w = 1; - vs_consts->src_trans.x = src_area->x / (float)src_surface->width[0]; - vs_consts->src_trans.y = src_area->y / (float)src_surface->height[0]; + vs_consts->src_trans.x = src_area->x / (float)src_surface->width0; + vs_consts->src_trans.y = src_area->y / (float)src_surface->height0; vs_consts->src_trans.z = 0; vs_consts->src_trans.w = 0; diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index 7d5ecbc73da..85fe2efd2b6 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -675,7 +675,7 @@ xfer_buffers_map(struct vl_mpeg12_mc_renderer *r) ( r->pipe->screen, r->textures.all[i], 0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, - r->textures.all[i]->width[0], r->textures.all[i]->height[0] + r->textures.all[i]->width0, r->textures.all[i]->height0 ); r->texels[i] = r->pipe->screen->transfer_map(r->pipe->screen, r->tex_transfer[i]); @@ -829,26 +829,26 @@ init_buffers(struct vl_mpeg12_mc_renderer *r) /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */ template.format = PIPE_FORMAT_R16_SNORM; template.last_level = 0; - template.width[0] = r->pot_buffers ? + template.width0 = r->pot_buffers ? util_next_power_of_two(r->picture_width) : r->picture_width; - template.height[0] = r->pot_buffers ? + template.height0 = r->pot_buffers ? util_next_power_of_two(r->picture_height) : r->picture_height; - template.depth[0] = 1; + template.depth0 = 1; pf_get_block(template.format, &template.block); template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC; r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template); if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - template.width[0] = r->pot_buffers ? + template.width0 = r->pot_buffers ? util_next_power_of_two(r->picture_width / 2) : r->picture_width / 2; - template.height[0] = r->pot_buffers ? + template.height0 = r->pot_buffers ? util_next_power_of_two(r->picture_height / 2) : r->picture_height / 2; } else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) - template.height[0] = r->pot_buffers ? + template.height0 = r->pot_buffers ? util_next_power_of_two(r->picture_height / 2) : r->picture_height / 2; @@ -1277,8 +1277,8 @@ flush(struct vl_mpeg12_mc_renderer *r) PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD ); - vs_consts->denorm.x = r->surface->width[0]; - vs_consts->denorm.y = r->surface->height[0]; + vs_consts->denorm.x = r->surface->width0; + vs_consts->denorm.y = r->surface->height0; pipe_buffer_unmap(r->pipe->screen, r->vs_const_buf.buffer); @@ -1290,8 +1290,8 @@ flush(struct vl_mpeg12_mc_renderer *r) if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) { r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems); - r->pipe->set_sampler_textures(r->pipe, 3, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 3, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->i_vs); r->pipe->bind_fs_state(r->pipe, r->i_fs); @@ -1304,8 +1304,8 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->past; - r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->p_vs[0]); r->pipe->bind_fs_state(r->pipe, r->p_fs[0]); @@ -1318,8 +1318,8 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->past; - r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->p_vs[1]); r->pipe->bind_fs_state(r->pipe, r->p_fs[1]); @@ -1332,8 +1332,8 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->future; - r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->p_vs[0]); r->pipe->bind_fs_state(r->pipe, r->p_fs[0]); @@ -1346,8 +1346,8 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->future; - r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->p_vs[1]); r->pipe->bind_fs_state(r->pipe, r->p_fs[1]); @@ -1361,8 +1361,8 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); r->textures.individual.ref[0] = r->past; r->textures.individual.ref[1] = r->future; - r->pipe->set_sampler_textures(r->pipe, 5, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 5, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->b_vs[0]); r->pipe->bind_fs_state(r->pipe, r->b_fs[0]); @@ -1376,8 +1376,8 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); r->textures.individual.ref[0] = r->past; r->textures.individual.ref[1] = r->future; - r->pipe->set_sampler_textures(r->pipe, 5, r->textures.all); - r->pipe->bind_sampler_states(r->pipe, 5, r->samplers.all); + r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all); + r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all); r->pipe->bind_vs_state(r->pipe, r->b_vs[1]); r->pipe->bind_fs_state(r->pipe, r->b_fs[1]); @@ -1627,8 +1627,8 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer renderer->past = past; renderer->future = future; renderer->fence = fence; - renderer->surface_tex_inv_size.x = 1.0f / surface->width[0]; - renderer->surface_tex_inv_size.y = 1.0f / surface->height[0]; + renderer->surface_tex_inv_size.x = 1.0f / surface->width0; + renderer->surface_tex_inv_size.y = 1.0f / surface->height0; } while (num_macroblocks) { diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index ccd0fef6e84..c18a5d0635e 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -383,10 +383,10 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.delete_blend_state = cell_delete_blend_state; cell->pipe.create_sampler_state = cell_create_sampler_state; - cell->pipe.bind_sampler_states = cell_bind_sampler_states; + cell->pipe.bind_fragment_sampler_states = cell_bind_sampler_states; cell->pipe.delete_sampler_state = cell_delete_sampler_state; - cell->pipe.set_sampler_textures = cell_set_sampler_textures; + cell->pipe.set_fragment_sampler_textures = cell_set_sampler_textures; cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 9479c0898fd..ac5fafec1ad 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -27,6 +27,7 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" +#include "util/u_math.h" #include "cell_context.h" #include "cell_gen_fragment.h" #include "cell_state.h" @@ -299,9 +300,9 @@ cell_emit_state(struct cell_context *cell) for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) { texture->start[level] = (ct->mapped + ct->level_offset[level]); - texture->width[level] = ct->base.width[level]; - texture->height[level] = ct->base.height[level]; - texture->depth[level] = ct->base.depth[level]; + texture->width[level] = u_minify(ct->base.width0, level); + texture->height[level] = u_minify(ct->base.height0, level); + texture->depth[level] = u_minify(ct->base.depth0, level); } texture->target = ct->base.target; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index ae4c61efb3b..e6b8a870452 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -49,9 +49,9 @@ cell_texture_layout(struct cell_texture *ct) { struct pipe_texture *pt = &ct->base; unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; ct->buffer_size = 0; @@ -65,9 +65,6 @@ cell_texture_layout(struct cell_texture *ct) w_tile = align(width, TILE_SIZE); h_tile = align(height, TILE_SIZE); - pt->width[level] = width; - pt->height[level] = height; - pt->depth[level] = depth; pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w_tile); pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h_tile); @@ -83,9 +80,9 @@ cell_texture_layout(struct cell_texture *ct) ct->buffer_size += size; - width = minify(width); - height = minify(height); - depth = minify(depth); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } } @@ -276,8 +273,8 @@ cell_get_tex_surface(struct pipe_screen *screen, pipe_reference_init(&ps->reference, 1); pipe_texture_reference(&ps->texture, pt); ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; + ps->width = u_minify(pt->width0, level); + ps->height = u_minify(pt->height0, level); ps->offset = ct->level_offset[level]; /* XXX may need to override usage flags (see sp_texture.c) */ ps->usage = usage; @@ -386,8 +383,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) struct pipe_texture *pt = transfer->texture; struct cell_texture *ct = cell_texture(pt); const uint level = ctrans->base.level; - const uint texWidth = pt->width[level]; - const uint texHeight = pt->height[level]; + const uint texWidth = u_minify(pt->width0, level); + const uint texHeight = u_minify(pt->height0, level); const uint stride = ct->stride[level]; unsigned size; @@ -440,8 +437,8 @@ cell_transfer_unmap(struct pipe_screen *screen, struct pipe_texture *pt = transfer->texture; struct cell_texture *ct = cell_texture(pt); const uint level = ctrans->base.level; - const uint texWidth = pt->width[level]; - const uint texHeight = pt->height[level]; + const uint texWidth = u_minify(pt->width0, level); + const uint texHeight = u_minify(pt->height0, level); const uint stride = ct->stride[level]; if (!ct->mapped) { diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 9ba86ba8664..149393712a3 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -72,6 +72,7 @@ struct failover_context { */ const struct fo_state *blend; const struct fo_state *sampler[PIPE_MAX_SAMPLERS]; + const struct fo_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; const struct fo_state *depth_stencil; const struct fo_state *rasterizer; const struct fo_state *fragment_shader; @@ -83,6 +84,7 @@ struct failover_context { struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; @@ -92,11 +94,15 @@ struct failover_context { void *sw_sampler_state[PIPE_MAX_SAMPLERS]; void *hw_sampler_state[PIPE_MAX_SAMPLERS]; + void *sw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS]; + void *hw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS]; unsigned dirty; unsigned num_samplers; + unsigned num_vertex_samplers; unsigned num_textures; + unsigned num_vertex_textures; unsigned mode; struct pipe_context *hw; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index c8eb9262994..3f5f5560323 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -322,8 +322,9 @@ failover_create_sampler_state(struct pipe_context *pipe, } static void -failover_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) +failover_bind_fragment_sampler_states(struct pipe_context *pipe, + unsigned num, + void **sampler) { struct failover_context *failover = failover_context(pipe); struct fo_state *state = (struct fo_state*)sampler; @@ -339,10 +340,40 @@ failover_bind_sampler_states(struct pipe_context *pipe, } failover->dirty |= FO_NEW_SAMPLER; failover->num_samplers = num; - failover->sw->bind_sampler_states(failover->sw, num, - failover->sw_sampler_state); - failover->hw->bind_sampler_states(failover->hw, num, - failover->hw_sampler_state); + failover->sw->bind_fragment_sampler_states(failover->sw, num, + failover->sw_sampler_state); + failover->hw->bind_fragment_sampler_states(failover->hw, num, + failover->hw_sampler_state); +} + +static void +failover_bind_vertex_sampler_states(struct pipe_context *pipe, + unsigned num_samplers, + void **samplers) +{ + struct failover_context *failover = failover_context(pipe); + struct fo_state *state = (struct fo_state*)samplers; + uint i; + + assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS); + + /* Check for no-op */ + if (num_samplers == failover->num_vertex_samplers && + !memcmp(failover->vertex_samplers, samplers, num_samplers * sizeof(void *))) { + return; + } + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + failover->sw_vertex_sampler_state[i] = i < num_samplers ? state[i].sw_state : NULL; + failover->hw_vertex_sampler_state[i] = i < num_samplers ? state[i].hw_state : NULL; + } + failover->dirty |= FO_NEW_SAMPLER; + failover->num_vertex_samplers = num_samplers; + failover->sw->bind_vertex_sampler_states(failover->sw, + num_samplers, + failover->sw_vertex_sampler_state); + failover->hw->bind_vertex_sampler_states(failover->hw, + num_samplers, + failover->hw_vertex_sampler_state); } static void @@ -360,9 +391,9 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) static void -failover_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) +failover_set_fragment_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) { struct failover_context *failover = failover_context(pipe); uint i; @@ -381,8 +412,38 @@ failover_set_sampler_textures(struct pipe_context *pipe, NULL); failover->dirty |= FO_NEW_TEXTURE; failover->num_textures = num; - failover->sw->set_sampler_textures( failover->sw, num, texture ); - failover->hw->set_sampler_textures( failover->hw, num, texture ); + failover->sw->set_fragment_sampler_textures( failover->sw, num, texture ); + failover->hw->set_fragment_sampler_textures( failover->hw, num, texture ); +} + + +static void +failover_set_vertex_sampler_textures(struct pipe_context *pipe, + unsigned num_textures, + struct pipe_texture **textures) +{ + struct failover_context *failover = failover_context(pipe); + uint i; + + assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); + + /* Check for no-op */ + if (num_textures == failover->num_vertex_textures && + !memcmp(failover->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { + return; + } + for (i = 0; i < num_textures; i++) { + pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i], + textures[i]); + } + for (i = num_textures; i < failover->num_vertex_textures; i++) { + pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i], + NULL); + } + failover->dirty |= FO_NEW_TEXTURE; + failover->num_vertex_textures = num_textures; + failover->sw->set_vertex_sampler_textures(failover->sw, num_textures, textures); + failover->hw->set_vertex_sampler_textures(failover->hw, num_textures, textures); } @@ -453,7 +514,8 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.bind_blend_state = failover_bind_blend_state; failover->pipe.delete_blend_state = failover_delete_blend_state; failover->pipe.create_sampler_state = failover_create_sampler_state; - failover->pipe.bind_sampler_states = failover_bind_sampler_states; + failover->pipe.bind_fragment_sampler_states = failover_bind_fragment_sampler_states; + failover->pipe.bind_vertex_sampler_states = failover_bind_vertex_sampler_states; failover->pipe.delete_sampler_state = failover_delete_sampler_state; failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state; failover->pipe.bind_depth_stencil_alpha_state = failover_bind_depth_stencil_state; @@ -473,7 +535,8 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; failover->pipe.set_scissor_state = failover_set_scissor_state; - failover->pipe.set_sampler_textures = failover_set_sampler_textures; + failover->pipe.set_fragment_sampler_textures = failover_set_fragment_sampler_textures; + failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; failover->pipe.set_vertex_elements = failover_set_vertex_elements; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index bd4fce9d209..a3341e33f80 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -92,13 +92,19 @@ failover_state_emit( struct failover_context *failover ) failover->sw->set_viewport_state( failover->sw, &failover->viewport ); if (failover->dirty & FO_NEW_SAMPLER) { - failover->sw->bind_sampler_states( failover->sw, failover->num_samplers, - failover->sw_sampler_state ); + failover->sw->bind_fragment_sampler_states( failover->sw, failover->num_samplers, + failover->sw_sampler_state ); + failover->sw->bind_vertex_sampler_states(failover->sw, + failover->num_vertex_samplers, + failover->sw_vertex_sampler_state); } if (failover->dirty & FO_NEW_TEXTURE) { - failover->sw->set_sampler_textures( failover->sw, failover->num_textures, - failover->texture ); + failover->sw->set_fragment_sampler_textures( failover->sw, failover->num_textures, + failover->texture ); + failover->sw->set_vertex_sampler_textures(failover->sw, + failover->num_vertex_textures, + failover->vertex_textures); } if (failover->dirty & FO_NEW_VERTEX_BUFFER) { diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 71f00bc346a..9103847f1c5 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -767,7 +767,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.delete_blend_state = i915_delete_blend_state; i915->base.create_sampler_state = i915_create_sampler_state; - i915->base.bind_sampler_states = i915_bind_sampler_states; + i915->base.bind_fragment_sampler_states = i915_bind_sampler_states; i915->base.delete_sampler_state = i915_delete_sampler_state; i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; @@ -791,7 +791,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.set_polygon_stipple = i915_set_polygon_stipple; i915->base.set_scissor_state = i915_set_scissor_state; - i915->base.set_sampler_textures = i915_set_sampler_textures; + i915->base.set_fragment_sampler_textures = i915_set_sampler_textures; i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_vertex_buffers = i915_set_vertex_buffers; i915->base.set_vertex_elements = i915_set_vertex_elements; diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index c5e9084d12e..cbac4175c8f 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -231,7 +231,7 @@ i915_update_texture(struct i915_context *i915, { const struct pipe_texture *pt = &tex->base; uint format, pitch; - const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + const uint width = pt->width0, height = pt->height0, depth = pt->depth0; const uint num_levels = pt->last_level; unsigned max_lod = num_levels * 4; unsigned tiled = MS3_USE_FENCE_REGS; diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c index 286c9ace8e5..c7b86dd4c57 100644 --- a/src/gallium/drivers/i915/i915_texture.c +++ b/src/gallium/drivers/i915/i915_texture.c @@ -105,10 +105,6 @@ i915_miptree_set_level_info(struct i915_texture *tex, assert(level < PIPE_MAX_TEXTURE_LEVELS); - pt->width[level] = w; - pt->height[level] = h; - pt->depth[level] = d; - pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w); pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h); @@ -168,16 +164,16 @@ i915_scanout_layout(struct i915_texture *tex) return FALSE; i915_miptree_set_level_info(tex, 0, 1, - tex->base.width[0], - tex->base.height[0], + tex->base.width0, + tex->base.height0, 1); i915_miptree_set_image_offset(tex, 0, 0, 0, 0); - if (tex->base.width[0] >= 240) { + if (tex->base.width0 >= 240) { tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); tex->hw_tiled = INTEL_TILE_X; - } else if (tex->base.width[0] == 64 && tex->base.height[0] == 64) { + } else if (tex->base.width0 == 64 && tex->base.height0 == 64) { tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); } else { @@ -185,7 +181,7 @@ i915_scanout_layout(struct i915_texture *tex) } debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - tex->base.width[0], tex->base.height[0], pt->block.size, + tex->base.width0, tex->base.height0, pt->block.size, tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); return TRUE; @@ -203,12 +199,12 @@ i915_display_target_layout(struct i915_texture *tex) return FALSE; /* fallback to normal textures for small textures */ - if (tex->base.width[0] < 240) + if (tex->base.width0 < 240) return FALSE; i915_miptree_set_level_info(tex, 0, 1, - tex->base.width[0], - tex->base.height[0], + tex->base.width0, + tex->base.height0, 1); i915_miptree_set_image_offset(tex, 0, 0, 0, 0); @@ -217,7 +213,7 @@ i915_display_target_layout(struct i915_texture *tex) tex->hw_tiled = INTEL_TILE_X; debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - tex->base.width[0], tex->base.height[0], pt->block.size, + tex->base.width0, tex->base.height0, pt->block.size, tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); return TRUE; @@ -228,8 +224,8 @@ i915_miptree_layout_2d(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; @@ -254,8 +250,8 @@ i915_miptree_layout_2d(struct i915_texture *tex) tex->total_nblocksy += nblocksy; - width = minify(width); - height = minify(height); + width = u_minify(width, 1); + height = u_minify(height, 1); nblocksx = pf_get_nblocksx(&pt->block, width); nblocksy = pf_get_nblocksy(&pt->block, height); } @@ -267,9 +263,9 @@ i915_miptree_layout_3d(struct i915_texture *tex) struct pipe_texture *pt = &tex->base; unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; unsigned stack_nblocksy = 0; @@ -285,36 +281,34 @@ i915_miptree_layout_3d(struct i915_texture *tex) stack_nblocksy += MAX2(2, nblocksy); - width = minify(width); - height = minify(height); - depth = minify(depth); + width = u_minify(width, 1); + height = u_minify(height, 1); nblocksx = pf_get_nblocksx(&pt->block, width); nblocksy = pf_get_nblocksy(&pt->block, height); } /* Fixup depth image_offsets: */ - depth = pt->depth[0]; for (level = 0; level <= pt->last_level; level++) { unsigned i; for (i = 0; i < depth; i++) i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy); - depth = minify(depth); + depth = u_minify(depth, 1); } /* Multiply slice size by texture depth for total size. It's * remarkable how wasteful of memory the i915 texture layouts * are. They are largely fixed in the i945. */ - tex->total_nblocksy = stack_nblocksy * pt->depth[0]; + tex->total_nblocksy = stack_nblocksy * pt->depth0; } static void i915_miptree_layout_cube(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; - unsigned width = pt->width[0], height = pt->height[0]; + unsigned width = pt->width0, height = pt->height0; const unsigned nblocks = pt->nblocksx[0]; unsigned level; unsigned face; @@ -383,8 +377,8 @@ i945_miptree_layout_2d(struct i915_texture *tex) unsigned level; unsigned x = 0; unsigned y = 0; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; @@ -407,8 +401,8 @@ i945_miptree_layout_2d(struct i915_texture *tex) */ if (pt->last_level > 0) { unsigned mip1_nblocksx - = align(pf_get_nblocksx(&pt->block, minify(width)), align_x) - + pf_get_nblocksx(&pt->block, minify(minify(width))); + = align(pf_get_nblocksx(&pt->block, u_minify(width, 1)), align_x) + + pf_get_nblocksx(&pt->block, u_minify(width, 2)); if (mip1_nblocksx > nblocksx) tex->stride = mip1_nblocksx * pt->block.size; @@ -439,8 +433,8 @@ i945_miptree_layout_2d(struct i915_texture *tex) y += nblocksy; } - width = minify(width); - height = minify(height); + width = u_minify(width, 1); + height = u_minify(height, 1); nblocksx = pf_get_nblocksx(&pt->block, width); nblocksy = pf_get_nblocksy(&pt->block, height); } @@ -450,9 +444,9 @@ static void i945_miptree_layout_3d(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; unsigned pack_x_pitch, pack_x_nr; @@ -495,9 +489,9 @@ i945_miptree_layout_3d(struct i915_texture *tex) pack_y_pitch >>= 1; } - width = minify(width); - height = minify(height); - depth = minify(depth); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); nblocksx = pf_get_nblocksx(&pt->block, width); nblocksy = pf_get_nblocksy(&pt->block, height); } @@ -511,11 +505,11 @@ i945_miptree_layout_cube(struct i915_texture *tex) const unsigned nblocks = pt->nblocksx[0]; unsigned face; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; /* - printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]); + printf("%s %i, %i\n", __FUNCTION__, pt->width0, pt->height0); */ assert(width == height); /* cubemap images are square */ @@ -651,8 +645,8 @@ i915_texture_create(struct pipe_screen *screen, pipe_reference_init(&tex->base.reference, 1); tex->base.screen = screen; - tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]); - tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]); + tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width0); + tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height0); if (is->is_i945) { if (!i945_miptree_layout(tex)) @@ -667,7 +661,7 @@ i915_texture_create(struct pipe_screen *screen, /* for scanouts and cursors, cursors arn't scanouts */ - if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width[0] != 64) + if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64) buf_usage = INTEL_NEW_SCANOUT; else buf_usage = INTEL_NEW_TEXTURE; @@ -710,7 +704,7 @@ i915_texture_blanket(struct pipe_screen * screen, /* Only supports one type */ if (base->target != PIPE_TEXTURE_2D || base->last_level != 0 || - base->depth[0] != 1) { + base->depth0 != 1) { return NULL; } @@ -724,7 +718,7 @@ i915_texture_blanket(struct pipe_screen * screen, tex->stride = stride[0]; - i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1); + i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1); i915_miptree_set_image_offset(tex, 0, 0, 0, 0); pipe_buffer_reference(&tex->buffer, buffer); @@ -788,8 +782,8 @@ i915_get_tex_surface(struct pipe_screen *screen, pipe_reference_init(&ps->reference, 1); pipe_texture_reference(&ps->texture, pt); ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; + ps->width = u_minify(pt->width0, level); + ps->height = u_minify(pt->height0, level); ps->offset = offset; ps->usage = flags; } @@ -919,7 +913,7 @@ i915_texture_blanket_intel(struct pipe_screen *screen, /* Only supports one type */ if (base->target != PIPE_TEXTURE_2D || base->last_level != 0 || - base->depth[0] != 1) { + base->depth0 != 1) { return NULL; } @@ -933,7 +927,7 @@ i915_texture_blanket_intel(struct pipe_screen *screen, tex->stride = stride; - i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1); + i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1); i915_miptree_set_image_offset(tex, 0, 0, 0, 0); tex->buffer = buffer; diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 4e700089e33..4509c7b1e5c 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -221,16 +221,29 @@ identity_create_sampler_state(struct pipe_context *_pipe, } static void -identity_bind_sampler_states(struct pipe_context *_pipe, - unsigned num, - void **samplers) +identity_bind_fragment_sampler_states(struct pipe_context *_pipe, + unsigned num_samplers, + void **samplers) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - pipe->bind_sampler_states(pipe, - num, - samplers); + pipe->bind_fragment_sampler_states(pipe, + num_samplers, + samplers); +} + +static void +identity_bind_vertex_sampler_states(struct pipe_context *_pipe, + unsigned num_samplers, + void **samplers) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_vertex_sampler_states(pipe, + num_samplers, + samplers); } static void @@ -480,9 +493,9 @@ identity_set_viewport_state(struct pipe_context *_pipe, } static void -identity_set_sampler_textures(struct pipe_context *_pipe, - unsigned num_textures, - struct pipe_texture **_textures) +identity_set_fragment_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **_textures) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; @@ -499,9 +512,34 @@ identity_set_sampler_textures(struct pipe_context *_pipe, textures = unwrapped_textures; } - pipe->set_sampler_textures(pipe, - num_textures, - textures); + pipe->set_fragment_sampler_textures(pipe, + num_textures, + textures); +} + +static void +identity_set_vertex_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **_textures) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_texture **textures = NULL; + unsigned i; + + if (_textures) { + for (i = 0; i < num_textures; i++) + unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); + for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++) + unwrapped_textures[i] = NULL; + + textures = unwrapped_textures; + } + + pipe->set_vertex_sampler_textures(pipe, + num_textures, + textures); } static void @@ -682,7 +720,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.bind_blend_state = identity_bind_blend_state; id_pipe->base.delete_blend_state = identity_delete_blend_state; id_pipe->base.create_sampler_state = identity_create_sampler_state; - id_pipe->base.bind_sampler_states = identity_bind_sampler_states; + id_pipe->base.bind_fragment_sampler_states = identity_bind_fragment_sampler_states; + id_pipe->base.bind_vertex_sampler_states = identity_bind_vertex_sampler_states; id_pipe->base.delete_sampler_state = identity_delete_sampler_state; id_pipe->base.create_rasterizer_state = identity_create_rasterizer_state; id_pipe->base.bind_rasterizer_state = identity_bind_rasterizer_state; @@ -703,7 +742,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple; id_pipe->base.set_scissor_state = identity_set_scissor_state; id_pipe->base.set_viewport_state = identity_set_viewport_state; - id_pipe->base.set_sampler_textures = identity_set_sampler_textures; + id_pipe->base.set_fragment_sampler_textures = identity_set_vertex_sampler_textures; + id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures; id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; id_pipe->base.set_vertex_elements = identity_set_vertex_elements; id_pipe->base.surface_copy = identity_surface_copy; diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index 89d08834a3c..0c3f00fd58f 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -51,21 +51,22 @@ Requirements - Linux - - udis86, http://udis86.sourceforge.net/ . Use my repository, which decodes - opcodes not yet supported by upstream. + - A x86 or amd64 processor. 64bit mode is preferred. - git clone git://people.freedesktop.org/~jrfonseca/udis86 - cd udis86 - ./configure --with-pic - make - sudo make install + Support for sse2 is strongly encouraged. Support for ssse3, and sse4.1 will + yield the most efficient code. The less features the CPU has the more + likely is that you ran into underperforming, buggy, or incomplete code. + + See /proc/cpuinfo to know what your CPU supports. + + - LLVM 2.5 or greater. LLVM 2.6 is preferred. - - LLVM 2.5. On Debian based distributions do: + On Debian based distributions do: aptitude install llvm-dev - There is a typo in one of the llvm-dev 2.5 headers, that causes compilation - errors in the debug build: + There is a typo in one of the llvm 2.5 headers, that may cause compilation + errors. To fix it apply the change: --- /usr/include/llvm-c/Core.h.orig 2009-08-10 15:38:54.000000000 +0100 +++ /usr/include/llvm-c/Core.h 2009-08-10 15:38:25.000000000 +0100 @@ -79,12 +80,17 @@ Requirements #endif return reinterpret_cast<T**>(Vals); - - A x86 or amd64 processor with support for sse2, sse3, and sse4.1 SIMD - instructions. This is necessary because we emit several SSE intrinsics for - convenience. See /proc/cpuinfo to know what your CPU supports. - - - scons + - scons (optional) + - udis86, http://udis86.sourceforge.net/ (optional): + + git clone git://udis86.git.sourceforge.net/gitroot/udis86/udis86 + cd udis86 + ./autogen.sh + ./configure --with-pic + make + sudo make install + Building ======== diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index 98ec1cb1b9d..d438c0e63d7 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -90,7 +90,7 @@ lp_depth_type(const struct util_format_description *format_desc, if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) { type.floating = TRUE; - assert(swizzle = 0); + assert(swizzle == 0); assert(format_desc->channel[swizzle].size == format_desc->block.bits); } else if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED) { diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample.c b/src/gallium/drivers/llvmpipe/lp_bld_sample.c index 4d272bea87e..af70ddc6ab9 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_sample.c @@ -59,9 +59,9 @@ lp_sampler_static_state(struct lp_sampler_static_state *state, state->format = texture->format; state->target = texture->target; - state->pot_width = util_is_pot(texture->width[0]); - state->pot_height = util_is_pot(texture->height[0]); - state->pot_depth = util_is_pot(texture->depth[0]); + state->pot_width = util_is_pot(texture->width0); + state->pot_height = util_is_pot(texture->height0); + state->pot_depth = util_is_pot(texture->depth0); state->wrap_s = sampler->wrap_s; state->wrap_t = sampler->wrap_t; diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 57e71f3e986..c081f6de036 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -180,7 +180,7 @@ llvmpipe_create( struct pipe_screen *screen ) llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state; llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state; - llvmpipe->pipe.bind_sampler_states = llvmpipe_bind_sampler_states; + llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states; llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state; llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state; @@ -205,7 +205,7 @@ llvmpipe_create( struct pipe_screen *screen ) llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state; llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple; llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state; - llvmpipe->pipe.set_sampler_textures = llvmpipe_set_sampler_textures; + llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures; llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state; llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 13535dd638e..bce3baec164 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -154,6 +154,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) #if 0 /* For simulating less capable machines */ util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_ssse3 = 0; util_cpu_caps.has_sse4_1 = 0; #endif @@ -167,7 +168,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) { _debug_printf("%s\n", error); LLVMDisposeMessage(error); - abort(); + assert(0); } screen->target = LLVMGetExecutionEngineTargetData(screen->engine); diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 05189274589..0fb133486aa 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -27,6 +27,7 @@ #include "util/u_memory.h" +#include "util/u_format.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" @@ -131,17 +132,17 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct llvmpipe_winsys *winsys = screen->winsys; + const struct util_format_description *format_desc; + + format_desc = util_format_description(format); + if(!format_desc) + return FALSE; assert(target == PIPE_TEXTURE_1D || target == PIPE_TEXTURE_2D || target == PIPE_TEXTURE_3D || target == PIPE_TEXTURE_CUBE); - if(format == PIPE_FORMAT_Z16_UNORM) - return FALSE; - if(format == PIPE_FORMAT_S8_UNORM) - return FALSE; - switch(format) { case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: @@ -152,8 +153,51 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, break; } - if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) - return winsys->is_displaytarget_format_supported(winsys, format); + if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + if(format_desc->block.width != 1 || + format_desc->block.height != 1) + return FALSE; + + if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR && + format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH && + format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) + return FALSE; + + if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB && + format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) + return FALSE; + } + + if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if(!winsys->is_displaytarget_format_supported(winsys, format)) + return FALSE; + } + + if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { + if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) + return FALSE; + + /* FIXME: Temporary restriction. See lp_state_fs.c. */ + if(format_desc->block.bits != 32) + return FALSE; + } + + /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */ + if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) { + if(format_desc->block.width != 1 || + format_desc->block.height != 1) + return FALSE; + + if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR && + format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH && + format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) + return FALSE; + + if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB && + format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && + format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) + return FALSE; + } return TRUE; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 2e9aa9fffe3..ee0f69b2af9 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -148,6 +148,20 @@ generate_depth(LLVMBuilderRef builder, format_desc = util_format_description(key->zsbuf_format); assert(format_desc); + /* + * Depths are expected to be between 0 and 1, even if they are stored in + * floats. Setting these bits here will ensure that the lp_build_conv() call + * below won't try to unnecessarily clamp the incoming values. + */ + if(src_type.floating) { + src_type.sign = FALSE; + src_type.norm = TRUE; + } + else { + assert(!src_type.sign); + assert(src_type.norm); + } + /* Pick the depth type. */ dst_type = lp_depth_type(format_desc, src_type.width*src_type.length); @@ -155,14 +169,11 @@ generate_depth(LLVMBuilderRef builder, assert(dst_type.width == src_type.width); assert(dst_type.length == src_type.length); -#if 1 - src = lp_build_clamped_float_to_unsigned_norm(builder, - src_type, - dst_type.width, - src); -#else lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1); -#endif + + dst_ptr = LLVMBuildBitCast(builder, + dst_ptr, + LLVMPointerType(lp_build_vec_type(dst_type), 0), ""); lp_build_depth_test(builder, &key->depth, @@ -611,10 +622,12 @@ generate_fragment(struct llvmpipe_context *lp, * Translate the LLVM IR into machine code. */ +#ifdef DEBUG if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { LLVMDumpValue(variant->function); - abort(); + assert(0); } +#endif LLVMRunFunctionPassManager(screen->pass, variant->function); diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index c69d90c723a..8333805a3fd 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -102,8 +102,8 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe, if(tex) { struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i]; - jit_tex->width = tex->width[0]; - jit_tex->height = tex->height[0]; + jit_tex->width = tex->width0; + jit_tex->height = tex->height0; jit_tex->stride = lp_tex->stride[0]; if(!lp_tex->dt) jit_tex->data = lp_tex->data; diff --git a/src/gallium/drivers/llvmpipe/lp_state_vs.c b/src/gallium/drivers/llvmpipe/lp_state_vs.c index 15c30296144..8a761648e7e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_vs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_vs.c @@ -92,5 +92,6 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs) (struct lp_vertex_shader *)vs; draw_delete_vertex_shader(llvmpipe->draw, state->draw_data); + FREE( (void *)state->shader.tokens ); FREE( state ); } diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.c b/src/gallium/drivers/llvmpipe/lp_tex_cache.c index 773e8482425..c7c4143bc62 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_cache.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.c @@ -36,6 +36,7 @@ #include "util/u_memory.h" #include "util/u_tile.h" #include "util/u_format.h" +#include "util/u_math.h" #include "lp_context.h" #include "lp_surface.h" #include "lp_texture.h" @@ -270,8 +271,8 @@ lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, addr.bits.level, addr.bits.z, PIPE_TRANSFER_READ, 0, 0, - tc->texture->width[addr.bits.level], - tc->texture->height[addr.bits.level]); + u_minify(tc->texture->width0, addr.bits.level), + u_minify(tc->texture->height0, addr.bits.level)); tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c index a1365a045f1..0d01c07fb5e 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c @@ -544,7 +544,7 @@ compute_lambda(struct tgsi_sampler *tgsi_sampler, float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; dsdx = fabsf(dsdx); dsdy = fabsf(dsdy); - rho = MAX2(dsdx, dsdy) * texture->width[0]; + rho = MAX2(dsdx, dsdy) * texture->width0; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -552,7 +552,7 @@ compute_lambda(struct tgsi_sampler *tgsi_sampler, float max; dtdx = fabsf(dtdx); dtdy = fabsf(dtdy); - max = MAX2(dtdx, dtdy) * texture->height[0]; + max = MAX2(dtdx, dtdy) * texture->height0; rho = MAX2(rho, max); } if (p) { @@ -561,7 +561,7 @@ compute_lambda(struct tgsi_sampler *tgsi_sampler, float max; dpdx = fabsf(dpdx); dpdy = fabsf(dpdy); - max = MAX2(dpdx, dpdy) * texture->depth[0]; + max = MAX2(dpdx, dpdy) * texture->depth0; rho = MAX2(rho, max); } @@ -726,9 +726,9 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, const struct pipe_texture *texture = samp->texture; const struct pipe_sampler_state *sampler = samp->sampler; - if (x < 0 || x >= (int) texture->width[level] || - y < 0 || y >= (int) texture->height[level] || - z < 0 || z >= (int) texture->depth[level]) { + if (x < 0 || x >= (int) u_minify(texture->width0, level) || + y < 0 || y >= (int) u_minify(texture->height0, level) || + z < 0 || z >= (int) u_minify(texture->depth0, level)) { rgba[0][j] = sampler->border_color[0]; rgba[1][j] = sampler->border_color[1]; rgba[2][j] = sampler->border_color[2]; @@ -1093,8 +1093,8 @@ lp_get_samples_2d_common(struct tgsi_sampler *tgsi_sampler, assert(sampler->normalized_coords); - width = texture->width[level0]; - height = texture->height[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); assert(width > 0); @@ -1250,9 +1250,9 @@ lp_get_samples_3d(struct tgsi_sampler *tgsi_sampler, assert(sampler->normalized_coords); - width = texture->width[level0]; - height = texture->height[level0]; - depth = texture->depth[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); + depth = u_minify(texture->depth0, level0); assert(width > 0); assert(height > 0); @@ -1394,8 +1394,8 @@ lp_get_samples_rect(struct tgsi_sampler *tgsi_sampler, /* texture RECTS cannot be mipmapped */ assert(level0 == level1); - width = texture->width[level0]; - height = texture->height[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); assert(width > 0); @@ -1513,8 +1513,8 @@ lp_get_samples(struct tgsi_sampler *tgsi_sampler, /* Do this elsewhere: */ - samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); - samp->ypot = util_unsigned_logbase2( samp->texture->height[0] ); + samp->xpot = util_unsigned_logbase2( samp->texture->width0 ); + samp->ypot = util_unsigned_logbase2( samp->texture->height0 ); /* Try to hook in a faster sampler. Ultimately we'll have to * code-generate these. Luckily most of this looks like it is diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index a00f2495dfc..65d62fd0723 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -57,9 +57,9 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, { struct pipe_texture *pt = &lpt->base; unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; unsigned buffer_size = 0; @@ -68,9 +68,6 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, for (level = 0; level <= pt->last_level; level++) { unsigned nblocksx, nblocksy; - pt->width[level] = width; - pt->height[level] = height; - pt->depth[level] = depth; pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); @@ -87,9 +84,9 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * lpt->stride[level]); - width = minify(width); - height = minify(height); - depth = minify(depth); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } lpt->data = align_malloc(buffer_size, 16); @@ -104,13 +101,13 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, struct llvmpipe_winsys *winsys = screen->winsys; pf_get_block(lpt->base.format, &lpt->base.block); - lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]); - lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]); + lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width0); + lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height0); lpt->dt = winsys->displaytarget_create(winsys, lpt->base.format, - lpt->base.width[0], - lpt->base.height[0], + lpt->base.width0, + lpt->base.height0, 16, &lpt->stride[0] ); @@ -172,7 +169,7 @@ llvmpipe_texture_blanket(struct pipe_screen * screen, /* Only supports one type */ if (base->target != PIPE_TEXTURE_2D || base->last_level != 0 || - base->depth[0] != 1) { + base->depth0 != 1) { return NULL; } @@ -183,8 +180,8 @@ llvmpipe_texture_blanket(struct pipe_screen * screen, lpt->base = *base; pipe_reference_init(&lpt->base.reference, 1); lpt->base.screen = screen; - lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]); - lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]); + lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width0); + lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height0); lpt->stride[0] = stride[0]; pipe_buffer_reference(&lpt->buffer, buffer); @@ -229,8 +226,8 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, pipe_reference_init(&ps->reference, 1); pipe_texture_reference(&ps->texture, pt); ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; + ps->width = u_minify(pt->width0, level); + ps->height = u_minify(pt->height0, level); ps->offset = lpt->level_offset[level]; ps->usage = usage; diff --git a/src/gallium/drivers/nv04/nv04_fragtex.c b/src/gallium/drivers/nv04/nv04_fragtex.c index 21f990fd536..0cce71ad1de 100644 --- a/src/gallium/drivers/nv04/nv04_fragtex.c +++ b/src/gallium/drivers/nv04/nv04_fragtex.c @@ -57,8 +57,8 @@ nv04_fragtex_build(struct nv04_context *nv04, int unit) | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER | nv04_fragtex_format(pt->format) | ( (pt->last_level + 1) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT ) - | ( log2i(pt->width[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT ) - | ( log2i(pt->height[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT ) + | ( log2i(pt->width0) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT ) + | ( log2i(pt->height0) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT ) | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE ; diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 93f752faec9..4fd72c82e62 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" #include "nv04_context.h" #include "nv04_screen.h" @@ -9,31 +10,29 @@ static void nv04_miptree_layout(struct nv04_miptree *nv04mt) { struct pipe_texture *pt = &nv04mt->base; - uint width = pt->width[0], height = pt->height[0]; + uint width = pt->width0, height = pt->height0; uint offset = 0; int nr_faces, l; nr_faces = 1; for (l = 0; l <= pt->last_level; l++) { - pt->width[l] = width; - pt->height[l] = height; pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); - nv04mt->level[l].pitch = pt->width[0]; + nv04mt->level[l].pitch = pt->width0; nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63; - width = MAX2(1, width >> 1); - height = MAX2(1, height >> 1); + width = u_minify(width, 1); + height = u_minify(height, 1); } for (l = 0; l <= pt->last_level; l++) { nv04mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); - offset += nv04mt->level[l].pitch * pt->height[l]; + offset += nv04mt->level[l].pitch * u_minify(pt->height0, l); } nv04mt->total_size = offset; @@ -75,7 +74,7 @@ nv04_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, /* Only supports 2D, non-mipmapped textures for the moment */ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth[0] != 1) + pt->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv04_miptree); @@ -120,8 +119,8 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; pipe_texture_reference(&ns->base.texture, pt); ns->base.format = pt->format; - ns->base.width = pt->width[level]; - ns->base.height = pt->height[level]; + ns->base.width = u_minify(pt->width0, level); + ns->base.height = u_minify(pt->height0, level); ns->base.usage = flags; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c index d356ebd8b36..ef3005db5fc 100644 --- a/src/gallium/drivers/nv04/nv04_state.c +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -425,9 +425,9 @@ nv04_init_state_functions(struct nv04_context *nv04) nv04->pipe.delete_blend_state = nv04_blend_state_delete; nv04->pipe.create_sampler_state = nv04_sampler_state_create; - nv04->pipe.bind_sampler_states = nv04_sampler_state_bind; + nv04->pipe.bind_fragment_sampler_states = nv04_sampler_state_bind; nv04->pipe.delete_sampler_state = nv04_sampler_state_delete; - nv04->pipe.set_sampler_textures = nv04_set_sampler_texture; + nv04->pipe.set_fragment_sampler_textures = nv04_set_sampler_texture; nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create; nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c index 6618660743d..e6456429f4e 100644 --- a/src/gallium/drivers/nv04/nv04_transfer.c +++ b/src/gallium/drivers/nv04/nv04_transfer.c @@ -2,6 +2,7 @@ #include <pipe/p_defines.h> #include <pipe/p_inlines.h> #include <util/u_memory.h> +#include <util/u_math.h> #include <nouveau/nouveau_winsys.h> #include "nv04_context.h" #include "nv04_screen.h" @@ -20,9 +21,9 @@ nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, memset(template, 0, sizeof(struct pipe_texture)); template->target = pt->target; template->format = pt->format; - template->width[0] = pt->width[level]; - template->height[0] = pt->height[level]; - template->depth[0] = 1; + template->width0 = u_minify(pt->width0, level); + template->height0 = u_minify(pt->height0, level); + template->depth0 = 1; template->block = pt->block; template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c index 27f2f875847..906fdfeeb93 100644 --- a/src/gallium/drivers/nv10/nv10_fragtex.c +++ b/src/gallium/drivers/nv10/nv10_fragtex.c @@ -62,9 +62,9 @@ nv10_fragtex_build(struct nv10_context *nv10, int unit) txf = tf->format << 8; txf |= (pt->last_level + 1) << 16; - txf |= log2i(pt->width[0]) << 20; - txf |= log2i(pt->height[0]) << 24; - txf |= log2i(pt->depth[0]) << 28; + txf |= log2i(pt->width0) << 20; + txf |= log2i(pt->height0) << 24; + txf |= log2i(pt->depth0) << 28; txf |= 8; switch (pt->target) { @@ -89,7 +89,7 @@ nv10_fragtex_build(struct nv10_context *nv10, int unit) OUT_RING (0x40000000); /* enable */ OUT_RING (txs); OUT_RING (ps->filt | 0x2000 /* magic */); - OUT_RING ((pt->width[0] << 16) | pt->height[0]); + OUT_RING ((pt->width0 << 16) | pt->height0); OUT_RING (ps->bcol); #endif } diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index 34e3c2ebd77..b2a6c59b749 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" #include "nv10_context.h" #include "nv10_screen.h" @@ -10,7 +11,7 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) { struct pipe_texture *pt = &nv10mt->base; boolean swizzled = FALSE; - uint width = pt->width[0], height = pt->height[0]; + uint width = pt->width0, height = pt->height0; uint offset = 0; int nr_faces, l, f; @@ -21,8 +22,7 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) } for (l = 0; l <= pt->last_level; l++) { - pt->width[l] = width; - pt->height[l] = height; + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); @@ -35,15 +35,15 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) nv10mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); - width = MAX2(1, width >> 1); - height = MAX2(1, height >> 1); + width = u_minify(width, 1); + height = u_minify(height, 1); } for (f = 0; f < nr_faces; f++) { for (l = 0; l <= pt->last_level; l++) { nv10mt->level[l].image_offset[f] = offset; - offset += nv10mt->level[l].pitch * pt->height[l]; + offset += nv10mt->level[l].pitch * u_minify(pt->height0, l); } } @@ -58,7 +58,7 @@ nv10_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, /* Only supports 2D, non-mipmapped textures for the moment */ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth[0] != 1) + pt->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv10_miptree); @@ -133,8 +133,8 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, return NULL; pipe_texture_reference(&ns->base.texture, pt); ns->base.format = pt->format; - ns->base.width = pt->width[level]; - ns->base.height = pt->height[level]; + ns->base.width = u_minify(pt->width0, level); + ns->base.height = u_minify(pt->height0, level); ns->base.usage = flags; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 9b38219b996..ffc6be3c401 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -553,9 +553,9 @@ nv10_init_state_functions(struct nv10_context *nv10) nv10->pipe.delete_blend_state = nv10_blend_state_delete; nv10->pipe.create_sampler_state = nv10_sampler_state_create; - nv10->pipe.bind_sampler_states = nv10_sampler_state_bind; + nv10->pipe.bind_fragment_sampler_states = nv10_sampler_state_bind; nv10->pipe.delete_sampler_state = nv10_sampler_state_delete; - nv10->pipe.set_sampler_textures = nv10_set_sampler_texture; + nv10->pipe.set_fragment_sampler_textures = nv10_set_sampler_texture; nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create; nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c index 8feb85e4bda..ec54297ab01 100644 --- a/src/gallium/drivers/nv10/nv10_transfer.c +++ b/src/gallium/drivers/nv10/nv10_transfer.c @@ -2,6 +2,7 @@ #include <pipe/p_defines.h> #include <pipe/p_inlines.h> #include <util/u_memory.h> +#include <util/u_math.h> #include <nouveau/nouveau_winsys.h> #include "nv10_context.h" #include "nv10_screen.h" @@ -20,9 +21,9 @@ nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, memset(template, 0, sizeof(struct pipe_texture)); template->target = pt->target; template->format = pt->format; - template->width[0] = pt->width[level]; - template->height[0] = pt->height[level]; - template->depth[0] = 1; + template->width0 = u_minify(pt->width0, level); + template->height0 = u_minify(pt->height0, level); + template->depth0 = 1; template->block = pt->block; template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; diff --git a/src/gallium/drivers/nv20/nv20_fragtex.c b/src/gallium/drivers/nv20/nv20_fragtex.c index 495a7be9127..2db4a4015a6 100644 --- a/src/gallium/drivers/nv20/nv20_fragtex.c +++ b/src/gallium/drivers/nv20/nv20_fragtex.c @@ -62,9 +62,9 @@ nv20_fragtex_build(struct nv20_context *nv20, int unit) txf = tf->format << 8; txf |= (pt->last_level + 1) << 16; - txf |= log2i(pt->width[0]) << 20; - txf |= log2i(pt->height[0]) << 24; - txf |= log2i(pt->depth[0]) << 28; + txf |= log2i(pt->width0) << 20; + txf |= log2i(pt->height0) << 24; + txf |= log2i(pt->depth0) << 28; txf |= 8; switch (pt->target) { @@ -89,7 +89,7 @@ nv20_fragtex_build(struct nv20_context *nv20, int unit) OUT_RING (0x40000000); /* enable */ OUT_RING (txs); OUT_RING (ps->filt | 0x2000 /* magic */); - OUT_RING ((pt->width[0] << 16) | pt->height[0]); + OUT_RING ((pt->width0 << 16) | pt->height0); OUT_RING (ps->bcol); #endif } diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c index 185fbf53e0f..554e28e47dd 100644 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" #include "nv20_context.h" #include "nv20_screen.h" @@ -9,7 +10,7 @@ static void nv20_miptree_layout(struct nv20_miptree *nv20mt) { struct pipe_texture *pt = &nv20mt->base; - uint width = pt->width[0], height = pt->height[0]; + uint width = pt->width0, height = pt->height0; uint offset = 0; int nr_faces, l, f; uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | @@ -25,21 +26,19 @@ nv20_miptree_layout(struct nv20_miptree *nv20mt) } for (l = 0; l <= pt->last_level; l++) { - pt->width[l] = width; - pt->height[l] = height; pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) - nv20mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64); + nv20mt->level[l].pitch = align(pt->width0 * pt->block.size, 64); else - nv20mt->level[l].pitch = pt->width[l] * pt->block.size; + nv20mt->level[l].pitch = u_minify(pt->width0, l) * pt->block.size; nv20mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); - width = MAX2(1, width >> 1); - height = MAX2(1, height >> 1); + width = u_minify(width, 1); + height = u_minify(height, 1); } for (f = 0; f < nr_faces; f++) { @@ -47,14 +46,14 @@ nv20_miptree_layout(struct nv20_miptree *nv20mt) nv20mt->level[l].image_offset[f] = offset; if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && - pt->width[l + 1] > 1 && pt->height[l + 1] > 1) - offset += align(nv20mt->level[l].pitch * pt->height[l], 64); + u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) + offset += align(nv20mt->level[l].pitch * u_minify(pt->height0, l), 64); else - offset += nv20mt->level[l].pitch * pt->height[l]; + offset += nv20mt->level[l].pitch * u_minify(pt->height0, l); } nv20mt->level[l].image_offset[f] = offset; - offset += nv20mt->level[l].pitch * pt->height[l]; + offset += nv20mt->level[l].pitch * u_minify(pt->height0, l); } nv20mt->total_size = offset; @@ -68,7 +67,7 @@ nv20_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, /* Only supports 2D, non-mipmapped textures for the moment */ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth[0] != 1) + pt->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv20_miptree); @@ -100,8 +99,8 @@ nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) mt->base.screen = screen; /* Swizzled textures must be POT */ - if (pt->width[0] & (pt->width[0] - 1) || - pt->height[0] & (pt->height[0] - 1)) + if (pt->width0 & (pt->width0 - 1) || + pt->height0 & (pt->height0 - 1)) mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; else if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | @@ -167,8 +166,8 @@ nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, return NULL; pipe_texture_reference(&ns->base.texture, pt); ns->base.format = pt->format; - ns->base.width = pt->width[level]; - ns->base.height = pt->height[level]; + ns->base.width = u_minify(pt->width0, level); + ns->base.height = u_minify(pt->height0, level); ns->base.usage = flags; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c index ed4084980f2..3a82e63423d 100644 --- a/src/gallium/drivers/nv20/nv20_state.c +++ b/src/gallium/drivers/nv20/nv20_state.c @@ -546,9 +546,9 @@ nv20_init_state_functions(struct nv20_context *nv20) nv20->pipe.delete_blend_state = nv20_blend_state_delete; nv20->pipe.create_sampler_state = nv20_sampler_state_create; - nv20->pipe.bind_sampler_states = nv20_sampler_state_bind; + nv20->pipe.bind_fragment_sampler_states = nv20_sampler_state_bind; nv20->pipe.delete_sampler_state = nv20_sampler_state_delete; - nv20->pipe.set_sampler_textures = nv20_set_sampler_texture; + nv20->pipe.set_fragment_sampler_textures = nv20_set_sampler_texture; nv20->pipe.create_rasterizer_state = nv20_rasterizer_state_create; nv20->pipe.bind_rasterizer_state = nv20_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c index 81b4f1a9177..87b5c14a3c2 100644 --- a/src/gallium/drivers/nv20/nv20_transfer.c +++ b/src/gallium/drivers/nv20/nv20_transfer.c @@ -2,6 +2,7 @@ #include <pipe/p_defines.h> #include <pipe/p_inlines.h> #include <util/u_memory.h> +#include <util/u_math.h> #include <nouveau/nouveau_winsys.h> #include "nv20_context.h" #include "nv20_screen.h" @@ -20,9 +21,9 @@ nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, memset(template, 0, sizeof(struct pipe_texture)); template->target = pt->target; template->format = pt->format; - template->width[0] = pt->width[level]; - template->height[0] = pt->height[level]; - template->depth[0] = 1; + template->width0 = u_minify(pt->width0, level); + template->height0 = u_minify(pt->height0, level); + template->depth0 = 1; template->block = pt->block; template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index dca760cae62..b3293ee700d 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -74,9 +74,9 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) txf = tf->format; txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0); - txf |= log2i(pt->width[0]) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT; - txf |= log2i(pt->height[0]) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT; - txf |= log2i(pt->depth[0]) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT; + txf |= log2i(pt->width0) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT; + txf |= log2i(pt->height0) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT; + txf |= log2i(pt->depth0) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT; txf |= NV34TCL_TX_FORMAT_NO_BORDER | 0x10000; switch (pt->target) { @@ -115,8 +115,8 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) so_data (so, NV34TCL_TX_ENABLE_ENABLE | ps->en); so_data (so, txs); so_data (so, ps->filt | 0x2000 /*voodoo*/); - so_data (so, (pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | - pt->height[0]); + so_data (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | + pt->height0); so_data (so, ps->bcol); return so; diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 280696d4503..b4c306d1272 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" #include "nv30_context.h" @@ -8,7 +9,7 @@ static void nv30_miptree_layout(struct nv30_miptree *nv30mt) { struct pipe_texture *pt = &nv30mt->base; - uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint width = pt->width0, height = pt->height0, depth = pt->depth0; uint offset = 0; int nr_faces, l, f; uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | @@ -21,29 +22,26 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) nr_faces = 6; } else if (pt->target == PIPE_TEXTURE_3D) { - nr_faces = pt->depth[0]; + nr_faces = pt->depth0; } else { nr_faces = 1; } for (l = 0; l <= pt->last_level; l++) { - pt->width[l] = width; - pt->height[l] = height; - pt->depth[l] = depth; pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) - nv30mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64); + nv30mt->level[l].pitch = align(pt->width0 * pt->block.size, 64); else - nv30mt->level[l].pitch = pt->width[l] * pt->block.size; + nv30mt->level[l].pitch = u_minify(pt->width0, l) * pt->block.size; nv30mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); - width = MAX2(1, width >> 1); - height = MAX2(1, height >> 1); - depth = MAX2(1, depth >> 1); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } for (f = 0; f < nr_faces; f++) { @@ -51,14 +49,14 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) nv30mt->level[l].image_offset[f] = offset; if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && - pt->width[l + 1] > 1 && pt->height[l + 1] > 1) - offset += align(nv30mt->level[l].pitch * pt->height[l], 64); + u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) + offset += align(nv30mt->level[l].pitch * u_minify(pt->height0, l), 64); else - offset += nv30mt->level[l].pitch * pt->height[l]; + offset += nv30mt->level[l].pitch * u_minify(pt->height0, l); } nv30mt->level[l].image_offset[f] = offset; - offset += nv30mt->level[l].pitch * pt->height[l]; + offset += nv30mt->level[l].pitch * u_minify(pt->height0, l); } nv30mt->total_size = offset; @@ -79,8 +77,8 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->base.screen = pscreen; /* Swizzled textures must be POT */ - if (pt->width[0] & (pt->width[0] - 1) || - pt->height[0] & (pt->height[0] - 1)) + if (pt->width0 & (pt->width0 - 1) || + pt->height0 & (pt->height0 - 1)) mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; else if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | @@ -134,7 +132,7 @@ nv30_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, /* Only supports 2D, non-mipmapped textures for the moment */ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth[0] != 1) + pt->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv30_miptree); @@ -182,8 +180,8 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; pipe_texture_reference(&ns->base.texture, pt); ns->base.format = pt->format; - ns->base.width = pt->width[level]; - ns->base.height = pt->height[level]; + ns->base.width = u_minify(pt->width0, level); + ns->base.height = u_minify(pt->height0, level); ns->base.usage = flags; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index b91e972c123..3f802d92416 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -690,9 +690,9 @@ nv30_init_state_functions(struct nv30_context *nv30) nv30->pipe.delete_blend_state = nv30_blend_state_delete; nv30->pipe.create_sampler_state = nv30_sampler_state_create; - nv30->pipe.bind_sampler_states = nv30_sampler_state_bind; + nv30->pipe.bind_fragment_sampler_states = nv30_sampler_state_bind; nv30->pipe.delete_sampler_state = nv30_sampler_state_delete; - nv30->pipe.set_sampler_textures = nv30_set_sampler_texture; + nv30->pipe.set_fragment_sampler_textures = nv30_set_sampler_texture; nv30->pipe.create_rasterizer_state = nv30_rasterizer_state_create; nv30->pipe.bind_rasterizer_state = nv30_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c index 98011decf7c..5e429b4d85c 100644 --- a/src/gallium/drivers/nv30/nv30_transfer.c +++ b/src/gallium/drivers/nv30/nv30_transfer.c @@ -2,6 +2,7 @@ #include <pipe/p_defines.h> #include <pipe/p_inlines.h> #include <util/u_memory.h> +#include <util/u_math.h> #include <nouveau/nouveau_winsys.h> #include "nv30_context.h" #include "nv30_screen.h" @@ -20,9 +21,9 @@ nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, memset(template, 0, sizeof(struct pipe_texture)); template->target = pt->target; template->format = pt->format; - template->width[0] = pt->width[level]; - template->height[0] = pt->height[level]; - template->depth[0] = 1; + template->width0 = u_minify(pt->width0, level); + template->height0 = u_minify(pt->height0, level); + template->depth0 = 1; template->block = pt->block; template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index e2ec57564d1..44abc845969 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -117,11 +117,11 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_data (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en); so_data (so, txs); so_data (so, ps->filt | tf->sign | 0x2000 /*voodoo*/); - so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | - pt->height[0]); + so_data (so, (pt->width0 << NV40TCL_TEX_SIZE0_W_SHIFT) | + pt->height0); so_data (so, ps->bcol); so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1); - so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); + so_data (so, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); return so; } diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 465dd3b0693..f73bedff6d8 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" #include "nv40_context.h" @@ -8,7 +9,7 @@ static void nv40_miptree_layout(struct nv40_miptree *mt) { struct pipe_texture *pt = &mt->base; - uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint width = pt->width0, height = pt->height0, depth = pt->depth0; uint offset = 0; int nr_faces, l, f; uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | @@ -21,29 +22,26 @@ nv40_miptree_layout(struct nv40_miptree *mt) nr_faces = 6; } else if (pt->target == PIPE_TEXTURE_3D) { - nr_faces = pt->depth[0]; + nr_faces = pt->depth0; } else { nr_faces = 1; } for (l = 0; l <= pt->last_level; l++) { - pt->width[l] = width; - pt->height[l] = height; - pt->depth[l] = depth; pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) - mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64); + mt->level[l].pitch = align(pt->width0 * pt->block.size, 64); else - mt->level[l].pitch = pt->width[l] * pt->block.size; + mt->level[l].pitch = u_minify(pt->width0, l) * pt->block.size; mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); - width = MAX2(1, width >> 1); - height = MAX2(1, height >> 1); - depth = MAX2(1, depth >> 1); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } for (f = 0; f < nr_faces; f++) { @@ -51,14 +49,14 @@ nv40_miptree_layout(struct nv40_miptree *mt) mt->level[l].image_offset[f] = offset; if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && - pt->width[l + 1] > 1 && pt->height[l + 1] > 1) - offset += align(mt->level[l].pitch * pt->height[l], 64); + u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) + offset += align(mt->level[l].pitch * u_minify(pt->height0, l), 64); else - offset += mt->level[l].pitch * pt->height[l]; + offset += mt->level[l].pitch * u_minify(pt->height0, l); } mt->level[l].image_offset[f] = offset; - offset += mt->level[l].pitch * pt->height[l]; + offset += mt->level[l].pitch * u_minify(pt->height0, l); } mt->total_size = offset; @@ -79,8 +77,8 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->base.screen = pscreen; /* Swizzled textures must be POT */ - if (pt->width[0] & (pt->width[0] - 1) || - pt->height[0] & (pt->height[0] - 1)) + if (pt->width0 & (pt->width0 - 1) || + pt->height0 & (pt->height0 - 1)) mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; else if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | @@ -128,7 +126,7 @@ nv40_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, /* Only supports 2D, non-mipmapped textures for the moment */ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth[0] != 1) + pt->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv40_miptree); @@ -176,8 +174,8 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; pipe_texture_reference(&ns->base.texture, pt); ns->base.format = pt->format; - ns->base.width = pt->width[level]; - ns->base.height = pt->height[level]; + ns->base.width = u_minify(pt->width0, level); + ns->base.height = u_minify(pt->height0, level); ns->base.usage = flags; pipe_reference_init(&ns->base.reference, 1); ns->base.face = face; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index c3ee4d23453..bc34e32a4b9 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -705,9 +705,9 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.delete_blend_state = nv40_blend_state_delete; nv40->pipe.create_sampler_state = nv40_sampler_state_create; - nv40->pipe.bind_sampler_states = nv40_sampler_state_bind; + nv40->pipe.bind_fragment_sampler_states = nv40_sampler_state_bind; nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; - nv40->pipe.set_sampler_textures = nv40_set_sampler_texture; + nv40->pipe.set_fragment_sampler_textures = nv40_set_sampler_texture; nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create; nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c index 92caee6f382..36e253c96f9 100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ b/src/gallium/drivers/nv40/nv40_transfer.c @@ -2,6 +2,7 @@ #include <pipe/p_defines.h> #include <pipe/p_inlines.h> #include <util/u_memory.h> +#include <util/u_math.h> #include <nouveau/nouveau_winsys.h> #include "nv40_context.h" #include "nv40_screen.h" @@ -20,9 +21,9 @@ nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, memset(template, 0, sizeof(struct pipe_texture)); template->target = pt->target; template->format = pt->format; - template->width[0] = pt->width[level]; - template->height[0] = pt->height[level]; - template->depth[0] = 1; + template->width0 = u_minify(pt->width0, level); + template->height0 = u_minify(pt->height0, level); + template->depth0 = 1; template->block = pt->block; template->nblocksx[0] = pt->nblocksx[level]; template->nblocksy[0] = pt->nblocksx[level]; diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 9c20c5cc282..3d58746793f 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -61,8 +61,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) struct nouveau_device *dev = nouveau_screen(pscreen)->device; struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); struct pipe_texture *pt = &mt->base.base; - unsigned width = tmp->width[0], height = tmp->height[0]; - unsigned depth = tmp->depth[0], image_alignment; + unsigned width = tmp->width0, height = tmp->height0; + unsigned depth = tmp->depth0, image_alignment; uint32_t tile_flags; int ret, i, l; @@ -92,9 +92,6 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) for (l = 0; l <= pt->last_level; l++) { struct nv50_miptree_level *lvl = &mt->level[l]; - pt->width[l] = width; - pt->height[l] = height; - pt->depth[l] = depth; pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); @@ -102,9 +99,9 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) lvl->pitch = align(pt->nblocksx[l] * pt->block.size, 64); lvl->tile_mode = get_tile_mode(pt->nblocksy[l], depth); - width = MAX2(1, width >> 1); - height = MAX2(1, height >> 1); - depth = MAX2(1, depth >> 1); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } image_alignment = get_tile_height(mt->level[0].tile_mode) * 64; @@ -122,7 +119,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) size = lvl->pitch; size *= align(pt->nblocksy[l], tile_h); - size *= align(pt->depth[l], tile_d); + size *= align(u_minify(pt->depth0, l), tile_d); lvl->image_offset[i] = mt->total_size; @@ -151,7 +148,7 @@ nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, /* Only supports 2D, non-mipmapped textures for the moment */ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth[0] != 1) + pt->depth0 != 1) return NULL; mt = CALLOC_STRUCT(nv50_miptree); @@ -202,8 +199,8 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; pipe_texture_reference(&ps->texture, pt); ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; + ps->width = u_minify(pt->width0, level); + ps->height = u_minify(pt->height0, level); ps->usage = flags; pipe_reference_init(&ps->reference, 1); ps->face = face; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 1509cecaac4..f0fe7e61684 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1440,19 +1440,25 @@ emit_ddx(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) static void emit_ddy(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { + struct nv50_reg *r = src; struct nv50_program_exec *e = exec(pc); assert(src->type == P_TEMP); - if (!(src->mod & NV50_MOD_NEG)) /* ! double negation */ - emit_neg(pc, src, src); + if (!(src->mod & NV50_MOD_NEG)) { /* ! double negation */ + r = alloc_temp(pc, NULL); + emit_neg(pc, r, src); + } e->inst[0] = 0xc0150000; e->inst[1] = 0x8a400000; set_long(pc, e); set_dst(pc, dst, e); - set_src_0(pc, src, e); - set_src_2(pc, src, e); + set_src_0(pc, r, e); + set_src_2(pc, r, e); + + if (r != src) + free_temp(pc, r); emit(pc, e); } @@ -2637,7 +2643,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) for (i = 0, rid = 0; i < pc->result_nr; ++i) { p->cfg.io[i].hw = rid; - p->cfg.io[i].id_vp = i; + p->cfg.io[i].id = i; for (c = 0; c < 4; ++c) { int n = i * 4 + c; @@ -2669,14 +2675,12 @@ nv50_program_tx_prep(struct nv50_pc *pc) * the lower hardware IDs, so sort them: */ for (i = 0; i < pc->attr_nr; i++) { - if (pc->interp_mode[i] == INTERP_FLAT) { - p->cfg.io[m].id_vp = i + base; - p->cfg.io[m++].id_fp = i; - } else { + if (pc->interp_mode[i] == INTERP_FLAT) + p->cfg.io[m++].id = i; + else { if (!(pc->interp_mode[i] & INTERP_PERSPECTIVE)) p->cfg.io[n].linear = TRUE; - p->cfg.io[n].id_vp = i + base; - p->cfg.io[n++].id_fp = i; + p->cfg.io[n++].id = i; } } @@ -2688,7 +2692,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) for (n = 0; n < pc->attr_nr; ++n) { p->cfg.io[n].hw = rid = aid; - i = p->cfg.io[n].id_fp; + i = p->cfg.io[n].id; if (p->info.input_semantic_name[n] == TGSI_SEMANTIC_FACE) { @@ -2728,8 +2732,8 @@ nv50_program_tx_prep(struct nv50_pc *pc) for (i = 0; i < pc->attr_nr; i++) { ubyte si, sn; - sn = p->info.input_semantic_name[p->cfg.io[i].id_fp]; - si = p->info.input_semantic_index[p->cfg.io[i].id_fp]; + sn = p->info.input_semantic_name[p->cfg.io[i].id]; + si = p->info.input_semantic_index[p->cfg.io[i].id]; if (sn == TGSI_SEMANTIC_COLOR) { p->cfg.two_side[si] = p->cfg.io[i]; @@ -2914,7 +2918,7 @@ nv50_fp_move_results(struct nv50_pc *pc) static void nv50_program_fixup_insns(struct nv50_pc *pc) { - struct nv50_program_exec *e, *prev = NULL, **bra_list; + struct nv50_program_exec *e, **bra_list; unsigned i, n, pos; bra_list = CALLOC(pc->p->exec_size, sizeof(struct nv50_program_exec *)); @@ -2926,6 +2930,16 @@ nv50_program_fixup_insns(struct nv50_pc *pc) if (e->param.index >= 0 && !e->param.mask) bra_list[n++] = e; + /* last instruction must be long so it can have the exit bit set */ + if (!is_long(pc->p->exec_tail)) + convert_to_long(pc, pc->p->exec_tail); + /* set exit bit */ + pc->p->exec_tail->inst[1] |= 1; + + /* !immd on exit insn simultaneously means !join */ + assert(!is_immd(pc->p->exec_head)); + assert(!is_immd(pc->p->exec_tail)); + /* Make sure we don't have any single 32 bit instructions. */ for (e = pc->p->exec_head, pos = 0; e; e = e->next) { pos += is_long(e) ? 2 : 1; @@ -2937,22 +2951,7 @@ nv50_program_fixup_insns(struct nv50_pc *pc) convert_to_long(pc, e); ++pos; } - if (e->next) - prev = e; - } - - assert(!is_immd(pc->p->exec_head)); - assert(!is_immd(pc->p->exec_tail)); - - /* last instruction must be long so it can have the end bit set */ - if (!is_long(pc->p->exec_tail)) { - convert_to_long(pc, pc->p->exec_tail); - if (prev) - convert_to_long(pc, prev); } - assert(!(pc->p->exec_tail->inst[1] & 2)); - /* set the end-bit */ - pc->p->exec_tail->inst[1] |= 1; FREE(bra_list); } @@ -3236,15 +3235,15 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base) struct nv50_program *vp = nv50->vertprog; unsigned i, c, m = base; - /* XXX: This can't work correctly in all cases yet, we either - * have to create TGSI_SEMANTIC_PNTC or sprite_coord_mode has - * to be per FP input instead of per VP output + /* XXX: this might not work correctly in all cases yet - we'll + * just assume that an FP generic input that is not written in + * the VP is PointCoord. */ memset(pntc, 0, 8 * sizeof(uint32_t)); for (i = 0; i < fp->cfg.io_nr; i++) { uint8_t sn, si; - uint8_t j = fp->cfg.io[i].id_vp, k = fp->cfg.io[i].id_fp; + uint8_t j, k = fp->cfg.io[i].id; unsigned n = popcnt4(fp->cfg.io[i].mask); if (fp->info.input_semantic_name[k] != TGSI_SEMANTIC_GENERIC) { @@ -3252,10 +3251,16 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base) continue; } - sn = vp->info.input_semantic_name[j]; - si = vp->info.input_semantic_index[j]; + for (j = 0; j < vp->info.num_outputs; ++j) { + sn = vp->info.output_semantic_name[j]; + si = vp->info.output_semantic_index[j]; - if (j < fp->cfg.io_nr && sn == TGSI_SEMANTIC_GENERIC) { + if (sn == fp->info.input_semantic_name[k] && + si == fp->info.input_semantic_index[k]) + break; + } + + if (j < vp->info.num_outputs) { ubyte mode = nv50->rasterizer->pipe.sprite_coord_mode[si]; @@ -3343,20 +3348,24 @@ nv50_linkage_validate(struct nv50_context *nv50) reg[0] += m - 4; /* adjust FFC0 id */ reg[4] |= m << 8; /* set mid where 'normal' FP inputs start */ - i = 0; - if (fp->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) - i = 1; - for (; i < fp->cfg.io_nr; i++) { - ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id_fp]; - ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id_fp]; - - n = fp->cfg.io[i].id_vp; - if (n >= vp->cfg.io_nr || - vp->info.output_semantic_name[n] != sn || - vp->info.output_semantic_index[n] != si) - vpo = &dummy; - else - vpo = &vp->cfg.io[n]; + for (i = 0; i < fp->cfg.io_nr; i++) { + ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id]; + ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id]; + + /* position must be mapped first */ + assert(i == 0 || sn != TGSI_SEMANTIC_POSITION); + + /* maybe even remove these from cfg.io */ + if (sn == TGSI_SEMANTIC_POSITION || sn == TGSI_SEMANTIC_FACE) + continue; + + /* VP outputs and vp->cfg.io are in the same order */ + for (n = 0; n < vp->info.num_outputs; ++n) { + if (vp->info.output_semantic_name[n] == sn && + vp->info.output_semantic_index[n] == si) + break; + } + vpo = (n < vp->info.num_outputs) ? &vp->cfg.io[n] : &dummy; m = nv50_sreg4_map(map, m, lin, &fp->cfg.io[i], vpo); } diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index d78dee083f1..255c7c737ef 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -17,8 +17,7 @@ struct nv50_program_exec { struct nv50_sreg4 { uint8_t hw; - uint8_t id_vp; - uint8_t id_fp; + uint8_t id; /* tgsi index, nv50 needs them sorted: flat ones last */ uint8_t mask; boolean linear; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index ffaa5e29d1c..07318f23947 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -648,9 +648,9 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.delete_blend_state = nv50_blend_state_delete; nv50->pipe.create_sampler_state = nv50_sampler_state_create; - nv50->pipe.bind_sampler_states = nv50_sampler_state_bind; + nv50->pipe.bind_fragment_sampler_states = nv50_sampler_state_bind; nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; - nv50->pipe.set_sampler_textures = nv50_set_sampler_texture; + nv50->pipe.set_fragment_sampler_textures = nv50_set_sampler_texture; nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create; nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 799d2758fee..c871acaab8d 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -201,7 +201,8 @@ nv50_state_emit(struct nv50_context *nv50) so_emit(chan, nv50->state.vertprog); if (nv50->state.dirty & NV50_NEW_FRAGPROG) so_emit(chan, nv50->state.fragprog); - if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG)) + if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | + NV50_NEW_RASTERIZER)) so_emit(chan, nv50->state.programs); if (nv50->state.dirty & NV50_NEW_RASTERIZER) so_emit(chan, nv50->state.rast); @@ -264,7 +265,8 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) nv50_fragprog_validate(nv50); - if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG)) + if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | + NV50_NEW_RASTERIZER)) nv50_linkage_validate(nv50); if (nv50->dirty & NV50_NEW_RASTERIZER) @@ -285,7 +287,7 @@ nv50_state_validate(struct nv50_context *nv50) so = so_new(33, 0); so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32); for (i = 0; i < 32; i++) - so_data(so, nv50->stipple.stipple[i]); + so_data(so, util_bswap32(nv50->stipple.stipple[i])); so_ref(so, &nv50->state.stipple); so_ref(NULL, &so); } diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 2813f544770..417d3679422 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -131,9 +131,9 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so, NOUVEAU_BO_RD, 0, 0); so_data (so, mode); so_data (so, 0x00300000); - so_data (so, mt->base.base.width[0] | (1 << 31)); + so_data (so, mt->base.base.width0 | (1 << 31)); so_data (so, (mt->base.base.last_level << 28) | - (mt->base.base.depth[0] << 16) | mt->base.base.height[0]); + (mt->base.base.depth0 << 16) | mt->base.base.height0); so_data (so, 0x03000000); so_data (so, mt->base.base.last_level << 4); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index ea61357aaa6..39d65279fc0 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -1,6 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" #include "nv50_context.h" @@ -156,9 +157,9 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->base.block = pt->block; if (!pt->nblocksx[level]) { tx->base.nblocksx = pf_get_nblocksx(&pt->block, - pt->width[level]); + u_minify(pt->width0, level)); tx->base.nblocksy = pf_get_nblocksy(&pt->block, - pt->height[level]); + u_minify(pt->height0, level)); } else { tx->base.nblocksx = pt->nblocksx[level]; tx->base.nblocksy = pt->nblocksy[level]; @@ -167,9 +168,9 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->base.usage = usage; tx->level_pitch = lvl->pitch; - tx->level_width = mt->base.base.width[level]; - tx->level_height = mt->base.base.height[level]; - tx->level_depth = mt->base.base.depth[level]; + tx->level_width = u_minify(mt->base.base.width0, level); + tx->level_height = u_minify(mt->base.base.height0, level); + tx->level_depth = u_minify(mt->base.base.depth0, level); tx->level_offset = lvl->image_offset[image]; tx->level_tiling = lvl->tile_mode; tx->level_x = pf_get_nblocksx(&tx->base.block, x); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index e6ab8e4af14..98a39390bf9 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -145,8 +145,8 @@ static const float * get_shader_constant( * normalized coords. Should only show up on non-r500. */ case RC_STATE_R300_TEXRECT_FACTOR: tex = &r300->textures[constant->u.State[1]]->tex; - vec[0] = 1.0 / tex->width[0]; - vec[1] = 1.0 / tex->height[0]; + vec[0] = 1.0 / tex->width0; + vec[1] = 1.0 / tex->height0; break; default: diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 29ddc84c411..79b01bb4dc2 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -1,6 +1,7 @@ /* * Copyright 2008 Corbin Simpson <[email protected]> * Joakim Sindholt <[email protected]> + * Copyright 2009 Marek Olšák <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -31,6 +32,41 @@ #include "radeon_code.h" #include "radeon_compiler.h" +/* Convert info about FS input semantics to r300_shader_semantics. */ +static void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, + struct r300_shader_semantics* fs_inputs) +{ + int i; + unsigned index; + + r300_shader_semantics_reset(fs_inputs); + + for (i = 0; i < info->num_inputs; i++) { + index = info->input_semantic_index[i]; + + switch (info->input_semantic_name[i]) { + case TGSI_SEMANTIC_COLOR: + assert(index <= ATTR_COLOR_COUNT); + fs_inputs->color[index] = i; + break; + + case TGSI_SEMANTIC_GENERIC: + assert(index <= ATTR_GENERIC_COUNT); + fs_inputs->generic[index] = i; + break; + + case TGSI_SEMANTIC_FOG: + assert(index == 0); + fs_inputs->fog = i; + break; + + default: + assert(0); + } + } +} + + static void find_output_registers(struct r300_fragment_program_compiler * compiler, struct r300_fragment_shader * fs) { @@ -58,38 +94,24 @@ static void allocate_hardware_inputs( void (*allocate)(void * data, unsigned input, unsigned hwreg), void * mydata) { - struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info; - int total_colors = 0; - int colors = 0; - int total_generic = 0; - int generic = 0; - int i; - - for (i = 0; i < info->num_inputs; i++) { - switch (info->input_semantic_name[i]) { - case TGSI_SEMANTIC_COLOR: - total_colors++; - break; - case TGSI_SEMANTIC_FOG: - case TGSI_SEMANTIC_GENERIC: - total_generic++; - break; + struct r300_shader_semantics* inputs = + &((struct r300_fragment_shader*)c->UserData)->inputs; + int i, reg = 0; + + /* Allocate input registers. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (inputs->color[i] != ATTR_UNUSED) { + allocate(mydata, inputs->color[i], reg++); } } - - for(i = 0; i < info->num_inputs; i++) { - switch (info->input_semantic_name[i]) { - case TGSI_SEMANTIC_COLOR: - allocate(mydata, i, colors); - colors++; - break; - case TGSI_SEMANTIC_FOG: - case TGSI_SEMANTIC_GENERIC: - allocate(mydata, i, total_colors + generic); - generic++; - break; + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (inputs->generic[i] != ATTR_UNUSED) { + allocate(mydata, inputs->generic[i], reg++); } } + if (inputs->fog != ATTR_UNUSED) { + allocate(mydata, inputs->fog, reg++); + } } void r300_translate_fragment_shader(struct r300_context* r300, @@ -98,6 +120,10 @@ void r300_translate_fragment_shader(struct r300_context* r300, struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; + /* Initialize. */ + r300_shader_read_fs_inputs(&fs->info, &fs->inputs); + + /* Setup the compiler. */ memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base); compiler.Base.Debug = DBG_ON(r300, DBG_FP); @@ -107,7 +133,7 @@ void r300_translate_fragment_shader(struct r300_context* r300, compiler.AllocateHwInputs = &allocate_hardware_inputs; compiler.UserData = fs; - /* TODO: Program compilation depends on texture compare modes, + /* XXX: Program compilation depends on texture compare modes, * which are sampler state. Therefore, programs need to be recompiled * depending on this state as in the classic Mesa driver. * @@ -133,6 +159,7 @@ void r300_translate_fragment_shader(struct r300_context* r300, /* XXX failover maybe? */ DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n", compiler.Base.ErrorMsg); + assert(0); } /* And, finally... */ diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h index e831c30301b..630e2d0c8a5 100644 --- a/src/gallium/drivers/r300/r300_fs.h +++ b/src/gallium/drivers/r300/r300_fs.h @@ -1,6 +1,7 @@ /* * Copyright 2008 Corbin Simpson <[email protected]> * Joakim Sindholt <[email protected]> + * Copyright 2009 Marek Olšák <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,15 +26,16 @@ #define R300_FS_H #include "pipe/p_state.h" - #include "tgsi/tgsi_scan.h" - #include "radeon_code.h" +#include "r300_shader_semantics.h" struct r300_fragment_shader { /* Parent class */ struct pipe_shader_state state; + struct tgsi_shader_info info; + struct r300_shader_semantics inputs; /* Has this shader been translated yet? */ boolean translated; diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 3a419b24b01..85b1ea568a3 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -661,20 +661,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_GB_SUPER_TILE_B (1 << 15) # define R300_GB_SUBPIXEL_1_12 (0 << 16) # define R300_GB_SUBPIXEL_1_16 (1 << 16) -# define GB_TILE_CONFIG_QUADS_PER_RAS_4 (0 << 17) -# define GB_TILE_CONFIG_QUADS_PER_RAS_8 (1 << 17) -# define GB_TILE_CONFIG_QUADS_PER_RAS_16 (2 << 17) -# define GB_TILE_CONFIG_QUADS_PER_RAS_32 (3 << 17) -# define GB_TILE_CONFIG_BB_SCAN_INTERCEPT (0 << 19) -# define GB_TILE_CONFIG_BB_SCAN_BOUND_BOX (1 << 19) -# define GB_TILE_CONFIG_ALT_SCAN_EN_LR (0 << 20) -# define GB_TILE_CONFIG_ALT_SCAN_EN_LRL (1 << 20) -# define GB_TILE_CONFIG_ALT_OFFSET (0 << 21) -# define GB_TILE_CONFIG_SUBPRECISION (0 << 22) -# define GB_TILE_CONFIG_ALT_TILING_DEF (0 << 23) -# define GB_TILE_CONFIG_ALT_TILING_3_2 (1 << 23) -# define GB_TILE_CONFIG_Z_EXTENDED_24_1 (0 << 24) -# define GB_TILE_CONFIG_Z_EXTENDED_S25_1 (1 << 24) +# define R300_GB_TILE_CONFIG_QUADS_PER_RAS_4 (0 << 17) +# define R300_GB_TILE_CONFIG_QUADS_PER_RAS_8 (1 << 17) +# define R300_GB_TILE_CONFIG_QUADS_PER_RAS_16 (2 << 17) +# define R300_GB_TILE_CONFIG_QUADS_PER_RAS_32 (3 << 17) +# define R300_GB_TILE_CONFIG_BB_SCAN_INTERCEPT (0 << 19) +# define R300_GB_TILE_CONFIG_BB_SCAN_BOUND_BOX (1 << 19) +# define R300_GB_TILE_CONFIG_ALT_SCAN_EN_LR (0 << 20) +# define R300_GB_TILE_CONFIG_ALT_SCAN_EN_LRL (1 << 20) +# define R300_GB_TILE_CONFIG_ALT_OFFSET (0 << 21) +# define R300_GB_TILE_CONFIG_SUBPRECISION (0 << 22) +# define R300_GB_TILE_CONFIG_ALT_TILING_DEF (0 << 23) +# define R300_GB_TILE_CONFIG_ALT_TILING_3_2 (1 << 23) +# define R300_GB_TILE_CONFIG_Z_EXTENDED_24_1 (0 << 24) +# define R300_GB_TILE_CONFIG_Z_EXTENDED_S25_1 (1 << 24) /* Specifies the sizes of the various FIFO`s in the sc/rs/us. This register must be the first one written */ #define R300_GB_FIFO_SIZE 0x4024 @@ -700,9 +700,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ # define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 -#define GB_Z_PEQ_CONFIG 0x4028 -# define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_4_4 (0 << 0) -# define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8 (1 << 0) +#define R300_GB_Z_PEQ_CONFIG 0x4028 +# define R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_4_4 (0 << 0) +# define R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8 (1 << 0) /* Specifies various polygon specific selects (fog, depth, perspective). */ #define R300_GB_SELECT 0x401c @@ -725,39 +725,39 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Specifies the graphics pipeline configuration for antialiasing. */ #define R300_GB_AA_CONFIG 0x4020 -# define GB_AA_CONFIG_AA_DISABLE (0 << 0) -# define GB_AA_CONFIG_AA_ENABLE (1 << 0) -# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2 (0 << 1) -# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3 (1 << 1) -# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4 (2 << 1) -# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6 (3 << 1) +# define R300_GB_AA_CONFIG_AA_DISABLE (0 << 0) +# define R300_GB_AA_CONFIG_AA_ENABLE (1 << 0) +# define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2 (0 << 1) +# define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3 (1 << 1) +# define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4 (2 << 1) +# define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6 (3 << 1) /* Selects which of 4 pipes are active. */ -#define GB_PIPE_SELECT 0x402c -# define GB_PIPE_SELECT_PIPE0_ID_SHIFT 0 -# define GB_PIPE_SELECT_PIPE1_ID_SHIFT 2 -# define GB_PIPE_SELECT_PIPE2_ID_SHIFT 4 -# define GB_PIPE_SELECT_PIPE3_ID_SHIFT 6 -# define GB_PIPE_SELECT_PIPE_MASK_SHIFT 8 -# define GB_PIPE_SELECT_MAX_PIPE 12 -# define GB_PIPE_SELECT_BAD_PIPES 14 -# define GB_PIPE_SELECT_CONFIG_PIPES 18 +#define R300_GB_PIPE_SELECT 0x402c +# define R300_GB_PIPE_SELECT_PIPE0_ID_SHIFT 0 +# define R300_GB_PIPE_SELECT_PIPE1_ID_SHIFT 2 +# define R300_GB_PIPE_SELECT_PIPE2_ID_SHIFT 4 +# define R300_GB_PIPE_SELECT_PIPE3_ID_SHIFT 6 +# define R300_GB_PIPE_SELECT_PIPE_MASK_SHIFT 8 +# define R300_GB_PIPE_SELECT_MAX_PIPE 12 +# define R300_GB_PIPE_SELECT_BAD_PIPES 14 +# define R300_GB_PIPE_SELECT_CONFIG_PIPES 18 /* Specifies the sizes of the various FIFO`s in the sc/rs. */ -#define GB_FIFO_SIZE1 0x4070 +#define R300_GB_FIFO_SIZE1 0x4070 /* High water mark for SC input fifo */ -# define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_SHIFT 0 -# define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_MASK 0x0000003f +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_SHIFT 0 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_MASK 0x0000003f /* High water mark for SC input fifo (B) */ -# define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_SHIFT 6 -# define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_MASK 0x00000fc0 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_SHIFT 6 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_MASK 0x00000fc0 /* High water mark for RS colors' fifo */ -# define GB_FIFO_SIZE1_SC_HIGHWATER_COL_SHIFT 12 -# define GB_FIFO_SIZE1_SC_HIGHWATER_COL_MASK 0x0003f000 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_COL_SHIFT 12 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_COL_MASK 0x0003f000 /* High water mark for RS textures' fifo */ -# define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_SHIFT 18 -# define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_MASK 0x00fc0000 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_TEX_SHIFT 18 +# define R300_GB_FIFO_SIZE1_SC_HIGHWATER_TEX_MASK 0x00fc0000 /* This table specifies the source location and format for up to 16 texture * addresses (i[0]:i[15]) and four colors (c[0]:c[3]) diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h new file mode 100644 index 00000000000..85184e2cfd7 --- /dev/null +++ b/src/gallium/drivers/r300/r300_shader_semantics.h @@ -0,0 +1,64 @@ +/* + * Copyright 2009 Marek Olšák <[email protected]> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_SHADER_SEMANTICS_H +#define R300_SHADER_SEMANTICS_H + +#define ATTR_UNUSED (-1) +#define ATTR_COLOR_COUNT 2 +#define ATTR_GENERIC_COUNT 16 + +/* This structure contains information about what attributes are written by VS + * or read by FS. (but not both) It's much easier to work with than + * tgsi_shader_info. + * + * The variables contain indices to tgsi_shader_info semantics and those + * indices are nothing else than input/output register numbers. */ +struct r300_shader_semantics { + int pos; + int psize; + int color[ATTR_COLOR_COUNT]; + int bcolor[ATTR_COLOR_COUNT]; + int generic[ATTR_GENERIC_COUNT]; + int fog; +}; + +static INLINE void r300_shader_semantics_reset( + struct r300_shader_semantics* info) +{ + int i; + + info->pos = ATTR_UNUSED; + info->psize = ATTR_UNUSED; + info->fog = ATTR_UNUSED; + + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + info->color[i] = ATTR_UNUSED; + info->bcolor[i] = ATTR_UNUSED; + } + + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + info->generic[i] = ATTR_UNUSED; + } +} + +#endif diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index a88d66db247..7505353953f 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -822,10 +822,10 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.delete_rasterizer_state = r300_delete_rs_state; r300->context.create_sampler_state = r300_create_sampler_state; - r300->context.bind_sampler_states = r300_bind_sampler_states; + r300->context.bind_fragment_sampler_states = r300_bind_sampler_states; r300->context.delete_sampler_state = r300_delete_sampler_state; - r300->context.set_sampler_textures = r300_set_sampler_textures; + r300->context.set_fragment_sampler_textures = r300_set_sampler_textures; r300->context.set_scissor_state = r300_set_scissor_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 6fb780cb299..cd969d633bc 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -1,5 +1,6 @@ /* * Copyright 2008 Corbin Simpson <[email protected]> + * Copyright 2009 Marek Olšák <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -28,6 +29,7 @@ #include "r300_context.h" #include "r300_fs.h" #include "r300_screen.h" +#include "r300_shader_semantics.h" #include "r300_state_derived.h" #include "r300_state_inlines.h" #include "r300_vs.h" @@ -61,126 +63,68 @@ int r300_shader_key_compare(void* key1, void* key2) { (shader_key1->fs == shader_key2->fs); } -/* Set up the vs_output_tab and routes. */ -static void r300_vs_output_tab_routes(struct r300_context* r300, - int* vs_output_tab) +static void r300_draw_emit_attrib(struct r300_context* r300, + enum attrib_emit emit, + enum interp_mode interp, + int index) { - struct vertex_info* vinfo = &r300->vertex_info->vinfo; - boolean pos = FALSE, psize = FALSE, fog = FALSE; - int i, texs = 0, cols = 0; - struct tgsi_shader_info* info = &r300->fs->info; - - /* XXX One day we should figure out how to handle a different number of - * VS outputs and FS inputs, as well as a different number of vertex streams - * and VS inputs. It's definitely one of the sources of hardlocks. */ - - for (i = 0; i < info->num_inputs; i++) { - switch (info->input_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - pos = TRUE; - vs_output_tab[i] = 0; - break; - case TGSI_SEMANTIC_COLOR: - vs_output_tab[i] = 2 + cols; - cols++; - break; - case TGSI_SEMANTIC_PSIZE: - assert(psize == FALSE); - psize = TRUE; - vs_output_tab[i] = 15; - break; - case TGSI_SEMANTIC_FOG: - assert(fog == FALSE); - fog = TRUE; - /* Fall through */ - case TGSI_SEMANTIC_GENERIC: - vs_output_tab[i] = 6 + texs; - texs++; - break; - default: - debug_printf("r300: Unknown vertex input %d\n", - info->input_semantic_name[i]); - break; - } - } + struct tgsi_shader_info* info = &r300->vs->info; + int output; - /* XXX magic */ - assert(texs <= 8); + output = draw_find_vs_output(r300->draw, + info->output_semantic_name[index], + info->output_semantic_index[index]); + draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output); +} - /* Do the actual vertex_info setup. - * - * vertex_info has four uints of hardware-specific data in it. - * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL - * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM - * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0 - * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */ - - vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */ - - /* We need to add vertex position attribute only for SW TCL case, - * for HW TCL case it could be generated by vertex shader */ - if (!pos) { - /* Make room for the position attribute - * at the beginning of the vs_output_tab. */ - for (i = 15; i > 0; i--) { - vs_output_tab[i] = vs_output_tab[i-1]; - } - vs_output_tab[0] = 0; - } +static void r300_draw_emit_all_attribs(struct r300_context* r300) +{ + struct r300_shader_semantics* vs_outputs = &r300->vs->outputs; + int i, gen_count; /* Position. */ - if (r300->draw) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, - draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0)); + if (vs_outputs->pos != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, + vs_outputs->pos); + } else { + assert(0); } - vinfo->hwfmt[1] |= R300_INPUT_CNTL_POS; - vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; /* Point size. */ - if (psize) { - if (r300->draw) { - draw_emit_vertex_attr(vinfo, EMIT_1F_PSIZE, INTERP_POS, - draw_find_vs_output(r300->draw, TGSI_SEMANTIC_PSIZE, 0)); - } - vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; + if (vs_outputs->psize != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS, + vs_outputs->psize); } /* Colors. */ - for (i = 0; i < cols; i++) { - if (r300->draw) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, - draw_find_vs_output(r300->draw, TGSI_SEMANTIC_COLOR, i)); + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (vs_outputs->color[i] != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR, + vs_outputs->color[i]); } - vinfo->hwfmt[1] |= R300_INPUT_CNTL_COLOR; - vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i); } - /* Init i right here, increment it if fog is enabled. - * This gets around a double-increment problem. */ - i = 0; + /* XXX Back-face colors. */ - /* Fog. This is a special-cased texcoord. */ - if (fog) { - i++; - if (r300->draw) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, - draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0)); + /* Texture coordinates. */ + gen_count = 0; + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (vs_outputs->generic[i] != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, + vs_outputs->generic[i]); + gen_count++; } - vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i); - vinfo->hwfmt[3] |= (4 << (3 * i)); } - /* Texcoords. */ - for (; i < texs; i++) { - if (r300->draw) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, - draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i)); - } - vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i); - vinfo->hwfmt[3] |= (4 << (3 * i)); + /* Fog coordinates. */ + if (vs_outputs->fog != ATTR_UNUSED) { + r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, + vs_outputs->fog); + gen_count++; } - draw_compute_vertex_size(vinfo); + /* XXX magic */ + assert(gen_count <= 8); } /* Update the PSC tables. */ @@ -227,14 +171,14 @@ static void r300_vertex_psc(struct r300_context* r300) } /* Update the PSC tables for SW TCL, using Draw. */ -static void r300_swtcl_vertex_psc(struct r300_context* r300, - int* vs_output_tab) +static void r300_swtcl_vertex_psc(struct r300_context* r300) { struct r300_vertex_info *vformat = r300->vertex_info; struct vertex_info* vinfo = &vformat->vinfo; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; + int* vs_output_tab = r300->vs->output_stream_loc_swtcl; /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ @@ -279,109 +223,191 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300, (R300_LAST_VEC << (i & 1 ? 16 : 0)); } -/* Set up the RS block. This is the part of the chipset that actually does - * the rasterization of vertices into fragments. This is also the part of the - * chipset that locks up if any part of it is even slightly wrong. */ -static void r300_update_rs_block(struct r300_context* r300) +static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, + boolean swizzle_0001) { - struct r300_rs_block* rs = r300->rs_block; - struct tgsi_shader_info* info = &r300->fs->info; - int col_count = 0, fp_offset = 0, i, tex_count = 0; - int rs_tex_comp = 0; + rs->ip[id] |= R300_RS_COL_PTR(ptr); + if (swizzle_0001) { + rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001); + } else { + rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); + } + rs->inst[id] |= R300_RS_INST_COL_ID(id); +} - if (r300_screen(r300->context.screen)->caps->is_r500) { - for (i = 0; i < info->num_inputs; i++) { - switch (info->input_semantic_name[i]) { - case TGSI_SEMANTIC_COLOR: - rs->ip[col_count] |= - R500_RS_COL_PTR(col_count) | - R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); - col_count++; - break; - case TGSI_SEMANTIC_GENERIC: - rs->ip[tex_count] |= - R500_RS_SEL_S(rs_tex_comp) | - R500_RS_SEL_T(rs_tex_comp + 1) | - R500_RS_SEL_R(rs_tex_comp + 2) | - R500_RS_SEL_Q(rs_tex_comp + 3); - tex_count++; - rs_tex_comp += 4; - break; - default: - break; - } - } +static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) +{ + rs->inst[id] |= R300_RS_INST_COL_CN_WRITE | + R300_RS_INST_COL_ADDR(fp_offset); +} - /* Rasterize at least one color, or bad things happen. */ - if ((col_count == 0) && (tex_count == 0)) { - rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); - col_count++; - } +static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr, + boolean swizzle_X001) +{ + if (swizzle_X001) { + rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + R300_RS_SEL_S(R300_RS_SEL_C0) | + R300_RS_SEL_T(R300_RS_SEL_K0) | + R300_RS_SEL_R(R300_RS_SEL_K0) | + R300_RS_SEL_Q(R300_RS_SEL_K1); + } else { + rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + R300_RS_SEL_S(R300_RS_SEL_C0) | + R300_RS_SEL_T(R300_RS_SEL_C1) | + R300_RS_SEL_R(R300_RS_SEL_C2) | + R300_RS_SEL_Q(R300_RS_SEL_C3); + } + rs->inst[id] |= R300_RS_INST_TEX_ID(id); +} - for (i = 0; i < col_count; i++) { - rs->inst[i] |= R500_RS_INST_COL_ID(i) | - R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(fp_offset); - fp_offset++; - } +static void r300_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) +{ + rs->inst[id] |= R300_RS_INST_TEX_CN_WRITE | + R300_RS_INST_TEX_ADDR(fp_offset); +} - for (i = 0; i < tex_count; i++) { - rs->inst[i] |= R500_RS_INST_TEX_ID(i) | - R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_offset); - fp_offset++; - } +static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr, + boolean swizzle_0001) +{ + rs->ip[id] |= R500_RS_COL_PTR(ptr); + if (swizzle_0001) { + rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); + } else { + rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); + } + rs->inst[id] |= R500_RS_INST_COL_ID(id); +} +static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) +{ + rs->inst[id] |= R500_RS_INST_COL_CN_WRITE | + R500_RS_INST_COL_ADDR(fp_offset); +} + +static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr, + boolean swizzle_X001) +{ + int rs_tex_comp = ptr*4; + + if (swizzle_X001) { + rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | + R500_RS_SEL_T(R500_RS_IP_PTR_K0) | + R500_RS_SEL_R(R500_RS_IP_PTR_K0) | + R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } else { - for (i = 0; i < info->num_inputs; i++) { - switch (info->input_semantic_name[i]) { - case TGSI_SEMANTIC_COLOR: - rs->ip[col_count] |= - R300_RS_COL_PTR(col_count) | - R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); - col_count++; - break; - case TGSI_SEMANTIC_GENERIC: - rs->ip[tex_count] |= - R300_RS_TEX_PTR(rs_tex_comp) | - R300_RS_SEL_S(R300_RS_SEL_C0) | - R300_RS_SEL_T(R300_RS_SEL_C1) | - R300_RS_SEL_R(R300_RS_SEL_C2) | - R300_RS_SEL_Q(R300_RS_SEL_C3); - tex_count++; - rs_tex_comp+=4; - break; - default: - break; - } - } + rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | + R500_RS_SEL_T(rs_tex_comp + 1) | + R500_RS_SEL_R(rs_tex_comp + 2) | + R500_RS_SEL_Q(rs_tex_comp + 3); + } + rs->inst[id] |= R500_RS_INST_TEX_ID(id); +} - /* Rasterize at least one color, or bad things happen. */ - if (col_count == 0) { - rs->ip[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001); +static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) +{ + rs->inst[id] |= R500_RS_INST_TEX_CN_WRITE | + R500_RS_INST_TEX_ADDR(fp_offset); +} + +/* Set up the RS block. + * + * This is the part of the chipset that actually does the rasterization + * of vertices into fragments. This is also the part of the chipset that + * locks up if any part of it is even slightly wrong. */ +static void r300_update_rs_block(struct r300_context* r300, + struct r300_shader_semantics* vs_outputs, + struct r300_shader_semantics* fs_inputs) +{ + struct r300_rs_block* rs = r300->rs_block; + int i, col_count = 0, tex_count = 0, fp_offset = 0; + void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean); + void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); + void (*rX00_rs_tex)(struct r300_rs_block*, int, int, boolean); + void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int); + + if (r300_screen(r300->context.screen)->caps->is_r500) { + rX00_rs_col = r500_rs_col; + rX00_rs_col_write = r500_rs_col_write; + rX00_rs_tex = r500_rs_tex; + rX00_rs_tex_write = r500_rs_tex_write; + } else { + rX00_rs_col = r300_rs_col; + rX00_rs_col_write = r300_rs_col_write; + rX00_rs_tex = r300_rs_tex; + rX00_rs_tex_write = r300_rs_tex_write; + } + + /* Rasterize colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (vs_outputs->color[i] != ATTR_UNUSED) { + /* Always rasterize if it's written by the VS, + * otherwise it locks up. */ + rX00_rs_col(rs, col_count, i, FALSE); + + /* Write it to the FS input register if it's used by the FS. */ + if (fs_inputs->color[i] != ATTR_UNUSED) { + rX00_rs_col_write(rs, col_count, fp_offset); + fp_offset++; + } col_count++; + } else { + /* Skip the FS input register, leave it uninitialized. */ + /* If we try to set it to (0,0,0,1), it will lock up. */ + if (fs_inputs->color[i] != ATTR_UNUSED) { + fp_offset++; + } } + } - if (tex_count == 0) { - rs->ip[0] |= - R300_RS_SEL_S(R300_RS_SEL_K0) | - R300_RS_SEL_T(R300_RS_SEL_K0) | - R300_RS_SEL_R(R300_RS_SEL_K0) | - R300_RS_SEL_Q(R300_RS_SEL_K1); + /* Rasterize texture coordinates. */ + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (vs_outputs->generic[i] != ATTR_UNUSED) { + /* Always rasterize if it's written by the VS, + * otherwise it locks up. */ + rX00_rs_tex(rs, tex_count, tex_count, FALSE); + + /* Write it to the FS input register if it's used by the FS. */ + if (fs_inputs->generic[i] != ATTR_UNUSED) { + rX00_rs_tex_write(rs, tex_count, fp_offset); + fp_offset++; + } + tex_count++; + } else { + /* Skip the FS input register, leave it uninitialized. */ + /* If we try to set it to (0,0,0,1), it will lock up. */ + if (fs_inputs->generic[i] != ATTR_UNUSED) { + fp_offset++; + } } + } - for (i = 0; i < col_count; i++) { - rs->inst[i] |= R300_RS_INST_COL_ID(i) | - R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_offset); + /* Rasterize fog coordinates. */ + if (vs_outputs->fog != ATTR_UNUSED) { + /* Always rasterize if it's written by the VS, + * otherwise it locks up. */ + rX00_rs_tex(rs, tex_count, tex_count, TRUE); + + /* Write it to the FS input register if it's used by the FS. */ + if (fs_inputs->fog != ATTR_UNUSED) { + rX00_rs_tex_write(rs, tex_count, fp_offset); fp_offset++; } - - for (i = 0; i < tex_count; i++) { - rs->inst[i] |= R300_RS_INST_TEX_ID(i) | - R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_offset); + tex_count++; + } else { + /* Skip the FS input register, leave it uninitialized. */ + /* If we try to set it to (0,0,0,1), it will lock up. */ + if (fs_inputs->fog != ATTR_UNUSED) { fp_offset++; } } - rs->count = (rs_tex_comp) | (col_count << R300_IC_COUNT_SHIFT) | + /* Rasterize at least one color, or bad things happen. */ + if (col_count == 0 && tex_count == 0) { + rX00_rs_col(rs, 0, 0, TRUE); + col_count++; + } + + rs->count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; rs->inst_count = MAX3(col_count - 1, tex_count - 1, 0); @@ -391,9 +417,6 @@ static void r300_update_rs_block(struct r300_context* r300) static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_screen* r300screen = r300_screen(r300->context.screen); - int vs_output_tab[16]; - int i; - /* struct r300_shader_key* key; @@ -424,22 +447,18 @@ static void r300_update_derived_shader_state(struct r300_context* r300) /* Reset structures */ memset(r300->rs_block, 0, sizeof(struct r300_rs_block)); memset(r300->vertex_info, 0, sizeof(struct r300_vertex_info)); + memcpy(r300->vertex_info->vinfo.hwfmt, r300->vs->hwfmt, sizeof(uint)*4); - for (i = 0; i < 16; i++) { - vs_output_tab[i] = -1; - } - - /* Update states */ - r300_vs_output_tab_routes(r300, vs_output_tab); + r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs); if (r300screen->caps->has_tcl) { r300_vertex_psc(r300); } else { - r300_swtcl_vertex_psc(r300, vs_output_tab); + r300_draw_emit_all_attribs(r300); + draw_compute_vertex_size(&r300->vertex_info->vinfo); + r300_swtcl_vertex_psc(r300); } - r300_update_rs_block(r300); - r300->dirty_state |= R300_NEW_RS_BLOCK; } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index d13aa8f036b..093a21ebe24 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -34,8 +34,8 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) struct r300_texture_state* state = &tex->state; struct pipe_texture *pt = &tex->tex; - state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) | - R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff); + state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) | + R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff); if (tex->is_npot) { /* rectangles love this */ @@ -43,7 +43,7 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) state->format2 = (tex->pitch[0] - 1) & 0x1fff; } else { /* power of two textures (3D, mipmaps, and no pitch) */ - state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf); + state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf); } state->format1 = r300_translate_texformat(pt->format); @@ -57,17 +57,17 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) /* large textures on r500 */ if (is_r500) { - if (pt->width[0] > 2048) { + if (pt->width0 > 2048) { state->format2 |= R500_TXWIDTH_BIT11; } - if (pt->height[0] > 2048) { + if (pt->height0 > 2048) { state->format2 |= R500_TXHEIGHT_BIT11; } } - assert(is_r500 || (pt->width[0] <= 2048 && pt->height[0] <= 2048)); + assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048)); debug_printf("r300: Set texture state (%dx%d, %d levels)\n", - pt->width[0], pt->height[0], pt->last_level); + pt->width0, pt->height0, pt->last_level); } unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, @@ -105,7 +105,7 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) return 0; } - return align(pf_get_stride(&tex->tex.block, tex->tex.width[level]), 32); + return align(pf_get_stride(&tex->tex.block, u_minify(tex->tex.width0, level)), 32); } static void r300_setup_miptree(struct r300_texture* tex) @@ -115,14 +115,8 @@ static void r300_setup_miptree(struct r300_texture* tex) int i; for (i = 0; i <= base->last_level; i++) { - if (i > 0) { - base->width[i] = minify(base->width[i-1]); - base->height[i] = minify(base->height[i-1]); - base->depth[i] = minify(base->depth[i-1]); - } - - base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]); - base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]); + base->nblocksx[i] = pf_get_nblocksx(&base->block, u_minify(base->width0, i)); + base->nblocksy[i] = pf_get_nblocksy(&base->block, u_minify(base->height0, i)); stride = r300_texture_get_stride(tex, i); layer_size = stride * base->nblocksy[i]; @@ -130,7 +124,7 @@ static void r300_setup_miptree(struct r300_texture* tex) if (base->target == PIPE_TEXTURE_CUBE) size = layer_size * 6; else - size = layer_size * base->depth[i]; + size = layer_size * u_minify(base->depth0, i); tex->offset[i] = align(tex->size, 32); tex->size = tex->offset[i] + size; @@ -139,15 +133,15 @@ static void r300_setup_miptree(struct r300_texture* tex) debug_printf("r300: Texture miptree: Level %d " "(%dx%dx%d px, pitch %d bytes)\n", - i, base->width[i], base->height[i], base->depth[i], - stride); + i, u_minify(base->width0, i), u_minify(base->height0, i), + u_minify(base->depth0, i), stride); } } static void r300_setup_flags(struct r300_texture* tex) { - tex->is_npot = !util_is_power_of_two(tex->tex.width[0]) || - !util_is_power_of_two(tex->tex.height[0]); + tex->is_npot = !util_is_power_of_two(tex->tex.width0) || + !util_is_power_of_two(tex->tex.height0); } /* Create a new texture. */ @@ -207,8 +201,8 @@ static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, pipe_reference_init(&surface->reference, 1); pipe_texture_reference(&surface->texture, texture); surface->format = texture->format; - surface->width = texture->width[level]; - surface->height = texture->height[level]; + surface->width = u_minify(texture->width0, level); + surface->height = u_minify(texture->height0, level); surface->offset = offset; surface->usage = flags; surface->zslice = zslice; @@ -236,7 +230,7 @@ static struct pipe_texture* /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || - base->depth[0] != 1 || + base->depth0 != 1 || base->last_level != 0) { return NULL; } @@ -286,9 +280,9 @@ r300_video_surface_create(struct pipe_screen *screen, template.target = PIPE_TEXTURE_2D; template.format = PIPE_FORMAT_X8R8G8B8_UNORM; template.last_level = 0; - template.width[0] = util_next_power_of_two(width); - template.height[0] = util_next_power_of_two(height); - template.depth[0] = 1; + template.width0 = util_next_power_of_two(width); + template.height0 = util_next_power_of_two(height); + template.depth0 = 1; pf_get_block(template.format, &template.block); template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index 096707dda40..31248346bc6 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -1,5 +1,6 @@ /* * Copyright 2009 Corbin Simpson <[email protected]> + * Copyright 2009 Marek Olšák <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,89 +24,226 @@ #include "r300_vs.h" #include "r300_context.h" +#include "r300_screen.h" #include "r300_tgsi_to_rc.h" +#include "r300_reg.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_parse.h" #include "radeon_compiler.h" - -static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) +/* Convert info about VS output semantics into r300_shader_semantics. */ +static void r300_shader_read_vs_outputs( + struct tgsi_shader_info* info, + struct r300_shader_semantics* vs_outputs) { - struct r300_vertex_shader * vs = c->UserData; - struct tgsi_shader_info* info = &vs->info; - struct tgsi_parse_context parser; - struct tgsi_full_declaration * decl; - boolean pointsize = FALSE; - int out_colors = 0; - int colors = 0; - int out_generic = 0; - int generic = 0; int i; + unsigned index; - /* Fill in the input mapping */ - for (i = 0; i < info->num_inputs; i++) - c->code->inputs[i] = i; + r300_shader_semantics_reset(vs_outputs); - /* Fill in the output mapping */ for (i = 0; i < info->num_outputs; i++) { + index = info->output_semantic_index[i]; + switch (info->output_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + assert(index == 0); + vs_outputs->pos = i; + break; + case TGSI_SEMANTIC_PSIZE: - pointsize = TRUE; + assert(index == 0); + vs_outputs->psize = i; break; + case TGSI_SEMANTIC_COLOR: - out_colors++; + assert(index <= ATTR_COLOR_COUNT); + vs_outputs->color[index] = i; break; - case TGSI_SEMANTIC_FOG: + + case TGSI_SEMANTIC_BCOLOR: + assert(index <= ATTR_COLOR_COUNT); + vs_outputs->bcolor[index] = i; + break; + case TGSI_SEMANTIC_GENERIC: - out_generic++; + assert(index <= ATTR_GENERIC_COUNT); + vs_outputs->generic[index] = i; break; + + case TGSI_SEMANTIC_FOG: + assert(index == 0); + vs_outputs->fog = i; + break; + + default: + assert(0); } } +} - tgsi_parse_init(&parser, vs->state.tokens); +static void r300_shader_vap_output_fmt( + struct r300_shader_semantics* vs_outputs, + uint* hwfmt) +{ + int i, gen_count; - while (!tgsi_parse_end_of_tokens(&parser)) { - tgsi_parse_token(&parser); + /* Do the actual vertex_info setup. + * + * vertex_info has four uints of hardware-specific data in it. + * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL + * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM + * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0 + * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */ - if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION) - continue; + hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */ - decl = &parser.FullToken.FullDeclaration; + /* Position. */ + if (vs_outputs->pos != ATTR_UNUSED) { + hwfmt[1] |= R300_INPUT_CNTL_POS; + hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; + } else { + assert(0); + } - if (decl->Declaration.File != TGSI_FILE_OUTPUT) - continue; + /* Point size. */ + if (vs_outputs->psize != ATTR_UNUSED) { + hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; + } - switch (decl->Semantic.Name) { - case TGSI_SEMANTIC_POSITION: - c->code->outputs[decl->Range.First] = 0; - break; - case TGSI_SEMANTIC_PSIZE: - c->code->outputs[decl->Range.First] = 1; - break; - case TGSI_SEMANTIC_COLOR: - c->code->outputs[decl->Range.First] = 1 + - (pointsize ? 1 : 0) + - colors++; - break; - case TGSI_SEMANTIC_FOG: - case TGSI_SEMANTIC_GENERIC: - c->code->outputs[decl->Range.First] = 1 + - (pointsize ? 1 : 0) + - out_colors + - generic++; - break; - default: - debug_printf("r300: vs: Bad semantic declaration %d\n", - decl->Semantic.Name); - break; + /* Colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (vs_outputs->color[i] != ATTR_UNUSED) { + hwfmt[1] |= R300_INPUT_CNTL_COLOR; + hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; + } + } + + /* XXX Back-face colors. */ + + /* Texture coordinates. */ + gen_count = 0; + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (vs_outputs->generic[i] != ATTR_UNUSED) { + hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count); + hwfmt[3] |= (4 << (3 * gen_count)); + gen_count++; + } + } + + /* Fog coordinates. */ + if (vs_outputs->fog != ATTR_UNUSED) { + hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count); + hwfmt[3] |= (4 << (3 * gen_count)); + gen_count++; + } + + /* XXX magic */ + assert(gen_count <= 8); +} + +/* Set VS output stream locations for SWTCL. */ +static void r300_stream_locations_swtcl( + struct r300_shader_semantics* vs_outputs, + int* output_stream_loc) +{ + int i, tabi = 0, gen_count; + + /* XXX Check whether the numbers (0, 1, 2+i, etc.) are correct. + * These should go to VAP_PROG_STREAM_CNTL/DST_VEC_LOC. */ + + /* Position. */ + output_stream_loc[tabi++] = 0; + + /* Point size. */ + if (vs_outputs->psize != ATTR_UNUSED) { + output_stream_loc[tabi++] = 1; + } + + /* Colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (vs_outputs->color[i] != ATTR_UNUSED) { + output_stream_loc[tabi++] = 2 + i; + } + } + + /* Back-face colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (vs_outputs->bcolor[i] != ATTR_UNUSED) { + output_stream_loc[tabi++] = 4 + i; + } + } + + /* Texture coordinates. */ + gen_count = 0; + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (vs_outputs->bcolor[i] != ATTR_UNUSED) { + assert(tabi < 16); + output_stream_loc[tabi++] = 6 + gen_count; + gen_count++; } } - tgsi_parse_free(&parser); + /* Fog coordinates. */ + if (vs_outputs->fog != ATTR_UNUSED) { + assert(tabi < 16); + output_stream_loc[tabi++] = 6 + gen_count; + gen_count++; + } + + /* XXX magic */ + assert(gen_count <= 8); + + for (; tabi < 16;) { + output_stream_loc[tabi++] = -1; + } } +static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) +{ + struct r300_vertex_shader * vs = c->UserData; + struct r300_shader_semantics* outputs = &vs->outputs; + struct tgsi_shader_info* info = &vs->info; + int i, reg = 0; + + /* Fill in the input mapping */ + for (i = 0; i < info->num_inputs; i++) + c->code->inputs[i] = i; + + /* Position. */ + if (outputs->pos != ATTR_UNUSED) { + c->code->outputs[outputs->pos] = reg++; + } else { + assert(0); + } + + /* Point size. */ + if (outputs->psize != ATTR_UNUSED) { + c->code->outputs[outputs->psize] = reg++; + } + + /* Colors. */ + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + if (outputs->color[i] != ATTR_UNUSED) { + c->code->outputs[outputs->color[i]] = reg++; + } + } + + /* XXX Back-face colors. */ + + /* Texture coordinates. */ + for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + if (outputs->generic[i] != ATTR_UNUSED) { + c->code->outputs[outputs->generic[i]] = reg++; + } + } + + /* Fog coordinates. */ + if (outputs->fog != ATTR_UNUSED) { + c->code->outputs[outputs->fog] = reg++; + } +} void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs) @@ -113,6 +251,14 @@ void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_program_compiler compiler; struct tgsi_to_rc ttr; + /* Initialize. */ + r300_shader_read_vs_outputs(&vs->info, &vs->outputs); + r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt); + + if (!r300_screen(r300->context.screen)->caps->has_tcl) { + r300_stream_locations_swtcl(&vs->outputs, vs->output_stream_loc_swtcl); + } + /* Setup the compiler */ rc_init(&compiler.Base); @@ -137,7 +283,7 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { - /* Todo: Fail gracefully */ + /* XXX Fail gracefully */ fprintf(stderr, "r300 VP: Compiler error\n"); abort(); } diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 00b02bf510d..283dd5a9e83 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -1,5 +1,6 @@ /* * Copyright 2009 Corbin Simpson <[email protected]> + * Copyright 2009 Marek Olšák <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,15 +26,20 @@ #include "pipe/p_state.h" #include "tgsi/tgsi_scan.h" - #include "radeon_code.h" +#include "r300_shader_semantics.h" + struct r300_context; struct r300_vertex_shader { /* Parent class */ struct pipe_shader_state state; + struct tgsi_shader_info info; + struct r300_shader_semantics outputs; + int output_stream_loc_swtcl[16]; + uint hwfmt[4]; /* Has this shader been translated yet? */ boolean translated; @@ -42,9 +48,6 @@ struct r300_vertex_shader { struct r300_vertex_program_code code; }; - -extern struct r300_vertex_program_code r300_passthrough_vertex_shader; - void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index bdbb7fa9b98..f8bf3e9974e 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -107,6 +107,11 @@ softpipe_destroy( struct pipe_context *pipe ) pipe_texture_reference(&softpipe->texture[i], NULL); } + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]); + pipe_texture_reference(&softpipe->vertex_textures[i], NULL); + } + for (i = 0; i < Elements(softpipe->constants); i++) { if (softpipe->constants[i].buffer) { pipe_buffer_reference(&softpipe->constants[i].buffer, NULL); @@ -153,6 +158,11 @@ softpipe_is_texture_referenced( struct pipe_context *pipe, softpipe->tex_cache[i]->texture == texture) return PIPE_REFERENCED_FOR_READ; } + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + if (softpipe->vertex_tex_cache[i] && + softpipe->vertex_tex_cache[i]->texture == texture) + return PIPE_REFERENCED_FOR_READ; + } return PIPE_UNREFERENCED; } @@ -192,7 +202,8 @@ softpipe_create( struct pipe_screen *screen ) softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; - softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states; + softpipe->pipe.bind_fragment_sampler_states = softpipe_bind_sampler_states; + softpipe->pipe.bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states; softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; @@ -217,7 +228,8 @@ softpipe_create( struct pipe_screen *screen ) softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; - softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; + softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures; + softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; @@ -247,7 +259,9 @@ softpipe_create( struct pipe_screen *screen ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen ); - + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache(screen); + } /* setup quad rendering stages */ softpipe->quad.shade = sp_quad_shade_stage(softpipe); @@ -263,7 +277,7 @@ softpipe_create( struct pipe_screen *screen ) goto fail; draw_texture_samplers(softpipe->draw, - PIPE_MAX_SAMPLERS, + PIPE_MAX_VERTEX_SAMPLERS, (struct tgsi_sampler **) softpipe->tgsi.vert_samplers_list); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index a735573d6fb..8ce20c5744c 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -53,6 +53,7 @@ struct softpipe_context { /** Constant state objects */ struct pipe_blend_state *blend; struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_depth_stencil_alpha_state *depth_stencil; struct pipe_rasterizer_state *rasterizer; struct sp_fragment_shader *fs; @@ -66,12 +67,15 @@ struct softpipe_context { struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; unsigned num_samplers; unsigned num_textures; + unsigned num_vertex_samplers; + unsigned num_vertex_textures; unsigned num_vertex_elements; unsigned num_vertex_buffers; @@ -121,7 +125,7 @@ struct softpipe_context { /** TGSI exec things */ struct { - struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_SAMPLERS]; + struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS]; struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS]; } tgsi; @@ -139,6 +143,7 @@ struct softpipe_context { unsigned tex_timestamp; struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS]; unsigned use_sse : 1; unsigned dump_fs : 1; diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index e38b767cf2c..75dac810a12 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -55,6 +55,9 @@ softpipe_flush( struct pipe_context *pipe, for (i = 0; i < softpipe->num_textures; i++) { sp_flush_tex_tile_cache(softpipe->tex_cache[i]); } + for (i = 0; i < softpipe->num_vertex_textures; i++) { + sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]); + } } if (flags & PIPE_FLUSH_SWAPBUFFERS) { diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 81fb7aa20c6..6bf3df8e6ad 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -58,7 +58,9 @@ softpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return PIPE_MAX_SAMPLERS; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return PIPE_MAX_SAMPLERS; + return PIPE_MAX_VERTEX_SAMPLERS; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: return 1; case PIPE_CAP_TWO_SIDED_STENCIL: @@ -143,6 +145,10 @@ softpipe_is_format_supported( struct pipe_screen *screen, case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: case PIPE_FORMAT_Z32_FLOAT: + case PIPE_FORMAT_R8G8_SNORM: + case PIPE_FORMAT_B6UG5SR5S_NORM: + case PIPE_FORMAT_X8UB8UG8SR8S_NORM: + case PIPE_FORMAT_A8B8G8R8_SNORM: return FALSE; default: return TRUE; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 77ee3c1136b..d488fb8710b 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -104,6 +104,10 @@ void * softpipe_create_sampler_state(struct pipe_context *, const struct pipe_sampler_state *); void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); +void +softpipe_bind_vertex_sampler_states(struct pipe_context *, + unsigned num_samplers, + void **samplers); void softpipe_delete_sampler_state(struct pipe_context *, void *); void * @@ -150,6 +154,11 @@ void softpipe_set_sampler_textures( struct pipe_context *, unsigned num, struct pipe_texture ** ); +void +softpipe_set_vertex_sampler_textures(struct pipe_context *, + unsigned num_textures, + struct pipe_texture **); + void softpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 3bc96b95385..c24a737d07b 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -213,6 +213,19 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) } } } + + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + struct softpipe_tex_tile_cache *tc = softpipe->vertex_tex_cache[i]; + + if (tc->texture) { + struct softpipe_texture *spt = softpipe_texture(tc->texture); + + if (spt->timestamp != tc->timestamp) { + sp_tex_tile_cache_validate_texture(tc); + tc->timestamp = spt->timestamp; + } + } + } } diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index db0b8ab76b1..ceb4e338f1a 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -94,6 +94,34 @@ softpipe_bind_sampler_states(struct pipe_context *pipe, void +softpipe_bind_vertex_sampler_states(struct pipe_context *pipe, + unsigned num_samplers, + void **samplers) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned i; + + assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS); + + /* Check for no-op */ + if (num_samplers == softpipe->num_vertex_samplers && + !memcmp(softpipe->vertex_samplers, samplers, num_samplers * sizeof(void *))) + return; + + draw_flush(softpipe->draw); + + for (i = 0; i < num_samplers; ++i) + softpipe->vertex_samplers[i] = samplers[i]; + for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) + softpipe->vertex_samplers[i] = NULL; + + softpipe->num_vertex_samplers = num_samplers; + + softpipe->dirty |= SP_NEW_SAMPLER; +} + + +void softpipe_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { @@ -122,6 +150,37 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, } +void +softpipe_set_vertex_sampler_textures(struct pipe_context *pipe, + unsigned num_textures, + struct pipe_texture **textures) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + + assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); + + /* Check for no-op */ + if (num_textures == softpipe->num_vertex_textures && + !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { + return; + } + + draw_flush(softpipe->draw); + + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; + + pipe_texture_reference(&softpipe->vertex_textures[i], tex); + sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex); + } + + softpipe->num_vertex_textures = num_textures; + + softpipe->dirty |= SP_NEW_TEXTURE; +} + + /** * Find/create an sp_sampler_varient object for sampling the given texture, * sampler and tex unit. @@ -185,16 +244,16 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) * fragment programs. */ for (i = 0; i <= softpipe->vs->max_sampler; i++) { - if (softpipe->sampler[i]) { + if (softpipe->vertex_samplers[i]) { softpipe->tgsi.vert_samplers_list[i] = get_sampler_varient( i, - sp_sampler(softpipe->sampler[i]), - softpipe->texture[i], + sp_sampler(softpipe->vertex_samplers[i]), + softpipe->vertex_textures[i], TGSI_PROCESSOR_VERTEX ); sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], - softpipe->tex_cache[i], - softpipe->texture[i] ); + softpipe->vertex_tex_cache[i], + softpipe->vertex_textures[i] ); } } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index c22ee86b66c..e26153b1d90 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -521,7 +521,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); - float rho = MAX2(dsdx, dsdy) * texture->width[0]; + float rho = MAX2(dsdx, dsdy) * texture->width0; float lambda; lambda = util_fast_log2(rho); @@ -545,8 +545,8 @@ compute_lambda_2d(const struct sp_sampler_varient *samp, float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]); - float maxx = MAX2(dsdx, dsdy) * texture->width[0]; - float maxy = MAX2(dtdx, dtdy) * texture->height[0]; + float maxx = MAX2(dsdx, dsdy) * texture->width0; + float maxy = MAX2(dtdx, dtdy) * texture->height0; float rho = MAX2(maxx, maxy); float lambda; @@ -573,9 +573,9 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]); float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]); float dpdy = fabsf(p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]); - float maxx = MAX2(dsdx, dsdy) * texture->width[0]; - float maxy = MAX2(dtdx, dtdy) * texture->height[0]; - float maxz = MAX2(dpdx, dpdy) * texture->depth[0]; + float maxx = MAX2(dsdx, dsdy) * texture->width0; + float maxy = MAX2(dtdx, dtdy) * texture->height0; + float maxz = MAX2(dpdx, dpdy) * texture->depth0; float rho, lambda; rho = MAX2(maxx, maxy); @@ -644,8 +644,8 @@ get_texel_2d(const struct sp_sampler_varient *samp, const struct pipe_texture *texture = samp->texture; unsigned level = addr.bits.level; - if (x < 0 || x >= (int) texture->width[level] || - y < 0 || y >= (int) texture->height[level]) { + if (x < 0 || x >= (int) u_minify(texture->width0, level) || + y < 0 || y >= (int) u_minify(texture->height0, level)) { return samp->sampler->border_color; } else { @@ -737,9 +737,9 @@ get_texel_3d(const struct sp_sampler_varient *samp, const struct pipe_texture *texture = samp->texture; unsigned level = addr.bits.level; - if (x < 0 || x >= (int) texture->width[level] || - y < 0 || y >= (int) texture->height[level] || - z < 0 || z >= (int) texture->depth[level]) { + if (x < 0 || x >= (int) u_minify(texture->width0, level) || + y < 0 || y >= (int) u_minify(texture->height0, level) || + z < 0 || z >= (int) u_minify(texture->depth0, level)) { return samp->sampler->border_color; } else { @@ -925,7 +925,7 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; + width = u_minify(texture->width0, level0); assert(width > 0); @@ -961,8 +961,8 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, level0 = samp->level; - width = texture->width[level0]; - height = texture->height[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); assert(width > 0); assert(height > 0); @@ -1008,8 +1008,8 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; - height = texture->height[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); assert(width > 0); assert(height > 0); @@ -1046,9 +1046,9 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; - height = texture->height[level0]; - depth = texture->depth[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); + depth = u_minify(texture->depth0, level0); assert(width > 0); assert(height > 0); @@ -1088,7 +1088,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; + width = u_minify(texture->width0, level0); assert(width > 0); @@ -1127,8 +1127,8 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; - height = texture->height[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); assert(width > 0); assert(height > 0); @@ -1174,8 +1174,8 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; - height = texture->height[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); assert(width > 0); assert(height > 0); @@ -1221,9 +1221,9 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, union tex_tile_address addr; level0 = samp->level; - width = texture->width[level0]; - height = texture->height[level0]; - depth = texture->depth[level0]; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); + depth = u_minify(texture->depth0, level0); addr.value = 0; addr.bits.level = level0; @@ -1778,8 +1778,8 @@ sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, samp->texture = texture; samp->cache = tex_cache; - samp->xpot = util_unsigned_logbase2( texture->width[0] ); - samp->ypot = util_unsigned_logbase2( texture->height[0] ); + samp->xpot = util_unsigned_logbase2( texture->width0 ); + samp->ypot = util_unsigned_logbase2( texture->height0 ); samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level); } diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index 407a22a9f4b..e50a76a73bc 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -35,6 +35,7 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "util/u_tile.h" +#include "util/u_math.h" #include "sp_context.h" #include "sp_surface.h" #include "sp_texture.h" @@ -246,9 +247,9 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, addr.bits.level, addr.bits.z, PIPE_TRANSFER_READ, 0, 0, - tc->texture->width[addr.bits.level], - tc->texture->height[addr.bits.level]); - + u_minify(tc->texture->width0, addr.bits.level), + u_minify(tc->texture->height0, addr.bits.level)); + tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); tc->tex_face = addr.bits.face; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 7caf2928b4b..ac5f61e46f4 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -52,16 +52,17 @@ softpipe_texture_layout(struct pipe_screen *screen, { struct pipe_texture *pt = &spt->base; unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; + unsigned width = pt->width0; + unsigned height = pt->height0; + unsigned depth = pt->depth0; unsigned buffer_size = 0; + pt->width0 = width; + pt->height0 = height; + pt->depth0 = depth; + for (level = 0; level <= pt->last_level; level++) { - pt->width[level] = width; - pt->height[level] = height; - pt->depth[level] = depth; pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); spt->stride[level] = pt->nblocksx[level]*pt->block.size; @@ -72,9 +73,9 @@ softpipe_texture_layout(struct pipe_screen *screen, ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * spt->stride[level]); - width = minify(width); - height = minify(height); - depth = minify(depth); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } spt->buffer = screen->buffer_create(screen, 32, @@ -96,12 +97,12 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, PIPE_BUFFER_USAGE_GPU_READ_WRITE); unsigned tex_usage = spt->base.tex_usage; - spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); - spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width0); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height0); spt->buffer = screen->surface_buffer_create( screen, - spt->base.width[0], - spt->base.height[0], + spt->base.width0, + spt->base.height0, spt->base.format, usage, tex_usage, @@ -126,9 +127,9 @@ softpipe_texture_create(struct pipe_screen *screen, pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; - spt->pot = (util_is_power_of_two(template->width[0]) && - util_is_power_of_two(template->height[0]) && - util_is_power_of_two(template->depth[0])); + spt->pot = (util_is_power_of_two(template->width0) && + util_is_power_of_two(template->height0) && + util_is_power_of_two(template->depth0)); if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | PIPE_TEXTURE_USAGE_PRIMARY)) { @@ -163,7 +164,7 @@ softpipe_texture_blanket(struct pipe_screen * screen, /* Only supports one type */ if (base->target != PIPE_TEXTURE_2D || base->last_level != 0 || - base->depth[0] != 1) { + base->depth0 != 1) { return NULL; } @@ -174,8 +175,8 @@ softpipe_texture_blanket(struct pipe_screen * screen, spt->base = *base; pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; - spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); - spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width0); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height0); spt->stride[0] = stride[0]; pipe_buffer_reference(&spt->buffer, buffer); @@ -213,8 +214,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen, pipe_reference_init(&ps->reference, 1); pipe_texture_reference(&ps->texture, pt); ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; + ps->width = u_minify(pt->width0, level); + ps->height = u_minify(pt->height0, level); ps->offset = spt->level_offset[level]; ps->usage = usage; @@ -434,9 +435,9 @@ softpipe_video_surface_create(struct pipe_screen *screen, template.format = PIPE_FORMAT_X8R8G8B8_UNORM; template.last_level = 0; /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */ - template.width[0] = util_next_power_of_two(width); - template.height[0] = util_next_power_of_two(height); - template.depth[0] = 1; + template.width0 = util_next_power_of_two(width); + template.height0 = util_next_power_of_two(height); + template.depth0 = 1; pf_get_block(template.format, &template.block); template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; diff --git a/src/gallium/drivers/svga/Makefile b/src/gallium/drivers/svga/Makefile index d1413319c97..f3619081875 100644 --- a/src/gallium/drivers/svga/Makefile +++ b/src/gallium/drivers/svga/Makefile @@ -4,8 +4,8 @@ include $(TOP)/configs/current LIBNAME = svga C_SOURCES = \ - svgadump/st_shader_dump.c \ - svgadump/st_shader_op.c \ + svgadump/svga_shader_dump.c \ + svgadump/svga_shader_op.c \ svgadump/svga_dump.c \ svga_cmd.c \ svga_context.c \ @@ -50,6 +50,9 @@ C_SOURCES = \ LIBRARY_INCLUDES = \ -I$(TOP)/src/gallium/drivers/svga/include +# With linux-debug we get a lots of warnings, filter out the bad flags. +CFLAGS := $(filter-out -pedantic, $(filter-out -ansi, $(CFLAGS))) + LIBRARY_DEFINES = \ -std=gnu99 -fvisibility=hidden \ -DHAVE_STDINT_H -DHAVE_SYS_TYPES_H diff --git a/src/gallium/drivers/svga/SConscript b/src/gallium/drivers/svga/SConscript index ff9645fc03a..737b791ceb0 100644 --- a/src/gallium/drivers/svga/SConscript +++ b/src/gallium/drivers/svga/SConscript @@ -60,8 +60,8 @@ sources = [ 'svga_tgsi_insn.c', 'svgadump/svga_dump.c', - 'svgadump/st_shader_dump.c', - 'svgadump/st_shader_op.c', + 'svgadump/svga_shader_dump.c', + 'svgadump/svga_shader_op.c', ] svga = env.ConvenienceLibrary( diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index 73233957f36..c3de12b4a39 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -230,7 +230,9 @@ void svga_context_flush( struct svga_context *svga, struct pipe_fence_handle **pfence ) { struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); - + + svga->curr.nr_fbs = 0; + /* Unmap upload manager buffers: */ u_upload_flush(svga->upload_vb); diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 9a3e92fd8d1..e650a251d19 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -191,6 +191,11 @@ struct svga_state struct pipe_framebuffer_state framebuffer; float depthscale; + /* Hack to limit the number of different render targets between + * flushes. Helps avoid blowing out our surface cache in EXA. + */ + int nr_fbs; + struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_blend_color blend_color; diff --git a/src/gallium/drivers/svga/svga_debug.h b/src/gallium/drivers/svga/svga_debug.h index b7bb5686ed3..3a3fcd8fae2 100644 --- a/src/gallium/drivers/svga/svga_debug.h +++ b/src/gallium/drivers/svga/svga_debug.h @@ -43,6 +43,7 @@ #define DEBUG_FLUSH 0x1000 /* flush after every draw */ #define DEBUG_SYNC 0x2000 /* sync after every flush */ #define DEBUG_QUERY 0x4000 +#define DEBUG_CACHE 0x8000 #ifdef DEBUG extern int SVGA_DEBUG; diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index 1b371cecc61..8db40d0fd57 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -29,10 +29,13 @@ #include "util/u_memory.h" #include "util/u_math.h" +#include "svga_context.h" #include "svga_draw.h" #include "svga_draw_private.h" +#include "svga_debug.h" #include "svga_screen.h" #include "svga_screen_buffer.h" +#include "svga_screen_texture.h" #include "svga_winsys.h" #include "svga_cmd.h" @@ -160,6 +163,10 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) ib_handle[i] = handle; } + SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n", + svga_surface(svga->curr.framebuffer.cbufs[0])->handle, + hwtnl->cmd.prim_count); + ret = SVGA3D_BeginDrawPrimitives(swc, &vdecl, hwtnl->cmd.vdecl_count, diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c index 5a4a8c0f5f1..4f575b06e62 100644 --- a/src/gallium/drivers/svga/svga_pipe_blit.c +++ b/src/gallium/drivers/svga/svga_pipe_blit.c @@ -25,6 +25,7 @@ #include "svga_screen_texture.h" #include "svga_context.h" +#include "svga_debug.h" #include "svga_cmd.h" #define FILE_DEBUG_FLAG DEBUG_BLIT @@ -43,6 +44,13 @@ static void svga_surface_copy(struct pipe_context *pipe, svga_hwtnl_flush_retry( svga ); + SVGA_DBG(DEBUG_DMA, "blit to sid %p (%d,%d), from sid %p (%d,%d) sz %dx%d\n", + svga_surface(dest)->handle, + destx, desty, + svga_surface(src)->handle, + srcx, srcy, + width, height); + ret = SVGA3D_BeginSurfaceCopy(svga->swc, src, dest, diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index 8977d26541c..6195c3897ed 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -24,12 +24,14 @@ **********************************************************/ #include "svga_cmd.h" +#include "svga_debug.h" #include "pipe/p_defines.h" #include "util/u_pack_color.h" #include "svga_context.h" #include "svga_state.h" +#include "svga_screen_texture.h" static enum pipe_error @@ -98,6 +100,10 @@ svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, { struct svga_context *svga = svga_context( pipe ); int ret; + + if (buffers & PIPE_CLEAR_COLOR) + SVGA_DBG(DEBUG_DMA, "clear sid %p\n", + svga_surface(svga->curr.framebuffer.cbufs[0])->handle); ret = try_clear( svga, buffers, rgba, depth, stencil ); diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c index 942366de721..0becb0765ac 100644 --- a/src/gallium/drivers/svga/svga_pipe_flush.c +++ b/src/gallium/drivers/svga/svga_pipe_flush.c @@ -59,6 +59,9 @@ static void svga_flush( struct pipe_context *pipe, /* Flush command queue. */ svga_context_flush(svga, fence); + + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s flags %x fence_ptr %p\n", + __FUNCTION__, flags, fence ? *fence : 0x0); } diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 3eeca6b784b..b4e57c5d15b 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -234,9 +234,9 @@ static void svga_set_sampler_textures(struct pipe_context *pipe, void svga_init_sampler_functions( struct svga_context *svga ) { svga->pipe.create_sampler_state = svga_create_sampler_state; - svga->pipe.bind_sampler_states = svga_bind_sampler_states; + svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states; svga->pipe.delete_sampler_state = svga_delete_sampler_state; - svga->pipe.set_sampler_textures = svga_set_sampler_textures; + svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures; } diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 3afcaffff55..fc1b3c980ef 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -57,6 +57,7 @@ static const struct debug_named_value svga_debug_flags[] = { { "perf", DEBUG_PERF }, { "flush", DEBUG_FLUSH }, { "sync", DEBUG_SYNC }, + { "cache", DEBUG_CACHE }, {NULL, 0} }; #endif @@ -297,6 +298,10 @@ svga_fence_finish(struct pipe_screen *screen, unsigned flag) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; + + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", + __FUNCTION__, fence); + return sws->fence_finish(sws, fence, flag); } diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c index 3b7811734ed..1f8a8896723 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.c +++ b/src/gallium/drivers/svga/svga_screen_buffer.c @@ -71,7 +71,10 @@ svga_buffer_create_host_surface(struct svga_screen *ss, sbuf->key.numFaces = 1; sbuf->key.numMipLevels = 1; + sbuf->key.cachable = 1; + SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size); + sbuf->handle = svga_screen_surface_create(ss, &sbuf->key); if(!sbuf->handle) return PIPE_ERROR_OUT_OF_MEMORY; @@ -82,7 +85,7 @@ svga_buffer_create_host_surface(struct svga_screen *ss, */ sbuf->hw.flags.discard = TRUE; - SVGA_DBG(DEBUG_DMA, " grab sid %p sz %d\n", sbuf->handle, sbuf->base.size); + SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size); } return PIPE_OK; @@ -444,7 +447,7 @@ svga_buffer_map_range( struct pipe_screen *screen, enum pipe_error ret; struct pipe_fence_handle *fence = NULL; - SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p, bytes %u - %u\n", + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n", sbuf->handle, 0, sbuf->base.size); memset(&flags, 0, sizeof flags); @@ -776,12 +779,11 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen, /* * We are not the creator of this surface and therefore we must not - * cache it for reuse. The caching code only caches SVGA3D_BUFFER surfaces - * so make sure this isn't one of those. + * cache it for reuse. Set the cacheable flag to zero in the key to + * prevent this. */ - - assert(format != SVGA3D_BUFFER); sbuf->key.format = format; + sbuf->key.cachable = 0; sws->surface_reference(sws, &sbuf->handle, srf); return buf; @@ -794,6 +796,8 @@ svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer) struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen); struct svga_winsys_surface *vsurf = NULL; + assert(svga_buffer(buffer)->key.cachable == 0); + svga_buffer(buffer)->key.cachable = 0; sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle); return vsurf; } diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c index 7360c1688bb..8a06383f61e 100644 --- a/src/gallium/drivers/svga/svga_screen_cache.c +++ b/src/gallium/drivers/svga/svga_screen_cache.c @@ -24,6 +24,7 @@ **********************************************************/ #include "util/u_memory.h" +#include "util/u_hash.h" #include "svga_debug.h" #include "svga_winsys.h" @@ -36,24 +37,11 @@ /** * Compute the bucket for this key. - * - * We simply compute log2(width) for now, but */ static INLINE unsigned svga_screen_cache_bucket(const struct svga_host_surface_cache_key *key) { - unsigned bucket = 0; - unsigned size = key->size.width; - - while ((size >>= 1)) - ++bucket; - - if(key->flags & SVGA3D_SURFACE_HINT_INDEXBUFFER) - bucket += 32; - - assert(bucket < SVGA_HOST_SURFACE_CACHE_BUCKETS); - - return bucket; + return util_hash_crc32( key, sizeof *key ) % SVGA_HOST_SURFACE_CACHE_BUCKETS; } @@ -69,6 +57,8 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen, unsigned bucket; unsigned tries = 0; + assert(key->cachable); + bucket = svga_screen_cache_bucket(key); pipe_mutex_lock(cache->mutex); @@ -104,11 +94,9 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen, pipe_mutex_unlock(cache->mutex); -#if 0 - _debug_printf("%s: cache %s after %u tries\n", __FUNCTION__, handle ? "hit" : "miss", tries); -#else - (void)tries; -#endif + if (SVGA_DEBUG & DEBUG_DMA) + debug_printf("%s: cache %s after %u tries (bucket %d)\n", __FUNCTION__, + handle ? "hit" : "miss", tries, bucket); return handle; } @@ -128,6 +116,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen, struct svga_host_surface_cache_entry *entry = NULL; struct svga_winsys_surface *handle = *p_handle; + assert(key->cachable); assert(handle); if(!handle) @@ -137,15 +126,16 @@ svga_screen_cache_add(struct svga_screen *svgascreen, pipe_mutex_lock(cache->mutex); if(!LIST_IS_EMPTY(&cache->empty)) { - /* use the first empty entry */ - entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head); + /* use the first empty entry */ + entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head); - LIST_DEL(&entry->head); - } + LIST_DEL(&entry->head); + } else if(!LIST_IS_EMPTY(&cache->unused)) { /* free the last used buffer and reuse its entry */ entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->unused.prev, head); - SVGA_DBG(DEBUG_DMA, "unref sid %p\n", entry->handle); + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "unref sid %p (make space)\n", entry->handle); sws->surface_reference(sws, &entry->handle, NULL); LIST_DEL(&entry->bucket_head); @@ -157,11 +147,14 @@ svga_screen_cache_add(struct svga_screen *svgascreen, entry->handle = handle; memcpy(&entry->key, key, sizeof entry->key); + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "cache sid %p\n", entry->handle); LIST_ADD(&entry->head, &cache->validated); } else { /* Couldn't cache the buffer -- this really shouldn't happen */ - SVGA_DBG(DEBUG_DMA, "unref sid %p\n", handle); + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "unref sid %p (couldn't find space)\n", handle); sws->surface_reference(sws, &handle, NULL); } @@ -220,7 +213,8 @@ svga_screen_cache_cleanup(struct svga_screen *svgascreen) for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) { if(cache->entries[i].handle) { - SVGA_DBG(DEBUG_DMA, "unref sid %p\n", cache->entries[i].handle); + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "unref sid %p (shutdown)\n", cache->entries[i].handle); sws->surface_reference(sws, &cache->entries[i].handle, NULL); } @@ -261,18 +255,45 @@ svga_screen_surface_create(struct svga_screen *svgascreen, { struct svga_winsys_screen *sws = svgascreen->sws; struct svga_winsys_surface *handle = NULL; + boolean cachable = SVGA_SURFACE_CACHE_ENABLED && key->cachable; + + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "%s sz %dx%dx%d mips %d faces %d cachable %d\n", + __FUNCTION__, + key->size.width, + key->size.height, + key->size.depth, + key->numMipLevels, + key->numFaces, + key->cachable); + + if (cachable) { + if (key->format == SVGA3D_BUFFER) { + /* For buffers, round the buffer size up to the nearest power + * of two to increase the probability of cache hits. Keep + * texture surface dimensions unchanged. + */ + uint32_t size = 1; + while(size < key->size.width) + size <<= 1; + key->size.width = size; + } - if (SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) { - /* round the buffer size up to the nearest power of two to increase the - * probability of cache hits */ - uint32_t size = 1; - while(size < key->size.width) - size <<= 1; - key->size.width = size; - handle = svga_screen_cache_lookup(svgascreen, key); - if (handle) - SVGA_DBG(DEBUG_DMA, " reuse sid %p sz %d\n", handle, size); + if (handle) { + if (key->format == SVGA3D_BUFFER) + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "reuse sid %p sz %d (buffer)\n", handle, + key->size.width); + else + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + "reuse sid %p sz %dx%dx%d mips %d faces %d\n", handle, + key->size.width, + key->size.height, + key->size.depth, + key->numMipLevels, + key->numFaces); + } } if (!handle) { @@ -283,7 +304,12 @@ svga_screen_surface_create(struct svga_screen *svgascreen, key->numFaces, key->numMipLevels); if (handle) - SVGA_DBG(DEBUG_DMA, "create sid %p sz %d\n", handle, key->size); + SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, + " CREATE sid %p sz %dx%dx%d\n", + handle, + key->size.width, + key->size.height, + key->size.depth); } return handle; @@ -297,11 +323,16 @@ svga_screen_surface_destroy(struct svga_screen *svgascreen, { struct svga_winsys_screen *sws = svgascreen->sws; - if(SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) { + /* We only set the cachable flag for surfaces of which we are the + * exclusive owner. So just hold onto our existing reference in + * that case. + */ + if(SVGA_SURFACE_CACHE_ENABLED && key->cachable) { svga_screen_cache_add(svgascreen, key, p_handle); } else { - SVGA_DBG(DEBUG_DMA, "unref sid %p\n", *p_handle); + SVGA_DBG(DEBUG_DMA, + "unref sid %p (uncachable)\n", *p_handle); sws->surface_reference(sws, p_handle, NULL); } } diff --git a/src/gallium/drivers/svga/svga_screen_cache.h b/src/gallium/drivers/svga/svga_screen_cache.h index 1bbe9877688..f5aa740d408 100644 --- a/src/gallium/drivers/svga/svga_screen_cache.h +++ b/src/gallium/drivers/svga/svga_screen_cache.h @@ -36,10 +36,18 @@ #include "util/u_double_list.h" -/* TODO: Reduce this once we don't allocate an index buffer per draw call */ +/* Guess the storage size of cached surfaces and try and keep it under + * this amount: + */ +#define SVGA_HOST_SURFACE_CACHE_BYTES 16*1024*1024 + +/* Maximum number of discrete surfaces in the cache: + */ #define SVGA_HOST_SURFACE_CACHE_SIZE 1024 -#define SVGA_HOST_SURFACE_CACHE_BUCKETS 64 +/* Number of hash buckets: + */ +#define SVGA_HOST_SURFACE_CACHE_BUCKETS 256 struct svga_winsys_surface; @@ -53,8 +61,9 @@ struct svga_host_surface_cache_key SVGA3dSurfaceFlags flags; SVGA3dSurfaceFormat format; SVGA3dSize size; - uint32_t numFaces; - uint32_t numMipLevels; + uint32_t numFaces:24; + uint32_t numMipLevels:7; + uint32_t cachable:1; /* False if this is a shared surface */ }; diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c index 8472dea04da..6e10d65a205 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ b/src/gallium/drivers/svga/svga_screen_texture.c @@ -266,14 +266,8 @@ svga_texture_create(struct pipe_screen *screen, const struct pipe_texture *templat) { struct svga_screen *svgascreen = svga_screen(screen); - struct svga_winsys_screen *sws = svgascreen->sws; struct svga_texture *tex = CALLOC_STRUCT(svga_texture); unsigned width, height, depth; - SVGA3dSurfaceFlags flags = 0; - SVGA3dSurfaceFormat format; - SVGA3dSize size; - uint32 numFaces; - uint32 numMipLevels; unsigned level; if (!tex) @@ -287,37 +281,35 @@ svga_texture_create(struct pipe_screen *screen, if(templat->last_level >= SVGA_MAX_TEXTURE_LEVELS) goto error2; - width = templat->width[0]; - height = templat->height[0]; - depth = templat->depth[0]; + width = templat->width0; + height = templat->height0; + depth = templat->depth0; for(level = 0; level <= templat->last_level; ++level) { - tex->base.width[level] = width; - tex->base.height[level] = height; - tex->base.depth[level] = depth; tex->base.nblocksx[level] = pf_get_nblocksx(&tex->base.block, width); tex->base.nblocksy[level] = pf_get_nblocksy(&tex->base.block, height); - width = minify(width); - height = minify(height); - depth = minify(depth); + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); } - size.width = templat->width[0]; - size.height = templat->height[0]; - size.depth = templat->depth[0]; + tex->key.flags = 0; + tex->key.size.width = templat->width0; + tex->key.size.height = templat->height0; + tex->key.size.depth = templat->depth0; if(templat->target == PIPE_TEXTURE_CUBE) { - flags |= SVGA3D_SURFACE_CUBEMAP; - numFaces = 6; + tex->key.flags |= SVGA3D_SURFACE_CUBEMAP; + tex->key.numFaces = 6; } else { - numFaces = 1; + tex->key.numFaces = 1; } if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) - flags |= SVGA3D_SURFACE_HINT_TEXTURE; + tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) - flags |= SVGA3D_SURFACE_HINT_SCANOUT; + tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; /* * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot @@ -328,21 +320,24 @@ svga_texture_create(struct pipe_screen *screen, #if 0 if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) && !pf_is_compressed(templat->format)) - flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; + tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET; #endif if(templat->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) - flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; + tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL; - numMipLevels = templat->last_level + 1; + tex->key.numMipLevels = templat->last_level + 1; - format = svga_translate_format(templat->format); - if(format == SVGA3D_FORMAT_INVALID) + tex->key.format = svga_translate_format(templat->format); + if(tex->key.format == SVGA3D_FORMAT_INVALID) goto error2; + + tex->key.cachable = 1; - tex->handle = sws->surface_create(sws, flags, format, size, numFaces, numMipLevels); + SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle); + tex->handle = svga_screen_surface_create(svgascreen, &tex->key); if (tex->handle) - SVGA_DBG(DEBUG_DMA, "create sid %p (texture)\n", tex->handle); + SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle); return &tex->base; @@ -367,7 +362,7 @@ svga_texture_blanket(struct pipe_screen * screen, /* Only supports one type */ if (base->target != PIPE_TEXTURE_2D || base->last_level != 0 || - base->depth[0] != 1) { + base->depth0 != 1) { return NULL; } @@ -398,6 +393,7 @@ svga_texture_blanket(struct pipe_screen * screen, return NULL; tex->base = *base; + if (sbuf->key.format == 1) tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM; @@ -407,6 +403,12 @@ svga_texture_blanket(struct pipe_screen * screen, pipe_reference_init(&tex->base.reference, 1); tex->base.screen = screen; + SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle); + + /* We don't own this storage, so don't try to cache it. + */ + assert(sbuf->key.cachable == 0); + tex->key.cachable = 0; sws->surface_reference(sws, &tex->handle, sbuf->handle); return &tex->base; @@ -427,7 +429,7 @@ svga_texture_destroy(struct pipe_texture *pt) DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); */ SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle); - ss->sws->surface_reference(ss->sws, &tex->handle, NULL); + svga_screen_surface_destroy(ss, &tex->key, &tex->handle); FREE(tex); } @@ -518,43 +520,47 @@ svga_texture_view_surface(struct pipe_context *pipe, unsigned start_mip, unsigned num_mip, int face_pick, - int zslice_pick) + int zslice_pick, + struct svga_host_surface_cache_key *key) /* OUT */ { struct svga_screen *ss = svga_screen(tex->base.screen); - struct svga_winsys_screen *sws = ss->sws; struct svga_winsys_surface *handle; int i, j; - SVGA3dSurfaceFlags flags = 0; - SVGA3dSize size; - uint32 numFaces; - uint32 numMipLevels = num_mip; unsigned z_offset = 0; SVGA_DBG(DEBUG_PERF, "svga: Create surface view: face %d zslice %d mips %d..%d\n", face_pick, zslice_pick, start_mip, start_mip+num_mip-1); - size.width = tex->base.width[start_mip]; - size.height = tex->base.height[start_mip]; - size.depth = zslice_pick < 0 ? tex->base.depth[start_mip] : 1; - assert(size.depth == 1); + key->flags = 0; + key->format = format; + key->numMipLevels = num_mip; + key->size.width = u_minify(tex->base.width0, start_mip); + key->size.height = u_minify(tex->base.height0, start_mip); + key->size.depth = zslice_pick < 0 ? u_minify(tex->base.depth0, start_mip) : 1; + key->cachable = 1; + assert(key->size.depth == 1); if(tex->base.target == PIPE_TEXTURE_CUBE && face_pick < 0) { - flags |= SVGA3D_SURFACE_CUBEMAP; - numFaces = 6; + key->flags |= SVGA3D_SURFACE_CUBEMAP; + key->numFaces = 6; } else { - numFaces = 1; + key->numFaces = 1; } - if(format == SVGA3D_FORMAT_INVALID) + if(key->format == SVGA3D_FORMAT_INVALID) { + key->cachable = 0; return NULL; + } - handle = sws->surface_create(sws, flags, format, size, numFaces, numMipLevels); - - if (!handle) + SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); + handle = svga_screen_surface_create(ss, key); + if (!handle) { + key->cachable = 0; return NULL; + } - SVGA_DBG(DEBUG_DMA, "create sid %p (texture view)\n", handle); + SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle); if (face_pick < 0) face_pick = 0; @@ -562,14 +568,23 @@ svga_texture_view_surface(struct pipe_context *pipe, if (zslice_pick >= 0) z_offset = zslice_pick; - for (i = 0; i < num_mip; i++) { - for (j = 0; j < numFaces; j++) { + for (i = 0; i < key->numMipLevels; i++) { + for (j = 0; j < key->numFaces; j++) { if(tex->defined[j + face_pick][i + start_mip]) { - unsigned depth = zslice_pick < 0 ? tex->base.depth[i + start_mip] : 1; - svga_texture_copy_handle(svga_context(pipe), ss, - tex->handle, 0, 0, z_offset, i + start_mip, j + face_pick, + unsigned depth = (zslice_pick < 0 ? + u_minify(tex->base.depth0, i + start_mip) : + 1); + + svga_texture_copy_handle(svga_context(pipe), + ss, + tex->handle, + 0, 0, z_offset, + i + start_mip, + j + face_pick, handle, 0, 0, 0, i, j, - tex->base.width[i + start_mip], tex->base.height[i + start_mip], depth); + u_minify(tex->base.width0, i + start_mip), + u_minify(tex->base.height0, i + start_mip), + depth); } } } @@ -586,25 +601,23 @@ svga_get_tex_surface(struct pipe_screen *screen, { struct svga_texture *tex = svga_texture(pt); struct svga_surface *s; - struct pipe_surface *ps; boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE; boolean view = FALSE; SVGA3dSurfaceFormat format; s = CALLOC_STRUCT(svga_surface); - ps = &s->base; - if (!ps) + if (!s) return NULL; - pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); - ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->usage = flags; - ps->level = level; - ps->face = face; - ps->zslice = zslice; + pipe_reference_init(&s->base.reference, 1); + pipe_texture_reference(&s->base.texture, pt); + s->base.format = pt->format; + s->base.width = u_minify(pt->width0, level); + s->base.height = u_minify(pt->height0, level); + s->base.usage = flags; + s->base.level = level; + s->base.face = face; + s->base.zslice = zslice; if (!render) format = svga_translate_format(pt->format); @@ -619,11 +632,13 @@ svga_get_tex_surface(struct pipe_screen *screen, view = TRUE; /* Currently only used for compressed textures */ - if (render && (format != svga_translate_format(pt->format))) { + if (render && + format != svga_translate_format(pt->format)) { view = TRUE; } - if (level != 0 && svga_screen(screen)->debug.force_level_surface_view) + if (level != 0 && + svga_screen(screen)->debug.force_level_surface_view) view = TRUE; if (pt->target == PIPE_TEXTURE_3D) @@ -634,9 +649,10 @@ svga_get_tex_surface(struct pipe_screen *screen, if (view) { SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n", - pt, level, face, zslice, ps); + pt, level, face, zslice, s); - s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice); + s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice, + &s->key); s->real_face = 0; s->real_level = 0; s->real_zslice = 0; @@ -644,15 +660,16 @@ svga_get_tex_surface(struct pipe_screen *screen, struct svga_winsys_screen *sws = svga_winsys_screen(screen); SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n", - pt, level, face, zslice, ps); + pt, level, face, zslice, s); + memset(&s->key, 0, sizeof s->key); sws->surface_reference(sws, &s->handle, tex->handle); s->real_face = face; s->real_level = level; s->real_zslice = zslice; } - return ps; + return &s->base; } @@ -663,7 +680,8 @@ svga_tex_surface_destroy(struct pipe_surface *surf) struct svga_screen *ss = svga_screen(surf->texture->screen); SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle); - ss->sws->surface_reference(ss->sws, &s->handle, NULL); + assert(s->key.cachable == 0); + svga_screen_surface_destroy(ss, &s->key, &s->handle); pipe_texture_reference(&surf->texture, NULL); FREE(surf); } @@ -723,7 +741,8 @@ svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf) svga_texture_copy_handle(svga_context(pipe), ss, s->handle, 0, 0, 0, s->real_level, s->real_face, tex->handle, 0, 0, surf->zslice, surf->level, surf->face, - tex->base.width[surf->level], tex->base.height[surf->level], 1); + u_minify(tex->base.width0, surf->level), + u_minify(tex->base.height0, surf->level), 1); tex->defined[surf->face][surf->level] = TRUE; } } @@ -953,10 +972,11 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt, "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", pt, min_lod, max_lod, max_lod - min_lod + 1, - pt->width[0], - pt->height[0], - pt->depth[0], + pt->width0, + pt->height0, + pt->depth0, pt->last_level); + sv->key.cachable = 0; sws->surface_reference(sws, &sv->handle, tex->handle); return sv; } @@ -965,19 +985,21 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt, "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", pt, min_lod, max_lod, max_lod - min_lod + 1, - pt->width[0], - pt->height[0], - pt->depth[0], + pt->width0, + pt->height0, + pt->depth0, pt->last_level); sv->age = tex->age; sv->handle = svga_texture_view_surface(pipe, tex, format, min_lod, max_lod - min_lod + 1, - -1, -1); + -1, -1, + &sv->key); if (!sv->handle) { assert(0); + sv->key.cachable = 0; sws->surface_reference(sws, &sv->handle, tex->handle); return sv; } @@ -1015,9 +1037,9 @@ svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view * svga_texture_copy_handle(svga, NULL, tex->handle, 0, 0, 0, i, k, v->handle, 0, 0, 0, i - v->min_lod, k, - tex->base.width[i], - tex->base.height[i], - tex->base.depth[i]); + u_minify(tex->base.width0, i), + u_minify(tex->base.height0, i), + u_minify(tex->base.depth0, i)); } } @@ -1030,7 +1052,7 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v) struct svga_screen *ss = svga_screen(v->texture->base.screen); SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle); - ss->sws->surface_reference(ss->sws, &v->handle, NULL); + svga_screen_surface_destroy(ss, &v->key, &v->handle); FREE(v); } @@ -1047,7 +1069,7 @@ svga_screen_buffer_from_texture(struct pipe_texture *texture, svga_translate_format(texture->format), stex->handle); - *stride = pf_get_nblocksx(&texture->block, texture->width[0]) * + *stride = pf_get_nblocksx(&texture->block, texture->width0) * texture->block.size; return *buffer != NULL; @@ -1060,6 +1082,8 @@ svga_screen_texture_get_winsys_surface(struct pipe_texture *texture) struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen); struct svga_winsys_surface *vsurf = NULL; + assert(svga_texture(texture)->key.cachable == 0); + svga_texture(texture)->key.cachable = 0; sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle); return vsurf; } diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h index 1e6fef59a39..1cc4063e653 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.h +++ b/src/gallium/drivers/svga/svga_screen_texture.h @@ -29,7 +29,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" - +#include "svga_screen_cache.h" struct pipe_context; struct pipe_screen; @@ -68,6 +68,7 @@ struct svga_sampler_view unsigned age; + struct svga_host_surface_cache_key key; struct svga_winsys_surface *handle; }; @@ -76,8 +77,6 @@ struct svga_texture { struct pipe_texture base; - struct svga_winsys_surface *handle; - boolean defined[6][PIPE_MAX_TEXTURE_LEVELS]; struct svga_sampler_view *cached_view; @@ -86,6 +85,16 @@ struct svga_texture unsigned age; boolean views_modified; + + /** + * Creation key for the host surface handle. + * + * This structure describes all the host surface characteristics so that it + * can be looked up in cache, since creating a host surface is often a slow + * operation. + */ + struct svga_host_surface_cache_key key; + struct svga_winsys_surface *handle; }; @@ -93,6 +102,7 @@ struct svga_surface { struct pipe_surface base; + struct svga_host_surface_cache_key key; struct svga_winsys_surface *handle; unsigned real_face; diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c index 18cce7dde1a..209ed282450 100644 --- a/src/gallium/drivers/svga/svga_state_constants.c +++ b/src/gallium/drivers/svga/svga_state_constants.c @@ -140,8 +140,8 @@ static int emit_fs_consts( struct svga_context *svga, struct pipe_texture *tex = svga->curr.texture[i]; float data[4]; - data[0] = 1.0 / (float)tex->width[0]; - data[1] = 1.0 / (float)tex->height[0]; + data[0] = 1.0 / (float)tex->width0; + data[1] = 1.0 / (float)tex->height0; data[2] = 1.0; data[3] = 1.0; diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index 7d7f93d8e3c..cfdcae4ee4a 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -54,6 +54,9 @@ static int emit_framebuffer( struct svga_context *svga, for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) { if (curr->cbufs[i] != hw->cbufs[i]) { + if (svga->curr.nr_fbs++ > 8) + return PIPE_ERROR_OUT_OF_MEMORY; + ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]); if (ret != PIPE_OK) return ret; diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c index 44d0930bc0a..b8ef137c015 100644 --- a/src/gallium/drivers/svga/svga_tgsi.c +++ b/src/gallium/drivers/svga/svga_tgsi.c @@ -32,7 +32,7 @@ #include "tgsi/tgsi_scan.h" #include "util/u_memory.h" -#include "svgadump/st_shader_dump.h" +#include "svgadump/svga_shader_dump.h" #include "svga_context.h" #include "svga_tgsi.h" @@ -222,6 +222,20 @@ svga_tgsi_translate( const struct svga_shader *shader, result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned); memcpy(&result->key, &key, sizeof key); + if (SVGA_DEBUG & DEBUG_TGSI) + { + debug_printf( "#####################################\n" ); + debug_printf( "Shader %u below\n", shader->id ); + tgsi_dump( shader->tokens, 0 ); + if (SVGA_DEBUG & DEBUG_TGSI) { + debug_printf( "Shader %u compiled below\n", shader->id ); + svga_shader_dump( result->tokens, + result->nr_tokens , + FALSE ); + } + debug_printf( "#####################################\n" ); + } + return result; fail: diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.c b/src/gallium/drivers/svga/svgadump/svga_dump.c index 180dde8dc13..910afa25287 100644 --- a/src/gallium/drivers/svga/svgadump/svga_dump.c +++ b/src/gallium/drivers/svga/svgadump/svga_dump.c @@ -31,7 +31,7 @@ */ #include "svga_types.h" -#include "st_shader_dump.h" +#include "svga_shader_dump.h" #include "svga3d_reg.h" #include "util/u_debug.h" @@ -1627,7 +1627,7 @@ svga_dump_commands(const void *commands, uint32_t size) const SVGA3dCmdDefineShader *cmd = (const SVGA3dCmdDefineShader *)body; dump_SVGA3dCmdDefineShader(cmd); body = (const uint8_t *)&cmd[1]; - sh_svga_dump((const uint32_t *)body, + svga_shader_dump((const uint32_t *)body, (unsigned)(next - body)/sizeof(uint32_t), FALSE ); body = next; diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.py b/src/gallium/drivers/svga/svgadump/svga_dump.py index 3cb29c395b6..288e753296e 100755 --- a/src/gallium/drivers/svga/svgadump/svga_dump.py +++ b/src/gallium/drivers/svga/svgadump/svga_dump.py @@ -291,7 +291,7 @@ def main(): print ' */' print print '#include "svga_types.h"' - print '#include "shader_dump/st_shader_dump.h"' + print '#include "svga_shader_dump.h"' print '#include "svga3d_reg.h"' print print '#include "pipe/p_debug.h"' diff --git a/src/gallium/drivers/svga/svgadump/st_shader.h b/src/gallium/drivers/svga/svgadump/svga_shader.h index 2fc1796a904..9217af2dd99 100644 --- a/src/gallium/drivers/svga/svgadump/st_shader.h +++ b/src/gallium/drivers/svga/svgadump/svga_shader.h @@ -211,4 +211,10 @@ struct sh_trinaryop struct sh_srcreg src2; }; +struct sh_comment +{ + unsigned opcode:16; + unsigned size:16; +}; + #endif /* ST_SHADER_SVGA_H */ diff --git a/src/gallium/drivers/svga/svgadump/st_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c index d65cc93bfd2..b0e7fdf378a 100644 --- a/src/gallium/drivers/svga/svgadump/st_shader_dump.c +++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c @@ -30,9 +30,9 @@ * @author Michal Krol <[email protected]> */ -#include "st_shader.h" -#include "st_shader_dump.h" -#include "st_shader_op.h" +#include "svga_shader.h" +#include "svga_shader_dump.h" +#include "svga_shader_op.h" #include "util/u_debug.h" #include "../svga_hw_reg.h" @@ -435,7 +435,7 @@ static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, cons } void -sh_svga_dump( +svga_shader_dump( const unsigned *assem, unsigned dwords, unsigned do_binary ) @@ -587,7 +587,12 @@ sh_svga_dump( break; case SVGA3DOP_COMMENT: - assert( 0 ); + { + struct sh_comment comment = *(struct sh_comment *)assem; + + /* Ignore comment contents. */ + assem += sizeof(struct sh_comment) / sizeof(unsigned) + comment.size; + } break; case SVGA3DOP_RET: @@ -602,7 +607,7 @@ sh_svga_dump( default: { - const struct sh_opcode_info *info = sh_svga_opcode_info( op.opcode ); + const struct sh_opcode_info *info = svga_opcode_info( op.opcode ); uint i; uint num_src = info->num_src + op.predicated; boolean not_first_arg = FALSE; diff --git a/src/gallium/drivers/svga/svgadump/st_shader_dump.h b/src/gallium/drivers/svga/svgadump/svga_shader_dump.h index af5549cdba2..a2657acb2f1 100644 --- a/src/gallium/drivers/svga/svgadump/st_shader_dump.h +++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.h @@ -30,13 +30,13 @@ * @author Michal Krol <[email protected]> */ -#ifndef ST_SHADER_SVGA_DUMP_H -#define ST_SHADER_SVGA_DUMP_H +#ifndef SVGA_SHADER_DUMP_H +#define SVGA_SHADER_DUMP_H void -sh_svga_dump( +svga_shader_dump( const unsigned *assem, unsigned dwords, unsigned do_binary ); -#endif /* ST_SHADER_SVGA_DUMP_H */ +#endif /* SVGA_SHADER_DUMP_H */ diff --git a/src/gallium/drivers/svga/svgadump/st_shader_op.c b/src/gallium/drivers/svga/svgadump/svga_shader_op.c index 2c05382ab92..8343bfdaab4 100644 --- a/src/gallium/drivers/svga/svgadump/st_shader_op.c +++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.c @@ -31,7 +31,7 @@ */ #include "util/u_debug.h" -#include "st_shader_op.h" +#include "svga_shader_op.h" #include "../svga_hw_reg.h" #include "svga3d_shaderdefs.h" @@ -140,7 +140,7 @@ static struct sh_opcode_info opcode_info[] = { "breakp", 1, 1, SVGA3DOP_INVALID, }, }; -const struct sh_opcode_info *sh_svga_opcode_info( uint op ) +const struct sh_opcode_info *svga_opcode_info( uint op ) { struct sh_opcode_info *info; diff --git a/src/gallium/drivers/svga/svgadump/st_shader_op.h b/src/gallium/drivers/svga/svgadump/svga_shader_op.h index 01d39dca847..e558de02c53 100644 --- a/src/gallium/drivers/svga/svgadump/st_shader_op.h +++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.h @@ -30,8 +30,8 @@ * @author Michal Krol <[email protected]> */ -#ifndef ST_SHADER_SVGA_OP_H -#define ST_SHADER_SVGA_OP_H +#ifndef SVGA_SHADER_OP_H +#define SVGA_SHADER_OP_H struct sh_opcode_info { @@ -41,6 +41,6 @@ struct sh_opcode_info unsigned svga_opcode:16; }; -const struct sh_opcode_info *sh_svga_opcode_info( unsigned op ); +const struct sh_opcode_info *svga_opcode_info( unsigned op ); -#endif /* ST_SHADER_SVGA_OP_H */ +#endif /* SVGA_SHADER_OP_H */ diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index bf470b46ae1..2f0f063d2de 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -107,7 +107,7 @@ trace_context_set_edgeflags(struct pipe_context *_pipe, /* FIXME: we don't know how big this array is */ trace_dump_arg(ptr, bitfield); - pipe->set_edgeflags(pipe, bitfield);; + pipe->set_edgeflags(pipe, bitfield); trace_dump_call_end(); } @@ -143,10 +143,16 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag) for (k = 0; k < tr_ctx->curr.nr_cbufs; k++) if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k]) block = TRUE; - if (tr_ctx->draw_rule.tex) + if (tr_ctx->draw_rule.tex) { for (k = 0; k < tr_ctx->curr.num_texs; k++) if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k]) block = TRUE; + for (k = 0; k < tr_ctx->curr.num_vert_texs; k++) { + if (tr_ctx->draw_rule.tex == tr_ctx->curr.vert_tex[k]) { + block = TRUE; + } + } + } if (block) tr_ctx->draw_blocked |= (flag | 4); @@ -192,7 +198,7 @@ trace_context_draw_arrays(struct pipe_context *_pipe, trace_dump_arg(uint, start); trace_dump_arg(uint, count); - result = pipe->draw_arrays(pipe, mode, start, count);; + result = pipe->draw_arrays(pipe, mode, start, count); trace_dump_ret(bool, result); @@ -232,7 +238,7 @@ trace_context_draw_elements(struct pipe_context *_pipe, trace_dump_arg(uint, start); trace_dump_arg(uint, count); - result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);; + result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count); trace_dump_ret(bool, result); @@ -306,7 +312,7 @@ trace_context_create_query(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(uint, query_type); - result = pipe->create_query(pipe, query_type);; + result = pipe->create_query(pipe, query_type); trace_dump_ret(ptr, result); @@ -328,7 +334,7 @@ trace_context_destroy_query(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, query); - pipe->destroy_query(pipe, query);; + pipe->destroy_query(pipe, query); trace_dump_call_end(); } @@ -346,7 +352,7 @@ trace_context_begin_query(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, query); - pipe->begin_query(pipe, query);; + pipe->begin_query(pipe, query); trace_dump_call_end(); } @@ -385,7 +391,7 @@ trace_context_get_query_result(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); - _result = pipe->get_query_result(pipe, query, wait, presult);; + _result = pipe->get_query_result(pipe, query, wait, presult); result = *presult; trace_dump_arg(uint, result); @@ -410,7 +416,7 @@ trace_context_create_blend_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(blend_state, state); - result = pipe->create_blend_state(pipe, state);; + result = pipe->create_blend_state(pipe, state); trace_dump_ret(ptr, result); @@ -432,7 +438,7 @@ trace_context_bind_blend_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->bind_blend_state(pipe, state);; + pipe->bind_blend_state(pipe, state); trace_dump_call_end(); } @@ -450,7 +456,7 @@ trace_context_delete_blend_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->delete_blend_state(pipe, state);; + pipe->delete_blend_state(pipe, state); trace_dump_call_end(); } @@ -469,7 +475,7 @@ trace_context_create_sampler_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(sampler_state, state); - result = pipe->create_sampler_state(pipe, state);; + result = pipe->create_sampler_state(pipe, state); trace_dump_ret(ptr, result); @@ -480,19 +486,40 @@ trace_context_create_sampler_state(struct pipe_context *_pipe, static INLINE void -trace_context_bind_sampler_states(struct pipe_context *_pipe, - unsigned num_states, void **states) +trace_context_bind_fragment_sampler_states(struct pipe_context *_pipe, + unsigned num_states, + void **states) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "bind_fragment_sampler_states"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_states); + trace_dump_arg_array(ptr, states, num_states); + + pipe->bind_fragment_sampler_states(pipe, num_states, states); + + trace_dump_call_end(); +} + + +static INLINE void +trace_context_bind_vertex_sampler_states(struct pipe_context *_pipe, + unsigned num_states, + void **states) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin("pipe_context", "bind_sampler_states"); + trace_dump_call_begin("pipe_context", "bind_vertex_sampler_states"); trace_dump_arg(ptr, pipe); trace_dump_arg(uint, num_states); trace_dump_arg_array(ptr, states, num_states); - pipe->bind_sampler_states(pipe, num_states, states);; + pipe->bind_vertex_sampler_states(pipe, num_states, states); trace_dump_call_end(); } @@ -510,7 +537,7 @@ trace_context_delete_sampler_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->delete_sampler_state(pipe, state);; + pipe->delete_sampler_state(pipe, state); trace_dump_call_end(); } @@ -529,7 +556,7 @@ trace_context_create_rasterizer_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(rasterizer_state, state); - result = pipe->create_rasterizer_state(pipe, state);; + result = pipe->create_rasterizer_state(pipe, state); trace_dump_ret(ptr, result); @@ -551,7 +578,7 @@ trace_context_bind_rasterizer_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->bind_rasterizer_state(pipe, state);; + pipe->bind_rasterizer_state(pipe, state); trace_dump_call_end(); } @@ -569,7 +596,7 @@ trace_context_delete_rasterizer_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->delete_rasterizer_state(pipe, state);; + pipe->delete_rasterizer_state(pipe, state); trace_dump_call_end(); } @@ -585,7 +612,7 @@ trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state"); - result = pipe->create_depth_stencil_alpha_state(pipe, state);; + result = pipe->create_depth_stencil_alpha_state(pipe, state); trace_dump_arg(ptr, pipe); trace_dump_arg(depth_stencil_alpha_state, state); @@ -610,7 +637,7 @@ trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->bind_depth_stencil_alpha_state(pipe, state);; + pipe->bind_depth_stencil_alpha_state(pipe, state); trace_dump_call_end(); } @@ -628,7 +655,7 @@ trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->delete_depth_stencil_alpha_state(pipe, state);; + pipe->delete_depth_stencil_alpha_state(pipe, state); trace_dump_call_end(); } @@ -647,7 +674,7 @@ trace_context_create_fs_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(shader_state, state); - result = pipe->create_fs_state(pipe, state);; + result = pipe->create_fs_state(pipe, state); trace_dump_ret(ptr, result); @@ -750,7 +777,7 @@ trace_context_bind_vs_state(struct pipe_context *_pipe, if (tr_shdr && tr_shdr->replaced) state = tr_shdr->replaced; - pipe->bind_vs_state(pipe, state);; + pipe->bind_vs_state(pipe, state); trace_dump_call_end(); } @@ -770,7 +797,7 @@ trace_context_delete_vs_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); - pipe->delete_vs_state(pipe, state);; + pipe->delete_vs_state(pipe, state); trace_dump_call_end(); @@ -790,7 +817,7 @@ trace_context_set_blend_color(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(blend_color, state); - pipe->set_blend_color(pipe, state);; + pipe->set_blend_color(pipe, state); trace_dump_call_end(); } @@ -808,7 +835,7 @@ trace_context_set_clip_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(clip_state, state); - pipe->set_clip_state(pipe, state);; + pipe->set_clip_state(pipe, state); trace_dump_call_end(); } @@ -880,7 +907,7 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(framebuffer_state, state); - pipe->set_framebuffer_state(pipe, state);; + pipe->set_framebuffer_state(pipe, state); trace_dump_call_end(); } @@ -898,7 +925,7 @@ trace_context_set_polygon_stipple(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(poly_stipple, state); - pipe->set_polygon_stipple(pipe, state);; + pipe->set_polygon_stipple(pipe, state); trace_dump_call_end(); } @@ -916,7 +943,7 @@ trace_context_set_scissor_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(scissor_state, state); - pipe->set_scissor_state(pipe, state);; + pipe->set_scissor_state(pipe, state); trace_dump_call_end(); } @@ -934,16 +961,16 @@ trace_context_set_viewport_state(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(viewport_state, state); - pipe->set_viewport_state(pipe, state);; + pipe->set_viewport_state(pipe, state); trace_dump_call_end(); } static INLINE void -trace_context_set_sampler_textures(struct pipe_context *_pipe, - unsigned num_textures, - struct pipe_texture **textures) +trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **textures) { struct trace_context *tr_ctx = trace_context(_pipe); struct trace_texture *tr_tex; @@ -959,13 +986,44 @@ trace_context_set_sampler_textures(struct pipe_context *_pipe, } textures = unwrapped_textures; - trace_dump_call_begin("pipe_context", "set_sampler_textures"); + trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_textures); + trace_dump_arg_array(ptr, textures, num_textures); + + pipe->set_fragment_sampler_textures(pipe, num_textures, textures); + + trace_dump_call_end(); +} + + +static INLINE void +trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **textures) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_texture *tr_tex; + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned i; + + tr_ctx->curr.num_vert_texs = num_textures; + for(i = 0; i < num_textures; ++i) { + tr_tex = trace_texture(textures[i]); + tr_ctx->curr.vert_tex[i] = tr_tex; + unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL; + } + textures = unwrapped_textures; + + trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures"); trace_dump_arg(ptr, pipe); trace_dump_arg(uint, num_textures); trace_dump_arg_array(ptr, textures, num_textures); - pipe->set_sampler_textures(pipe, num_textures, textures);; + pipe->set_vertex_sampler_textures(pipe, num_textures, textures); trace_dump_call_end(); } @@ -1024,7 +1082,7 @@ trace_context_set_vertex_elements(struct pipe_context *_pipe, trace_dump_struct_array(vertex_element, elements, num_elements); trace_dump_arg_end(); - pipe->set_vertex_elements(pipe, num_elements, elements);; + pipe->set_vertex_elements(pipe, num_elements, elements); trace_dump_call_end(); } @@ -1085,7 +1143,7 @@ trace_context_surface_fill(struct pipe_context *_pipe, trace_dump_arg(uint, width); trace_dump_arg(uint, height); - pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);; + pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value); trace_dump_call_end(); } @@ -1128,7 +1186,7 @@ trace_context_flush(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(uint, flags); - pipe->flush(pipe, flags, fence);; + pipe->flush(pipe, flags, fence); if(fence) trace_dump_ret(ptr, *fence); @@ -1253,7 +1311,8 @@ trace_context_create(struct pipe_screen *_screen, tr_ctx->base.bind_blend_state = trace_context_bind_blend_state; tr_ctx->base.delete_blend_state = trace_context_delete_blend_state; tr_ctx->base.create_sampler_state = trace_context_create_sampler_state; - tr_ctx->base.bind_sampler_states = trace_context_bind_sampler_states; + tr_ctx->base.bind_fragment_sampler_states = trace_context_bind_fragment_sampler_states; + tr_ctx->base.bind_vertex_sampler_states = trace_context_bind_vertex_sampler_states; tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state; tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state; tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state; @@ -1274,7 +1333,8 @@ trace_context_create(struct pipe_screen *_screen, tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple; tr_ctx->base.set_scissor_state = trace_context_set_scissor_state; tr_ctx->base.set_viewport_state = trace_context_set_viewport_state; - tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures; + tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures; + tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures; tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements; if (pipe->surface_copy) diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 6febe4b4114..852b480765a 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -54,6 +54,9 @@ struct trace_context struct trace_texture *tex[PIPE_MAX_SAMPLERS]; unsigned num_texs; + struct trace_texture *vert_tex[PIPE_MAX_VERTEX_SAMPLERS]; + unsigned num_vert_texs; + unsigned nr_cbufs; struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS]; struct trace_texture *zsbuf; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index bcf6751af4f..6d582092941 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -83,15 +83,15 @@ void trace_dump_template(const struct pipe_texture *templat) trace_dump_member(format, templat, format); trace_dump_member_begin("width"); - trace_dump_array(uint, templat->width, 1); + trace_dump_uint(templat->width0); trace_dump_member_end(); trace_dump_member_begin("height"); - trace_dump_array(uint, templat->height, 1); + trace_dump_uint(templat->height0); trace_dump_member_end(); trace_dump_member_begin("depth"); - trace_dump_array(uint, templat->depth, 1); + trace_dump_uint(templat->depth0); trace_dump_member_end(); trace_dump_member_begin("block"); diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index 81e0a6f3b00..b59458c0e37 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -200,9 +200,9 @@ trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, t = tr_tex->texture; rbug_send_texture_info_reply(tr_rbug->con, serial, t->target, t->format, - t->width, t->last_level + 1, - t->height, t->last_level + 1, - t->depth, t->last_level + 1, + &t->width0, 1, + &t->height0, 1, + &t->depth0, 1, t->block.width, t->block.height, t->block.size, t->last_level, t->nr_samples, diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 5569001e601..f896001eb12 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -123,7 +123,12 @@ struct pipe_context { void * (*create_sampler_state)(struct pipe_context *, const struct pipe_sampler_state *); - void (*bind_sampler_states)(struct pipe_context *, unsigned num, void **); + void (*bind_fragment_sampler_states)(struct pipe_context *, + unsigned num_samplers, + void **samplers); + void (*bind_vertex_sampler_states)(struct pipe_context *, + unsigned num_samplers, + void **samplers); void (*delete_sampler_state)(struct pipe_context *, void *); void * (*create_rasterizer_state)(struct pipe_context *, @@ -173,9 +178,13 @@ struct pipe_context { void (*set_viewport_state)( struct pipe_context *, const struct pipe_viewport_state * ); - void (*set_sampler_textures)( struct pipe_context *, - unsigned num_textures, - struct pipe_texture ** ); + void (*set_fragment_sampler_textures)(struct pipe_context *, + unsigned num_textures, + struct pipe_texture **); + + void (*set_vertex_sampler_textures)(struct pipe_context *, + unsigned num_textures, + struct pipe_texture **); void (*set_vertex_buffers)( struct pipe_context *, unsigned num_buffers, diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index fd14dc8e92d..69a0970d5f8 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -390,6 +390,8 @@ enum pipe_transfer_usage { #define PIPE_CAP_BLEND_EQUATION_SEPARATE 28 #define PIPE_CAP_SM3 29 /*< Shader Model 3 supported */ #define PIPE_CAP_MAX_PREDICATE_REGISTERS 30 +#define PIPE_CAP_MAX_COMBINED_SAMPLERS 31 /*< Maximum texture image units accessible from vertex + and fragment shaders combined */ /** diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 287b424e4ac..6de7af6a81c 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -60,6 +60,7 @@ extern "C" { #define PIPE_MAX_COLOR_BUFS 8 #define PIPE_MAX_CONSTANT 32 #define PIPE_MAX_SAMPLERS 16 +#define PIPE_MAX_VERTEX_SAMPLERS 16 #define PIPE_MAX_SHADER_INPUTS 16 #define PIPE_MAX_SHADER_OUTPUTS 16 #define PIPE_MAX_TEXTURE_LEVELS 16 @@ -343,9 +344,9 @@ struct pipe_texture enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ enum pipe_format format; /**< PIPE_FORMAT_x */ - unsigned width[PIPE_MAX_TEXTURE_LEVELS]; - unsigned height[PIPE_MAX_TEXTURE_LEVELS]; - unsigned depth[PIPE_MAX_TEXTURE_LEVELS]; + unsigned width0; + unsigned height0; + unsigned depth0; struct pipe_format_block block; unsigned nblocksx[PIPE_MAX_TEXTURE_LEVELS]; /**< allocated width in blocks */ diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 5625ff53cfd..45a6059ea83 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -46,7 +46,7 @@ #include "util/u_memory.h" #include "util/u_rect.h" - + static struct pipe_surface * dri_surface_from_handle(struct drm_api *api, struct pipe_screen *screen, @@ -62,10 +62,10 @@ dri_surface_from_handle(struct drm_api *api, templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; - templat.depth[0] = 1; + templat.depth0 = 1; templat.format = format; - templat.width[0] = width; - templat.height[0] = height; + templat.width0 = width; + templat.height0 = height; pf_get_block(templat.format, &templat.block); texture = api->texture_from_shared_handle(api, screen, &templat, diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c index 91615abebee..ddd9b04cd48 100644 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ b/src/gallium/state_trackers/egl/egl_surface.c @@ -114,10 +114,10 @@ drm_create_texture(_EGLDisplay *dpy, templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; - templat.depth[0] = 1; + templat.depth0 = 1; templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.width[0] = w; - templat.height[0] = h; + templat.width0 = w; + templat.height0 = h; pf_get_block(templat.format, &templat.block); texture = screen->texture_create(dev->screen, diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index a40aa1e5187..9728207d9c7 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -147,9 +147,9 @@ struct st_context { if(!texture) texture = $self->default_texture; pipe_texture_reference(&$self->sampler_textures[index], texture); - $self->pipe->set_sampler_textures($self->pipe, - PIPE_MAX_SAMPLERS, - $self->sampler_textures); + $self->pipe->set_fragment_sampler_textures($self->pipe, + PIPE_MAX_SAMPLERS, + $self->sampler_textures); } void set_vertex_buffer(unsigned index, diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i index f16fe5b0ff7..a83bcc71a1a 100644 --- a/src/gallium/state_trackers/python/p_device.i +++ b/src/gallium/state_trackers/python/p_device.i @@ -113,9 +113,9 @@ struct st_device { memset(&templat, 0, sizeof(templat)); templat.format = format; pf_get_block(templat.format, &templat.block); - templat.width[0] = width; - templat.height[0] = height; - templat.depth[0] = depth; + templat.width0 = width; + templat.height0 = height; + templat.depth0 = depth; templat.last_level = last_level; templat.target = target; templat.tex_usage = tex_usage; diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index 1d513abf3c7..5416b872f53 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -59,15 +59,15 @@ } unsigned get_width(unsigned level=0) { - return $self->width[level]; + return u_minify($self->width0, level); } unsigned get_height(unsigned level=0) { - return $self->height[level]; + return u_minify($self->height0, level); } unsigned get_depth(unsigned level=0) { - return $self->depth[level]; + return u_minify($self->depth0, level); } unsigned get_nblocksx(unsigned level=0) { @@ -88,7 +88,7 @@ SWIG_exception(SWIG_ValueError, "face out of bounds"); if(level > $self->last_level) SWIG_exception(SWIG_ValueError, "level out of bounds"); - if(zslice >= $self->depth[level]) + if(zslice >= u_minify($self->depth0, level)) SWIG_exception(SWIG_ValueError, "zslice out of bounds"); surface = CALLOC_STRUCT(st_surface); @@ -375,13 +375,13 @@ struct st_surface static unsigned st_surface_width_get(struct st_surface *surface) { - return surface->texture->width[surface->level]; + return u_minify(surface->texture->width0, surface->level); } static unsigned st_surface_height_get(struct st_surface *surface) { - return surface->texture->height[surface->level]; + return u_minify(surface->texture->height0, surface->level); } static unsigned diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 348f2e43683..5f826b1c4c4 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -279,9 +279,9 @@ class Screen(Object): def texture_create(self, templat): return self.real.texture_create( format = templat.format, - width = templat.width[0], - height = templat.height[0], - depth = templat.depth[0], + width = templat.width0, + height = templat.height0, + depth = templat.depth0, last_level = templat.last_level, target = templat.target, tex_usage = templat.tex_usage, @@ -388,7 +388,7 @@ class Context(Object): def delete_sampler_state(self, state): pass - def bind_sampler_states(self, num_states, states): + def bind_fragment_sampler_states(self, num_states, states): for i in range(num_states): self.real.set_sampler(i, states[i]) @@ -486,7 +486,7 @@ class Context(Object): def set_viewport_state(self, state): self.real.set_viewport(state) - def set_sampler_textures(self, num_textures, textures): + def set_fragment_sampler_textures(self, num_textures, textures): for i in range(num_textures): self.real.set_sampler_texture(i, textures[i]) diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index ea7d18738f6..a791113abac 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -252,9 +252,9 @@ st_context_create(struct st_device *st_dev) templat.block.size = 4; templat.block.width = 1; templat.block.height = 1; - templat.width[0] = 1; - templat.height[0] = 1; - templat.depth[0] = 1; + templat.width0 = 1; + templat.height0 = 1; + templat.depth0 = 1; templat.last_level = 0; st_ctx->default_texture = screen->texture_create( screen, &templat ); @@ -264,8 +264,8 @@ st_context_create(struct st_device *st_dev) 0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, - st_ctx->default_texture->width[0], - st_ctx->default_texture->height[0]); + st_ctx->default_texture->width0, + st_ctx->default_texture->height0); if (transfer) { uint32_t *map; map = (uint32_t *) screen->transfer_map(screen, transfer); diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index 53a01891e12..6fee90afdaf 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -528,8 +528,8 @@ st_sample_surface(struct st_surface *surface, float *rgba) { struct pipe_texture *texture = surface->texture; struct pipe_screen *screen = texture->screen; - unsigned width = texture->width[surface->level]; - unsigned height = texture->height[surface->level]; + unsigned width = u_minify(texture->width0, surface->level); + unsigned height = u_minify(texture->height0, surface->level); uint rgba_stride = width * 4; struct pipe_transfer *transfer; void *raw; diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 862cbb03c43..faf396d0877 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -68,9 +68,9 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx, templ.target = PIPE_TEXTURE_1D; templ.format = PIPE_FORMAT_A8R8G8B8_UNORM; templ.last_level = 0; - templ.width[0] = color_data_len; - templ.height[0] = 1; - templ.depth[0] = 1; + templ.width0 = color_data_len; + templ.height0 = 1; + templ.depth0 = 1; pf_get_block(PIPE_FORMAT_A8R8G8B8_UNORM, &templ.block); templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; @@ -81,7 +81,7 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx, screen->get_tex_transfer(screen, tex, 0, 0, 0, PIPE_TRANSFER_READ_WRITE , - 0, 0, tex->width[0], tex->height[0]); + 0, 0, tex->width0, tex->height0); void *map = screen->transfer_map(screen, transfer); memcpy(map, color_data, sizeof(VGint)*color_data_len); screen->transfer_unmap(screen, transfer); diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c index 9a722980d52..4684a5727dd 100644 --- a/src/gallium/state_trackers/vega/image.c +++ b/src/gallium/state_trackers/vega/image.c @@ -93,8 +93,8 @@ static void vg_copy_texture(struct vg_context *ctx, dst_loc[3] = height; dst_bounds[0] = 0.f; dst_bounds[1] = 0.f; - dst_bounds[2] = dst->width[0]; - dst_bounds[3] = dst->height[0]; + dst_bounds[2] = dst->width0; + dst_bounds[3] = dst->height0; src_loc[0] = sx; src_loc[1] = sy; @@ -102,8 +102,8 @@ static void vg_copy_texture(struct vg_context *ctx, src_loc[3] = height; src_bounds[0] = 0.f; src_bounds[1] = 0.f; - src_bounds[2] = src->width[0]; - src_bounds[3] = src->height[0]; + src_bounds[2] = src->width0; + src_bounds[3] = src->height0; vg_bound_rect(src_loc, src_bounds, src_shift); vg_bound_rect(dst_loc, dst_bounds, dst_shift); @@ -272,9 +272,9 @@ struct vg_image * image_create(VGImageFormat format, pt.format = pformat; pf_get_block(pformat, &pt.block); pt.last_level = 0; - pt.width[0] = width; - pt.height[0] = height; - pt.depth[0] = 1; + pt.width0 = width; + pt.height0 = height; + pt.depth0 = 1; pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; newtex = screen->texture_create(screen, &pt); @@ -414,7 +414,7 @@ void image_sub_data(struct vg_image *image, { /* upload color_data */ struct pipe_transfer *transfer = screen->get_tex_transfer( screen, texture, 0, 0, 0, - PIPE_TRANSFER_WRITE, 0, 0, texture->width[0], texture->height[0]); + PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0); src += (dataStride * yoffset); for (i = 0; i < height; i++) { _vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp); diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c index 24650a37d50..b84103fdbac 100644 --- a/src/gallium/state_trackers/vega/mask.c +++ b/src/gallium/state_trackers/vega/mask.c @@ -426,7 +426,7 @@ static void mask_using_texture(struct pipe_texture *texture, if (!surface) return; if (!intersect_rectangles(surface->width, surface->height, - texture->width[0], texture->height[0], + texture->width0, texture->height0, x, y, width, height, offsets, loc)) return; @@ -493,9 +493,9 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height) pt.format = PIPE_FORMAT_A8R8G8B8_UNORM; pf_get_block(PIPE_FORMAT_A8R8G8B8_UNORM, &pt.block); pt.last_level = 0; - pt.width[0] = width; - pt.height[0] = height; - pt.depth[0] = 1; + pt.width0 = width; + pt.height0 = height; + pt.depth0 = 1; pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; pt.compressed = 0; @@ -607,8 +607,8 @@ void mask_render_to(struct path *path, struct vg_mask_layer *temp_layer; VGint width, height; - width = fb_buffers->alpha_mask->width[0]; - height = fb_buffers->alpha_mask->width[0]; + width = fb_buffers->alpha_mask->width0; + height = fb_buffers->alpha_mask->width0; temp_layer = mask_layer_create(width, height); diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c index 04a6ba9cdcd..e8ca7d9e89b 100644 --- a/src/gallium/state_trackers/vega/paint.c +++ b/src/gallium/state_trackers/vega/paint.c @@ -151,9 +151,9 @@ static INLINE struct pipe_texture *create_gradient_texture(struct vg_paint *p) templ.target = PIPE_TEXTURE_1D; templ.format = PIPE_FORMAT_A8R8G8B8_UNORM; templ.last_level = 0; - templ.width[0] = 1024; - templ.height[0] = 1; - templ.depth[0] = 1; + templ.width0 = 1024; + templ.height0 = 1; + templ.depth0 = 1; pf_get_block(PIPE_FORMAT_A8R8G8B8_UNORM, &templ.block); templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; @@ -328,8 +328,8 @@ static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer) map[4] = 0.f; map[5] = 1.f; - map[6] = paint->pattern.texture->width[0]; - map[7] = paint->pattern.texture->height[0]; + map[6] = paint->pattern.texture->width0; + map[7] = paint->pattern.texture->height0; { struct matrix mat; memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix, diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 396c88aa3d2..9085ed1bfe0 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -230,13 +230,13 @@ void renderer_draw_texture(struct renderer *r, struct pipe_buffer *buf; VGfloat s0, t0, s1, t1; - assert(tex->width[0] != 0); - assert(tex->height[0] != 0); + assert(tex->width0 != 0); + assert(tex->height0 != 0); - s0 = x1offset / tex->width[0]; - s1 = x2offset / tex->width[0]; - t0 = y1offset / tex->height[0]; - t1 = y2offset / tex->height[0]; + s0 = x1offset / tex->width0; + s1 = x2offset / tex->width0; + t0 = y1offset / tex->height0; + t1 = y2offset / tex->height0; cso_save_vertex_shader(r->cso); /* shaders */ @@ -276,10 +276,10 @@ void renderer_copy_texture(struct renderer *ctx, struct pipe_framebuffer_state fb; float s0, t0, s1, t1; - assert(src->width[0] != 0); - assert(src->height[0] != 0); - assert(dst->width[0] != 0); - assert(dst->height[0] != 0); + assert(src->width0 != 0); + assert(src->height0 != 0); + assert(dst->width0 != 0); + assert(dst->height0 != 0); #if 0 debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n", @@ -287,10 +287,10 @@ void renderer_copy_texture(struct renderer *ctx, #endif #if 1 - s0 = sx1 / src->width[0]; - s1 = sx2 / src->width[0]; - t0 = sy1 / src->height[0]; - t1 = sy2 / src->height[0]; + s0 = sx1 / src->width0; + s1 = sx2 / src->width0; + t0 = sy1 / src->height0; + t1 = sy2 / src->height0; #else s0 = 0; s1 = 1; @@ -445,9 +445,9 @@ void renderer_copy_surface(struct renderer *ctx, texTemp.target = PIPE_TEXTURE_2D; texTemp.format = src->format; texTemp.last_level = 0; - texTemp.width[0] = srcW; - texTemp.height[0] = srcH; - texTemp.depth[0] = 1; + texTemp.width0 = srcW; + texTemp.height0 = srcH; + texTemp.depth0 = 1; pf_get_block(src->format, &texTemp.block); tex = screen->texture_create(screen, &texTemp); @@ -570,13 +570,13 @@ void renderer_texture_quad(struct renderer *r, struct pipe_buffer *buf; VGfloat s0, t0, s1, t1; - assert(tex->width[0] != 0); - assert(tex->height[0] != 0); + assert(tex->width0 != 0); + assert(tex->height0 != 0); - s0 = x1offset / tex->width[0]; - s1 = x2offset / tex->width[0]; - t0 = y1offset / tex->height[0]; - t1 = y2offset / tex->height[0]; + s0 = x1offset / tex->width0; + s1 = x2offset / tex->width0; + t0 = y1offset / tex->height0; + t1 = y2offset / tex->height0; cso_save_vertex_shader(r->cso); /* shaders */ diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c index c4da01e52cc..d28463dd1b8 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.c +++ b/src/gallium/state_trackers/vega/vg_tracker.c @@ -51,9 +51,9 @@ create_texture(struct pipe_context *pipe, enum pipe_format format, templ.target = PIPE_TEXTURE_2D; pf_get_block(templ.format, &templ.block); - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; templ.last_level = 0; if (pf_get_component_bits(format, PIPE_FORMAT_COMP_S)) { diff --git a/src/gallium/state_trackers/wgl/stw_winsys.h b/src/gallium/state_trackers/wgl/stw_winsys.h index 1ead47d6e63..1de6e906d0d 100644 --- a/src/gallium/state_trackers/wgl/stw_winsys.h +++ b/src/gallium/state_trackers/wgl/stw_winsys.h @@ -73,7 +73,7 @@ struct stw_winsys HANDLE hSharedSurface); /** - * Open a shared surface (optional). + * Close a shared surface (optional). */ void (*shared_surface_close)(struct pipe_screen *screen, diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile index 22c107370e8..cb2c3aea410 100644 --- a/src/gallium/state_trackers/xorg/Makefile +++ b/src/gallium/state_trackers/xorg/Makefile @@ -7,6 +7,9 @@ LIBRARY_INCLUDES = \ -DHAVE_CONFIG_H \ $(shell pkg-config xextproto --atleast-version=7.0.99.1 \ && echo "-DHAVE_XEXTPROTO_71") \ + $(shell pkg-config libkms --atleast-version=1.0 \ + && echo "-DHAVE_LIBKMS") \ + $(shell pkg-config libkms --silence-errors --cflags-only-I) \ $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 4dbb490ca51..1c248a629e6 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -232,15 +232,25 @@ bind_blend_state(struct exa_context *exa, int op, } static unsigned -picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask) +picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask, + PicturePtr pDstPicture) { boolean set_alpha = FALSE; boolean swizzle = FALSE; unsigned ret = 0; if (pSrc->picture_format == pSrcPicture->format) { - if (pSrc->picture_format == PICT_a8) - return mask ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE; + if (pSrc->picture_format == PICT_a8) { + if (mask) + return FS_MASK_LUMINANCE; + else if (pDstPicture->format != PICT_a8) { + /* if both dst and src are luminance then + * we don't want to swizzle the alpha (X) of the + * source into W component of the dst because + * it will break our destination */ + return FS_SRC_LUMINANCE; + } + } return 0; } @@ -285,7 +295,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool static void bind_shaders(struct exa_context *exa, int op, - PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask) { unsigned vs_traits = 0, fs_traits = 0; @@ -313,7 +323,7 @@ bind_shaders(struct exa_context *exa, int op, vs_traits |= VS_COMPOSITE; } - fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE); + fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture); } if (pMaskPicture) { @@ -331,7 +341,7 @@ bind_shaders(struct exa_context *exa, int op, fs_traits |= FS_CA_FULL; } - fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE); + fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture); } shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); @@ -411,40 +421,7 @@ bind_samplers(struct exa_context *exa, int op, exa->bound_textures); } -static void -setup_vs_constant_buffer(struct exa_context *exa, - int width, int height) -{ - const int param_bytes = 8 * sizeof(float); - float vs_consts[8] = { - 2.f/width, 2.f/height, 1, 1, - -1, -1, 0, 0 - }; - renderer_set_constants(exa->renderer, PIPE_SHADER_VERTEX, - vs_consts, param_bytes); -} - - -static void -setup_fs_constant_buffer(struct exa_context *exa) -{ - const int param_bytes = 4 * sizeof(float); - const float fs_consts[8] = { - 0, 0, 0, 1, - }; - renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT, - fs_consts, param_bytes); -} - -static void -setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst) -{ - int width = pDst->tex->width[0]; - int height = pDst->tex->height[0]; - setup_vs_constant_buffer(exa, width, height); - setup_fs_constant_buffer(exa); -} static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix) { @@ -493,14 +470,16 @@ boolean xorg_composite_bind_state(struct exa_context *exa, struct exa_pixmap_priv *pMask, struct exa_pixmap_priv *pDst) { - renderer_bind_framebuffer(exa->renderer, pDst); - renderer_bind_viewport(exa->renderer, pDst); + struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst); + + renderer_bind_destination(exa->renderer, dst_surf, + pDst->width, + pDst->height); + bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture); - renderer_bind_rasterizer(exa->renderer); - bind_shaders(exa, op, pSrcPicture, pMaskPicture, pSrc, pMask); + bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask); bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask, pDst); - setup_constant_buffers(exa, pDst); setup_transforms(exa, pSrcPicture, pMaskPicture); @@ -512,6 +491,8 @@ boolean xorg_composite_bind_state(struct exa_context *exa, exa->num_bound_samplers); } + + pipe_surface_reference(&dst_surf, NULL); return TRUE; } @@ -546,6 +527,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa, struct exa_pixmap_priv *pixmap, Pixel fg) { + struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap); unsigned vs_traits, fs_traits; struct xorg_shader shader; @@ -563,13 +545,11 @@ boolean xorg_solid_bind_state(struct exa_context *exa, vs_traits = VS_SOLID_FILL; fs_traits = FS_SOLID_FILL; - renderer_bind_framebuffer(exa->renderer, pixmap); - renderer_bind_viewport(exa->renderer, pixmap); - renderer_bind_rasterizer(exa->renderer); + renderer_bind_destination(exa->renderer, dst_surf, + pixmap->width, pixmap->height); bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL); cso_set_samplers(exa->renderer->cso, 0, NULL); cso_set_sampler_textures(exa->renderer->cso, 0, NULL); - setup_constant_buffers(exa, pixmap); shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits); cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs); @@ -577,6 +557,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa, renderer_begin_solid(exa->renderer); + pipe_surface_reference(&dst_surf, NULL); return TRUE; } @@ -588,3 +569,13 @@ void xorg_solid(struct exa_context *exa, x0, y0, x1, y1, exa->solid_color); } +void +xorg_composite_done(struct exa_context *exa) +{ + renderer_draw_flush(exa->renderer); + + exa->transform.has_src = FALSE; + exa->transform.has_mask = FALSE; + exa->has_solid_color = FALSE; + exa->num_bound_samplers = 0; +} diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h index 236addf1ce4..ec71ebfe0dc 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.h +++ b/src/gallium/state_trackers/xorg/xorg_composite.h @@ -29,4 +29,8 @@ void xorg_solid(struct exa_context *exa, struct exa_pixmap_priv *pixmap, int x0, int y0, int x1, int y1); + +void +xorg_composite_done(struct exa_context *exa); + #endif diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 85b9162d4cf..9e8c14d741c 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -52,12 +52,18 @@ #include "pipe/p_inlines.h" #include "util/u_rect.h" +#ifdef HAVE_LIBKMS +#include "libkms.h" +#endif + struct crtc_private { drmModeCrtcPtr drm_crtc; /* hwcursor */ struct pipe_texture *cursor_tex; + struct kms_bo *cursor_bo; + unsigned cursor_handle; }; @@ -134,6 +140,7 @@ static void crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, int size) { + /* XXX: hockup */ } static void * @@ -160,6 +167,7 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) static void crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) { + /* XXX: See if this one is needed, as we only support ARGB cursors */ } static void @@ -170,8 +178,9 @@ crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); } + static void -crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) +crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) { unsigned char *ptr; modesettingPtr ms = modesettingPTR(crtc->scrn); @@ -187,10 +196,10 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; - templat.depth[0] = 1; + templat.depth0 = 1; templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.width[0] = 64; - templat.height[0] = 64; + templat.width0 = 64; + templat.height0 = 64; pf_get_block(templat.format, &templat.block); crtcp->cursor_tex = ms->screen->texture_create(ms->screen, @@ -214,13 +223,63 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) ms->screen->tex_transfer_destroy(transfer); } +#if HAVE_LIBKMS +static void +crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + struct crtc_private *crtcp = crtc->driver_private; + unsigned char *ptr; + + if (!crtcp->cursor_bo) { + unsigned attr[8]; + + attr[0] = KMS_BO_TYPE; + attr[1] = KMS_BO_TYPE_CURSOR; + attr[2] = KMS_WIDTH; + attr[3] = 64; + attr[4] = KMS_HEIGHT; + attr[5] = 64; + attr[6] = 0; + + if (kms_bo_create(ms->kms, attr, &crtcp->cursor_bo)) + return; + + if (kms_bo_get_prop(crtcp->cursor_bo, KMS_HANDLE, + &crtcp->cursor_handle)) + goto err_bo_destroy; + } + + kms_bo_map(crtcp->cursor_bo, (void**)&ptr); + memcpy(ptr, image, 64*64*4); + kms_bo_unmap(crtcp->cursor_bo); + + return; + +err_bo_destroy: + kms_bo_destroy(crtcp->cursor_bo); +} +#endif + +static void +crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + if (ms->screen) + crtc_load_cursor_argb_ga3d(crtc, image); +#ifdef HAVE_LIBKMS + else if (ms->kms) + crtc_load_cursor_argb_kms(crtc, image); +#endif +} + static void crtc_show_cursor(xf86CrtcPtr crtc) { modesettingPtr ms = modesettingPTR(crtc->scrn); struct crtc_private *crtcp = crtc->driver_private; - if (crtcp->cursor_tex) + if (crtcp->cursor_tex || crtcp->cursor_bo) drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, crtcp->cursor_handle, 64, 64); } @@ -234,14 +293,22 @@ crtc_hide_cursor(xf86CrtcPtr crtc) drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); } +/** + * Called at vt leave + */ void -crtc_cursor_destroy(xf86CrtcPtr crtc) +xorg_crtc_cursor_destroy(xf86CrtcPtr crtc) { struct crtc_private *crtcp = crtc->driver_private; - if (crtcp->cursor_tex) { + if (crtcp->cursor_tex) pipe_texture_reference(&crtcp->cursor_tex, NULL); - } +#ifdef HAVE_LIBKMS + if (crtcp->cursor_bo) + kms_bo_destroy(crtcp->cursor_bo); +#endif + + xfree(crtcp); } /* @@ -279,7 +346,7 @@ static const xf86CrtcFuncsRec crtc_funcs = { }; void -crtc_init(ScrnInfoPtr pScrn) +xorg_crtc_init(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); xf86CrtcPtr crtc; diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index ca3c712dcd2..2394f004d25 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -55,7 +55,7 @@ typedef struct { } *BufferPrivatePtr; static Bool -driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) +dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) { struct pipe_texture *tex = NULL; ScreenPtr pScreen = pDraw->pScreen; @@ -109,9 +109,9 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) template.format = ms->ds_depth_bits_last ? PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; pf_get_block(template.format, &template.block); - template.width[0] = pDraw->width; - template.height[0] = pDraw->height; - template.depth[0] = 1; + template.width0 = pDraw->width; + template.height0 = pDraw->height; + template.depth0 = 1; template.last_level = 0; template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL | PIPE_TEXTURE_USAGE_DISPLAY_TARGET; @@ -157,7 +157,7 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) } static void -driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer) +dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -174,7 +174,7 @@ driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer) #if DRI2INFOREC_VERSION >= 2 static DRI2Buffer2Ptr -driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) +dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { DRI2Buffer2Ptr buffer; BufferPrivatePtr private; @@ -192,7 +192,7 @@ driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) buffer->driverPrivate = private; /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */ - if (driDoCreateBuffer(pDraw, (DRI2BufferPtr)buffer, format)) + if (dri2_do_create_buffer(pDraw, (DRI2BufferPtr)buffer, format)) return buffer; xfree(private); @@ -202,10 +202,10 @@ fail: } static void -driDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) +dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) { /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */ - driDoDestroyBuffer(pDraw, (DRI2BufferPtr)buffer); + dri2_do_destroy_buffer(pDraw, (DRI2BufferPtr)buffer); xfree(buffer->driverPrivate); xfree(buffer); @@ -214,7 +214,7 @@ driDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) #else /* DRI2INFOREC_VERSION < 2 */ static DRI2BufferPtr -driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) +dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count) { BufferPrivatePtr privates; DRI2BufferPtr buffers; @@ -232,7 +232,7 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) buffers[i].attachment = attachments[i]; buffers[i].driverPrivate = &privates[i]; - if (!driDoCreateBuffer(pDraw, &buffers[i], 0)) + if (!dri2_do_create_buffer(pDraw, &buffers[i], 0)) goto fail; } @@ -247,12 +247,12 @@ fail_buffers: } static void -driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) +dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) { int i; for (i = 0; i < count; i++) { - driDoDestroyBuffer(pDraw, &buffers[i]); + dri2_do_destroy_buffer(pDraw, &buffers[i]); } if (buffers) { @@ -264,16 +264,16 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) #endif /* DRI2INFOREC_VERSION >= 2 */ static void -driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, - DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) +dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, + DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; - PixmapPtr src_pixmap; - PixmapPtr dst_pixmap; + DrawablePtr src_draw; + DrawablePtr dst_draw; GCPtr gc; RegionPtr copy_clip; Bool save_accel; @@ -284,12 +284,10 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, * We need to use the real drawable in CopyArea * so that cliprects and offsets are correct. */ - src_pixmap = src_priv->pPixmap; - dst_pixmap = dst_priv->pPixmap; - if (pSrcBuffer->attachment == DRI2BufferFrontLeft) - src_pixmap = (PixmapPtr)pDraw; - if (pDestBuffer->attachment == DRI2BufferFrontLeft) - dst_pixmap = (PixmapPtr)pDraw; + src_draw = (pSrcBuffer->attachment == DRI2BufferFrontLeft) ? pDraw : + &src_priv->pPixmap->drawable; + dst_draw = (pDestBuffer->attachment == DRI2BufferFrontLeft) ? pDraw : + &dst_priv->pPixmap->drawable; /* * The clients implements glXWaitX with a copy front to fake and then @@ -308,7 +306,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, * must in the glXWaitGL case but we don't know if this is a glXWaitGL * or a glFlush/glFinish call. */ - if (dst_pixmap == src_pixmap) { + if (dst_priv->pPixmap == src_priv->pPixmap) { /* pixmap glXWaitX */ if (pSrcBuffer->attachment == DRI2BufferFrontLeft && pDestBuffer->attachment == DRI2BufferFakeFrontLeft) { @@ -329,7 +327,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, copy_clip = REGION_CREATE(pScreen, NULL, 0); REGION_COPY(pScreen, copy_clip, pRegion); (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); - ValidateGC(&dst_pixmap->drawable, gc); + ValidateGC(dst_draw, gc); /* If this is a full buffer swap, throttle on the previous one */ if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { @@ -342,9 +340,19 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, } } + /* Try to make sure the blit will be accelerated */ save_accel = ms->exa->accel; ms->exa->accel = TRUE; - (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc, + + /* In case it won't be though, make sure the GPU copy contents of the + * source pixmap will be used for the software fallback - presumably the + * client modified them before calling in here. + */ + exaMoveInPixmap(src_priv->pPixmap); + DamageRegionAppend(src_draw, pRegion); + DamageRegionProcessPending(src_draw); + + (*gc->ops->CopyArea)(src_draw, dst_draw, gc, 0, 0, pDraw->width, pDraw->height, 0, 0); ms->exa->accel = save_accel; @@ -356,7 +364,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, } Bool -driScreenInit(ScreenPtr pScreen) +xorg_dri2_init(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); @@ -373,13 +381,13 @@ driScreenInit(ScreenPtr pScreen) dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ #if DRI2INFOREC_VERSION >= 2 - dri2info.CreateBuffer = driCreateBuffer; - dri2info.DestroyBuffer = driDestroyBuffer; + dri2info.CreateBuffer = dri2_create_buffer; + dri2info.DestroyBuffer = dri2_destroy_buffer; #else - dri2info.CreateBuffers = driCreateBuffers; - dri2info.DestroyBuffers = driDestroyBuffers; + dri2info.CreateBuffers = dri2_create_buffers; + dri2info.DestroyBuffers = dri2_destroy_buffers; #endif - dri2info.CopyRegion = driCopyRegion; + dri2info.CopyRegion = dri2_copy_region; dri2info.Wait = NULL; ms->d_depth_bits_last = @@ -395,7 +403,7 @@ driScreenInit(ScreenPtr pScreen) } void -driCloseScreen(ScreenPtr pScreen) +xorg_dri2_close(ScreenPtr pScreen) { DRI2CloseScreen(pScreen); } diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index d949167adce..12915912986 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -56,34 +56,38 @@ #include "xorg_tracker.h" #include "xorg_winsys.h" -static void AdjustFrame(int scrnIndex, int x, int y, int flags); -static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool EnterVT(int scrnIndex, int flags); -static Bool SaveHWState(ScrnInfoPtr pScrn); -static Bool RestoreHWState(ScrnInfoPtr pScrn); - - -static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, - int flags); -static void FreeScreen(int scrnIndex, int flags); -static void LeaveVT(int scrnIndex, int flags); -static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); -static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, - char **argv); -static Bool PreInit(ScrnInfoPtr pScrn, int flags); +#ifdef HAVE_LIBKMS +#include "libkms.h" +#endif + +/* + * Functions and symbols exported to Xorg via pointers. + */ + +static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags); +static Bool drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, + char **argv); +static Bool drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags); +static void drv_adjust_frame(int scrnIndex, int x, int y, int flags); +static Bool drv_enter_vt(int scrnIndex, int flags); +static void drv_leave_vt(int scrnIndex, int flags); +static void drv_free_screen(int scrnIndex, int flags); +static ModeStatus drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); typedef enum { OPTION_SW_CURSOR, OPTION_2D_ACCEL, -} modesettingOpts; +} drv_option_enums; -static const OptionInfoRec Options[] = { +static const OptionInfoRec drv_options[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; + /* * Exported Xorg driver functions to winsys */ @@ -91,28 +95,39 @@ static const OptionInfoRec Options[] = { const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid) { - return Options; + return drv_options; } void xorg_tracker_set_functions(ScrnInfoPtr scrn) { - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; + scrn->PreInit = drv_pre_init; + scrn->ScreenInit = drv_screen_init; + scrn->SwitchMode = drv_switch_mode; + scrn->AdjustFrame = drv_adjust_frame; + scrn->EnterVT = drv_enter_vt; + scrn->LeaveVT = drv_leave_vt; + scrn->FreeScreen = drv_free_screen; + scrn->ValidMode = drv_valid_mode; } + /* - * Static Xorg funtctions + * Internal function definitions + */ + +static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn); +static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen); +static Bool drv_save_hw_state(ScrnInfoPtr pScrn); +static Bool drv_restore_hw_state(ScrnInfoPtr pScrn); + + +/* + * Internal functions */ static Bool -GetRec(ScrnInfoPtr pScrn) +drv_get_rec(ScrnInfoPtr pScrn) { if (pScrn->driverPrivate) return TRUE; @@ -123,7 +138,7 @@ GetRec(ScrnInfoPtr pScrn) } static void -FreeRec(ScrnInfoPtr pScrn) +drv_free_rec(ScrnInfoPtr pScrn) { if (!pScrn) return; @@ -137,88 +152,21 @@ FreeRec(ScrnInfoPtr pScrn) } static void -ProbeDDC(ScrnInfoPtr pScrn, int index) +drv_probe_ddc(ScrnInfoPtr pScrn, int index) { ConfiguredMonitor = NULL; } static Bool -CreateFrontBuffer(ScrnInfoPtr pScrn) -{ - modesettingPtr ms = modesettingPTR(pScrn); - unsigned handle, stride; - struct pipe_texture *tex; - - ms->noEvict = TRUE; - - tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY, - pScrn->depth, pScrn->bitsPerPixel); - - if (!tex) - return FALSE; - - if (!ms->api->local_handle_from_texture(ms->api, ms->screen, - tex, - &stride, - &handle)) - return FALSE; - - drmModeAddFB(ms->fd, - pScrn->virtualX, - pScrn->virtualY, - pScrn->depth, - pScrn->bitsPerPixel, - stride, - handle, - &ms->fb_id); - - pScrn->frameX0 = 0; - pScrn->frameY0 = 0; - AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - pipe_texture_reference(&ms->root_texture, tex); - pipe_texture_reference(&tex, NULL); - return TRUE; -} - -static Bool -BindTextureToRoot(ScrnInfoPtr pScrn) -{ - modesettingPtr ms = modesettingPTR(pScrn); - ScreenPtr pScreen = pScrn->pScreen; - struct pipe_texture *check; - PixmapPtr rootPixmap; - - rootPixmap = pScreen->GetScreenPixmap(pScreen); - - xorg_exa_set_displayed_usage(rootPixmap); - xorg_exa_set_shared_usage(rootPixmap); - xorg_exa_set_texture(rootPixmap, ms->root_texture); - if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) - FatalError("Couldn't adjust screen pixmap\n"); - - check = xorg_exa_get_texture(rootPixmap); - if (ms->root_texture != check) - FatalError("Created new root texture\n"); - - pipe_texture_reference(&check, NULL); - - return TRUE; -} - -static Bool -crtc_resize(ScrnInfoPtr pScrn, int width, int height) +drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height) { modesettingPtr ms = modesettingPTR(pScrn); - unsigned handle, stride; PixmapPtr rootPixmap; ScreenPtr pScreen = pScrn->pScreen; if (width == pScrn->virtualX && height == pScrn->virtualY) return TRUE; - ErrorF("RESIZING TO %dx%d\n", width, height); - pScrn->virtualX = width; pScrn->virtualY = height; @@ -226,44 +174,26 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height) * Remove the old framebuffer & texture. */ drmModeRmFB(ms->fd, ms->fb_id); - pipe_texture_reference(&ms->root_texture, NULL); - + if (!ms->destroy_front_buffer(pScrn)) + FatalError("failed to destroy front buffer\n"); rootPixmap = pScreen->GetScreenPixmap(pScreen); if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL)) return FALSE; - /* takes one ref */ - ms->root_texture = xorg_exa_get_texture(rootPixmap); - - if (!ms->api->local_handle_from_texture(ms->api, ms->screen, - ms->root_texture, - &stride, - &handle)) - FatalError("Could not get handle and stride from texture\n"); - - drmModeAddFB(ms->fd, - pScrn->virtualX, - pScrn->virtualY, - pScrn->depth, - pScrn->bitsPerPixel, - stride, - handle, - &ms->fb_id); - /* HW dependent - FIXME */ pScrn->displayWidth = pScrn->virtualX; /* now create new frontbuffer */ - return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn); + return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn); } static const xf86CrtcConfigFuncsRec crtc_config_funcs = { - crtc_resize + .resize = drv_crtc_resize }; static Bool -InitDRM(ScrnInfoPtr pScrn) +drv_init_drm(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); @@ -283,18 +213,62 @@ InitDRM(ScrnInfoPtr pScrn) return FALSE; } - if (!ms->api) { - ms->api = drm_api_create(); + return TRUE; +} - if (!ms->api) - return FALSE; +static Bool +drv_init_resource_management(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + if (ms->screen || ms->kms) + return TRUE; + + ms->api = drm_api_create(); + if (ms->api) { + ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); + + if (ms->screen) + return TRUE; + + if (ms->api->destroy) + ms->api->destroy(ms->api); + + ms->api = NULL; } +#ifdef HAVE_LIBKMS + if (!kms_create(ms->fd, &ms->kms)) + return TRUE; +#endif + + return FALSE; +} + +static Bool +drv_close_resource_management(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + if (ms->screen) + ms->screen->destroy(ms->screen); + ms->screen = NULL; + + if (ms->api && ms->api->destroy) + ms->api->destroy(ms->api); + ms->api = NULL; + +#ifdef HAVE_LIBKMS + if (ms->kms) + kms_destroy(ms->kms); + ms->kms = NULL; +#endif + return TRUE; } static Bool -PreInit(ScrnInfoPtr pScrn, int flags) +drv_pre_init(ScrnInfoPtr pScrn, int flags) { xf86CrtcConfigPtr xf86_config; modesettingPtr ms; @@ -309,12 +283,12 @@ PreInit(ScrnInfoPtr pScrn, int flags) pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (flags & PROBE_DETECT) { - ProbeDDC(pScrn, pEnt->index); + drv_probe_ddc(pScrn, pEnt->index); return TRUE; } /* Allocate driverPrivate */ - if (!GetRec(pScrn)) + if (!drv_get_rec(pScrn)) return FALSE; ms = modesettingPTR(pScrn); @@ -351,7 +325,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) ms->fd = -1; ms->api = NULL; - if (!InitDRM(pScrn)) + if (!drv_init_drm(pScrn)) return FALSE; pScrn->monitor = pScrn->confScreen->monitor; @@ -383,9 +357,9 @@ PreInit(ScrnInfoPtr pScrn, int flags) /* Process the options */ xf86CollectOptions(pScrn, NULL); - if (!(ms->Options = xalloc(sizeof(Options)))) + if (!(ms->Options = xalloc(sizeof(drv_options)))) return FALSE; - memcpy(ms->Options, Options, sizeof(Options)); + memcpy(ms->Options, drv_options, sizeof(drv_options)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); /* Allocate an xf86CrtcConfig */ @@ -400,18 +374,18 @@ PreInit(ScrnInfoPtr pScrn, int flags) ms->SWCursor = TRUE; } - SaveHWState(pScrn); + drv_save_hw_state(pScrn); - crtc_init(pScrn); - output_init(pScrn); + xorg_crtc_init(pScrn); + xorg_output_init(pScrn); if (!xf86InitialConfiguration(pScrn, TRUE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); + drv_restore_hw_state(pScrn); return FALSE; } - RestoreHWState(pScrn); + drv_restore_hw_state(pScrn); /* * If the driver can do gamma correction, it should call xf86SetGamma() here. @@ -435,21 +409,23 @@ PreInit(ScrnInfoPtr pScrn, int flags) xf86SetDpi(pScrn, 0, 0); /* Load the required sub modules */ - if (!xf86LoadSubModule(pScrn, "fb")) { + if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; - } - xf86LoadSubModule(pScrn, "exa"); + /* XXX: these aren't needed when we are using libkms */ + if (!xf86LoadSubModule(pScrn, "exa")) + return FALSE; #ifdef DRI2 - xf86LoadSubModule(pScrn, "dri2"); + if (!xf86LoadSubModule(pScrn, "dri2")) + return FALSE; #endif return TRUE; } static Bool -SaveHWState(ScrnInfoPtr pScrn) +drv_save_hw_state(ScrnInfoPtr pScrn) { /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/ @@ -457,24 +433,45 @@ SaveHWState(ScrnInfoPtr pScrn) } static Bool -RestoreHWState(ScrnInfoPtr pScrn) +drv_restore_hw_state(ScrnInfoPtr pScrn) { /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/ return TRUE; } -static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout, - pointer pReadmask) +static void drv_block_handler(int i, pointer blockData, pointer pTimeout, + pointer pReadmask) { ScreenPtr pScreen = screenInfo.screens[i]; modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]); pScreen->BlockHandler = ms->blockHandler; pScreen->BlockHandler(i, blockData, pTimeout, pReadmask); - pScreen->BlockHandler = xorgBlockHandler; - - ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + pScreen->BlockHandler = drv_block_handler; + + if (ms->ctx) { + int j; + + ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]); + + if (ms->fence[0]) + ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0); + + /* The amount of rendering generated by a block handler can be + * quite small. Let us get a fair way ahead of hardware before + * throttling. + */ + for (j = 0; j < XORG_NR_FENCES; j++) + ms->screen->fence_reference(ms->screen, + &ms->fence[j], + ms->fence[j+1]); + + ms->screen->fence_reference(ms->screen, + &ms->fence[XORG_NR_FENCES-1], + NULL); + } + #ifdef DRM_MODE_FEATURE_DIRTYFB { @@ -504,7 +501,7 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout, } static Bool -CreateScreenResources(ScreenPtr pScreen) +drv_create_screen_resources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); @@ -515,13 +512,13 @@ CreateScreenResources(ScreenPtr pScreen) pScreen->CreateScreenResources = ms->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); - pScreen->CreateScreenResources = CreateScreenResources; + pScreen->CreateScreenResources = drv_create_screen_resources; - BindTextureToRoot(pScrn); + ms->bind_front_buffer(pScrn); ms->noEvict = FALSE; - AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); #ifdef DRM_MODE_FEATURE_DIRTYFB rootPixmap = pScreen->GetScreenPixmap(pScreen); @@ -545,22 +542,25 @@ CreateScreenResources(ScreenPtr pScreen) } static Bool -ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); VisualPtr visual; - if (!InitDRM(pScrn)) + if (!drv_init_drm(pScrn)) { + FatalError("Could not init DRM"); return FALSE; + } - if (!ms->screen) { - ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); + if (!drv_init_resource_management(pScrn)) { + FatalError("Could not init resource management (!pipe_screen && !libkms)"); + return FALSE; + } - if (!ms->screen) { - FatalError("Could not init pipe_screen\n"); - return FALSE; - } + if (!drv_init_front_buffer_functions(pScrn)) { + FatalError("Could not init front buffer manager"); + return FALSE; } pScrn->pScreen = pScreen; @@ -605,17 +605,22 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) fbPictureInit(pScreen, NULL, 0); ms->blockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = xorgBlockHandler; + pScreen->BlockHandler = drv_block_handler; ms->createScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = CreateScreenResources; + pScreen->CreateScreenResources = drv_create_screen_resources; xf86SetBlackWhitePixels(pScreen); - ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options, - OPTION_2D_ACCEL, TRUE)); - ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE); + if (ms->screen) { + ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options, + OPTION_2D_ACCEL, TRUE)); + ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE); - xorg_init_video(pScreen); + xorg_xv_init(pScreen); +#ifdef DRI2 + xorg_dri2_init(pScreen); +#endif + } miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); @@ -634,7 +639,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScreen->SaveScreen = xf86SaveScreen; ms->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = CloseScreen; + pScreen->CloseScreen = drv_close_screen; if (!xf86CrtcScreenInit(pScreen)) return FALSE; @@ -647,17 +652,11 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); -#if 1 -#ifdef DRI2 - driScreenInit(pScreen); -#endif -#endif - - return EnterVT(scrnIndex, 1); + return drv_enter_vt(scrnIndex, 1); } static void -AdjustFrame(int scrnIndex, int x, int y, int flags) +drv_adjust_frame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -673,13 +672,13 @@ AdjustFrame(int scrnIndex, int x, int y, int flags) } static void -FreeScreen(int scrnIndex, int flags) +drv_free_screen(int scrnIndex, int flags) { - FreeRec(xf86Screens[scrnIndex]); + drv_free_rec(xf86Screens[scrnIndex]); } static void -LeaveVT(int scrnIndex, int flags) +drv_leave_vt(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); @@ -689,7 +688,7 @@ LeaveVT(int scrnIndex, int flags) for (o = 0; o < config->num_crtc; o++) { xf86CrtcPtr crtc = config->crtc[o]; - crtc_cursor_destroy(crtc); + xorg_crtc_cursor_destroy(crtc); if (crtc->rotatedPixmap || crtc->rotatedData) { crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, @@ -701,7 +700,7 @@ LeaveVT(int scrnIndex, int flags) drmModeRmFB(ms->fd, ms->fb_id); - RestoreHWState(pScrn); + drv_restore_hw_state(pScrn); if (drmDropMaster(ms->fd)) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -714,7 +713,7 @@ LeaveVT(int scrnIndex, int flags) * This gets called when gaining control of the VT, and from ScreenInit(). */ static Bool -EnterVT(int scrnIndex, int flags) +drv_enter_vt(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); @@ -736,13 +735,13 @@ EnterVT(int scrnIndex, int flags) */ if (ms->SaveGeneration != serverGeneration) { ms->SaveGeneration = serverGeneration; - SaveHWState(pScrn); + drv_save_hw_state(pScrn); } - if (!CreateFrontBuffer(pScrn)) + if (!ms->create_front_buffer(pScrn)) return FALSE; - if (!flags && !BindTextureToRoot(pScrn)) + if (!flags && !ms->bind_front_buffer(pScrn)) return FALSE; if (!xf86SetDesiredModes(pScrn)) @@ -752,7 +751,7 @@ EnterVT(int scrnIndex, int flags) } static Bool -SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; @@ -760,16 +759,18 @@ SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) } static Bool -CloseScreen(int scrnIndex, ScreenPtr pScreen) +drv_close_screen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); if (pScrn->vtSema) { - LeaveVT(scrnIndex, 0); + drv_leave_vt(scrnIndex, 0); } + #ifdef DRI2 - driCloseScreen(pScreen); + if (ms->screen) + xorg_dri2_close(pScreen); #endif pScreen->BlockHandler = ms->blockHandler; @@ -783,14 +784,14 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen) } #endif - pipe_texture_reference(&ms->root_texture, NULL); + drmModeRmFB(ms->fd, ms->fb_id); + ms->destroy_front_buffer(pScrn); if (ms->exa) xorg_exa_close(pScrn); + ms->exa = NULL; - if (ms->api && ms->api->destroy) - ms->api->destroy(ms->api); - ms->api = NULL; + drv_close_resource_management(pScrn); drmClose(ms->fd); ms->fd = -1; @@ -801,9 +802,190 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen) } static ModeStatus -ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { return MODE_OK; } + +/* + * Front buffer backing store functions. + */ + +static Bool +drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + pipe_texture_reference(&ms->root_texture, NULL); + return TRUE; +} + +static Bool +drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + unsigned handle, stride; + struct pipe_texture *tex; + + ms->noEvict = TRUE; + + tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel); + + if (!tex) + return FALSE; + + if (!ms->api->local_handle_from_texture(ms->api, ms->screen, + tex, + &stride, + &handle)) + return FALSE; + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + stride, + handle, + &ms->fb_id); + + pScrn->frameX0 = 0; + pScrn->frameY0 = 0; + drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + pipe_texture_reference(&ms->root_texture, tex); + pipe_texture_reference(&tex, NULL); + + return TRUE; +} + +static Bool +drv_bind_front_buffer_ga3d(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + struct pipe_texture *check; + + xorg_exa_set_displayed_usage(rootPixmap); + xorg_exa_set_shared_usage(rootPixmap); + xorg_exa_set_texture(rootPixmap, ms->root_texture); + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) + FatalError("Couldn't adjust screen pixmap\n"); + + check = xorg_exa_get_texture(rootPixmap); + if (ms->root_texture != check) + FatalError("Created new root texture\n"); + + pipe_texture_reference(&check, NULL); + return TRUE; +} + +#ifdef HAVE_LIBKMS +static Bool +drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + if (!ms->root_bo) + return TRUE; + + kms_bo_unmap(ms->root_bo); + kms_bo_destroy(ms->root_bo); + ms->root_bo = NULL; + return TRUE; +} + +static Bool +drv_create_front_buffer_kms(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + unsigned handle, stride; + struct kms_bo *bo; + unsigned attr[8]; + + attr[0] = KMS_BO_TYPE; + attr[1] = KMS_BO_TYPE_SCANOUT; + attr[2] = KMS_WIDTH; + attr[3] = pScrn->virtualX; + attr[4] = KMS_HEIGHT; + attr[5] = pScrn->virtualY; + attr[6] = 0; + + if (kms_bo_create(ms->kms, attr, &bo)) + return FALSE; + + if (kms_bo_get_prop(bo, KMS_PITCH, &stride)) + goto err_destroy; + + if (kms_bo_get_prop(bo, KMS_HANDLE, &handle)) + goto err_destroy; + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + stride, + handle, + &ms->fb_id); + + pScrn->frameX0 = 0; + pScrn->frameY0 = 0; + drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + ms->root_bo = bo; + + return TRUE; + +err_destroy: + kms_bo_destroy(bo); + return FALSE; +} + +static Bool +drv_bind_front_buffer_kms(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + unsigned stride; + void *ptr; + + if (kms_bo_get_prop(ms->root_bo, KMS_PITCH, &stride)) + return FALSE; + + if (kms_bo_map(ms->root_bo, &ptr)) + return FALSE; + + pScreen->ModifyPixmapHeader(rootPixmap, + pScreen->width, + pScreen->height, + pScreen->rootDepth, + pScrn->bitsPerPixel, + stride, + ptr); + return TRUE; +} +#endif /* HAVE_LIBKMS */ + +static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + if (ms->screen) { + ms->destroy_front_buffer = drv_destroy_front_buffer_ga3d; + ms->create_front_buffer = drv_create_front_buffer_ga3d; + ms->bind_front_buffer = drv_bind_front_buffer_ga3d; +#ifdef HAVE_LIBKMS + } else if (ms->kms) { + ms->destroy_front_buffer = drv_destroy_front_buffer_kms; + ms->create_front_buffer = drv_create_front_buffer_kms; + ms->bind_front_buffer = drv_bind_front_buffer_kms; +#endif + } else + return FALSE; + + return TRUE; +} + /* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 3d83b5700d5..16e683019c1 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -44,8 +44,11 @@ #include "pipe/p_inlines.h" #include "util/u_rect.h" +#include "util/u_math.h" +#include "util/u_debug.h" #define DEBUG_PRINT 0 +#define ROUND_UP_TEXTURES 1 /* * Helper functions @@ -149,18 +152,6 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_ } } -static void -xorg_exa_common_done(struct exa_context *exa) -{ - renderer_draw_flush(exa->renderer); - - exa->copy.src = NULL; - exa->copy.dst = NULL; - exa->transform.has_src = FALSE; - exa->transform.has_mask = FALSE; - exa->has_solid_color = FALSE; - exa->num_bound_samplers = 0; -} /* * Static exported EXA functions @@ -178,6 +169,11 @@ ExaMarkSync(ScreenPtr pScreen) return 1; } + +/*********************************************************************** + * Screen upload/download + */ + static Bool ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst, int dst_pitch) @@ -278,13 +274,22 @@ ExaPrepareAccess(PixmapPtr pPix, int index) PIPE_REFERENCED_FOR_WRITE) exa->pipe->flush(exa->pipe, 0, NULL); + assert(pPix->drawable.width <= priv->tex->width0); + assert(pPix->drawable.height <= priv->tex->height0); + priv->map_transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, #ifdef EXA_MIXED_PIXMAPS PIPE_TRANSFER_MAP_DIRECTLY | #endif PIPE_TRANSFER_READ_WRITE, - 0, 0, priv->tex->width[0], priv->tex->height[0]); +<<<<<<< HEAD:src/gallium/state_trackers/xorg/xorg_exa.c + 0, 0, priv->tex->width0, priv->tex->height0); +======= + 0, 0, + pPix->drawable.width, + pPix->drawable.height ); +>>>>>>> origin/mesa_7_7_branch:src/gallium/state_trackers/xorg/xorg_exa.c if (!priv->map_transfer) #ifdef EXA_MIXED_PIXMAPS return FALSE; @@ -327,29 +332,9 @@ ExaFinishAccess(PixmapPtr pPix, int index) } } -static void -ExaDone(PixmapPtr pPixmap) -{ - ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); - struct exa_context *exa = ms->exa; - - if (!priv) - return; - - xorg_exa_common_done(exa); -} - -static void -ExaDoneComposite(PixmapPtr pPixmap) -{ - ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - struct exa_context *exa = ms->exa; - - xorg_exa_common_done(exa); -} +/*********************************************************************** + * Solid Fills + */ static Bool ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) @@ -395,9 +380,34 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1); #endif + if (x0 == 0 && y0 == 0 && + x1 == pPixmap->drawable.width && y1 == pPixmap->drawable.height) { + exa->pipe->clear(exa->pipe, PIPE_CLEAR_COLOR, exa->solid_color, 0.0, 0); + return; + } + xorg_solid(exa, priv, x0, y0, x1, y1) ; } + +static void +ExaDoneSolid(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_context *exa = ms->exa; + + if (!priv) + return; + + xorg_composite_done(exa); +} + +/*********************************************************************** + * Copy Blits + */ + static Bool ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planeMask) @@ -439,6 +449,51 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, exa->copy.src = src_priv; exa->copy.dst = priv; + /* For same-surface copies, the pipe->surface_copy path is clearly + * superior, providing it is implemented. In other cases it's not + * clear what the better path would be, and eventually we'd + * probably want to gather timings and choose dynamically. + */ + if (exa->pipe->surface_copy && + exa->copy.src == exa->copy.dst) { + + exa->copy.use_surface_copy = TRUE; + + exa->copy.src_surface = + exa->scrn->get_tex_surface( exa->scrn, + exa->copy.src->tex, + 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ); + + exa->copy.dst_surface = + exa->scrn->get_tex_surface( exa->scrn, + exa->copy.dst->tex, + 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE ); + } + else { + exa->copy.use_surface_copy = FALSE; + + if (exa->copy.dst == exa->copy.src) + exa->copy.src_texture = renderer_clone_texture( exa->renderer, + exa->copy.src->tex ); + else + pipe_texture_reference(&exa->copy.src_texture, + exa->copy.src->tex); + + exa->copy.dst_surface = + exa->scrn->get_tex_surface(exa->scrn, + exa->copy.dst->tex, + 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + + renderer_copy_prepare(exa->renderer, + exa->copy.dst_surface, + exa->copy.src_texture ); + } + + return exa->accel; } @@ -458,11 +513,48 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, debug_assert(priv == exa->copy.dst); - renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY, - exa->copy.src, srcX, srcY, - width, height); + if (exa->copy.use_surface_copy) { + /* XXX: consider exposing >1 box in surface_copy interface. + */ + exa->pipe->surface_copy( exa->pipe, + exa->copy.dst_surface, + dstX, dstY, + exa->copy.src_surface, + srcX, srcY, + width, height ); + } + else { + renderer_copy_pixmap(exa->renderer, + dstX, dstY, + srcX, srcY, + width, height, + exa->copy.src_texture->width0, + exa->copy.src_texture->height0); + } } +static void +ExaDoneCopy(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_context *exa = ms->exa; + + if (!priv) + return; + + renderer_draw_flush(exa->renderer); + + exa->copy.src = NULL; + exa->copy.dst = NULL; + pipe_surface_reference(&exa->copy.src_surface, NULL); + pipe_surface_reference(&exa->copy.dst_surface, NULL); + pipe_texture_reference(&exa->copy.src_texture, NULL); +} + + + static Bool picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture) { @@ -498,6 +590,30 @@ picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture) return FALSE; } +/*********************************************************************** + * Composite entrypoints + */ + +static Bool +ExaCheckComposite(int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + boolean accelerated = xorg_composite_accelerated(op, + pSrcPicture, + pMaskPicture, + pDstPicture); +#if DEBUG_PRINT + debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n", + op, pSrcPicture, pMaskPicture, pDstPicture, accelerated); +#endif + return exa->accel && accelerated; +} + + static Bool ExaPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, @@ -548,8 +664,6 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, render_format_name(priv->picture_format), render_format_name(pSrcPicture->format)); - if (priv->picture_format == PICT_a8) - XORG_FALLBACK("pSrc pic_format == PICT_a8"); } if (pMask) { @@ -596,25 +710,23 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, dstX, dstY, width, height); } -static Bool -ExaCheckComposite(int op, - PicturePtr pSrcPicture, PicturePtr pMaskPicture, - PicturePtr pDstPicture) + + +static void +ExaDoneComposite(PixmapPtr pPixmap) { - ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; - boolean accelerated = xorg_composite_accelerated(op, - pSrcPicture, - pMaskPicture, - pDstPicture); -#if DEBUG_PRINT - debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n", - op, pSrcPicture, pMaskPicture, pDstPicture, accelerated); -#endif - return exa->accel && accelerated; + + xorg_composite_done(exa); } + +/*********************************************************************** + * Pixmaps + */ + static void * ExaCreatePixmap(ScreenPtr pScreen, int size, int align) { @@ -718,6 +830,22 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out) } static Bool +size_match( int width, int tex_width ) +{ +#if ROUND_UP_TEXTURES + if (width > tex_width) + return FALSE; + + if (width * 2 < tex_width) + return FALSE; + + return TRUE; +#else + return width == tex_width; +#endif +} + +static Bool ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) @@ -731,6 +859,17 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, if (!priv || pPixData) return FALSE; + if (0) { + debug_printf("%s pixmap %p sz %dx%dx%d devKind %d\n", + __FUNCTION__, pPixmap, width, height, bitsPerPixel, devKind); + + if (priv->tex) + debug_printf(" ==> old texture %dx%d\n", + priv->tex->width0, + priv->tex->height0); + } + + if (depth <= 0) depth = pPixmap->drawable.depth; @@ -749,12 +888,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, NULL); + priv->width = width; + priv->height = height; + /* Deal with screen resize */ if ((exa->accel || priv->flags) && (!priv->tex || - (priv->tex->width[0] != width || - priv->tex->height[0] != height || - priv->tex_flags != priv->flags))) { + !size_match(width, priv->tex->width0) || + !size_match(height, priv->tex->height0) || + priv->tex_flags != priv->flags)) { struct pipe_texture *texture = NULL; struct pipe_texture template; @@ -762,9 +904,16 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, template.target = PIPE_TEXTURE_2D; exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format); pf_get_block(template.format, &template.block); - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; + if (ROUND_UP_TEXTURES && priv->flags == 0) { + template.width0 = util_next_power_of_two(width); + template.height0 = util_next_power_of_two(height); + } + else { + template.width0 = width; + template.height0 = height; + } + + template.depth0 = 1; template.last_level = 0; template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; priv->tex_flags = priv->flags; @@ -777,15 +926,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, dst_surf = exa->scrn->get_tex_surface( exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); src_surf = xorg_gpu_surface(exa->pipe->screen, priv); - if (exa->pipe->surface_copy) { - exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, - 0, 0, min(width, texture->width[0]), - min(height, texture->height[0])); - } else { - util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf, - 0, 0, min(width, texture->width[0]), - min(height, texture->height[0])); - } + if (exa->pipe->surface_copy) { + exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, + 0, 0, min(width, texture->width0), + min(height, texture->height0)); + } else { + util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf, + 0, 0, min(width, texture->width0), + min(height, texture->height0)); + } exa->scrn->tex_surface_destroy(dst_surf); exa->scrn->tex_surface_destroy(src_surf); } @@ -817,8 +966,8 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex) if (!priv) return FALSE; - if (pPixmap->drawable.width != tex->width[0] || - pPixmap->drawable.height != tex->height[0]) + if (pPixmap->drawable.width != tex->width0 || + pPixmap->drawable.height != tex->height0) return FALSE; pipe_texture_reference(&priv->tex, tex); @@ -841,9 +990,9 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn, template.target = PIPE_TEXTURE_2D; exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &dummy); pf_get_block(template.format, &template.block); - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; + template.width0 = width; + template.height0 = height; + template.depth0 = 1; template.last_level = 0; template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; @@ -907,10 +1056,10 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) pExa->MarkSync = ExaMarkSync; pExa->PrepareSolid = ExaPrepareSolid; pExa->Solid = ExaSolid; - pExa->DoneSolid = ExaDone; + pExa->DoneSolid = ExaDoneSolid; pExa->PrepareCopy = ExaPrepareCopy; pExa->Copy = ExaCopy; - pExa->DoneCopy = ExaDone; + pExa->DoneCopy = ExaDoneCopy; pExa->CheckComposite = ExaCheckComposite; pExa->PrepareComposite = ExaPrepareComposite; pExa->Composite = ExaComposite; diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h index 15cc29d6620..f2cefe23b99 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.h +++ b/src/gallium/state_trackers/xorg/xorg_exa.h @@ -35,13 +35,22 @@ struct exa_context } transform; struct { + boolean use_surface_copy; + struct exa_pixmap_priv *src; struct exa_pixmap_priv *dst; + + struct pipe_surface *src_surface; + struct pipe_surface *dst_surface; + + struct pipe_texture *src_texture; } copy; }; struct exa_pixmap_priv { + int width, height; + int flags; int tex_flags; diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index 52b97af1635..89b794a09ac 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -396,15 +396,11 @@ xrender_tex(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src coords, struct ureg_src sampler, + struct ureg_src imm0, boolean repeat_none, boolean swizzle, boolean set_alpha) { - struct ureg_src imm0 = { 0 }; - - if (repeat_none || set_alpha) - imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); - if (repeat_none) { struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); @@ -466,6 +462,7 @@ create_fs(struct pipe_context *pipe, struct ureg_src /*dst_pos,*/ src_input, mask_pos; struct ureg_dst src, mask; struct ureg_dst out; + struct ureg_src imm0 = { 0 }; unsigned has_mask = (fs_traits & FS_MASK) != 0; unsigned is_fill = (fs_traits & FS_FILL) != 0; unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0; @@ -483,8 +480,6 @@ create_fs(struct pipe_context *pipe, unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; - if (src_luminance) - assert(!"src_luminance not supported"); #if 0 print_fs_traits(fs_traits); #else @@ -502,6 +497,11 @@ create_fs(struct pipe_context *pipe, TGSI_SEMANTIC_COLOR, 0); + if (src_repeat_none || mask_repeat_none || + src_set_alpha || mask_set_alpha || + src_luminance) { + imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); + } if (is_composite) { src_sampler = ureg_DECL_sampler(ureg, 0); src_input = ureg_DECL_fs_input(ureg, @@ -540,16 +540,17 @@ create_fs(struct pipe_context *pipe, TGSI_INTERPOLATE_PERSPECTIVE); #endif + if (is_composite) { - if (has_mask) + if (has_mask || src_luminance) src = ureg_DECL_temporary(ureg); else src = out; - xrender_tex(ureg, src, src_input, src_sampler, + xrender_tex(ureg, src, src_input, src_sampler, imm0, src_repeat_none, src_swizzle, src_set_alpha); } else if (is_fill) { if (is_solid) { - if (has_mask) + if (has_mask || src_luminance) src = ureg_dst(src_input); else ureg_MOV(ureg, out, src_input); @@ -557,7 +558,7 @@ create_fs(struct pipe_context *pipe, struct ureg_src coords, const0124, matrow0, matrow1, matrow2; - if (has_mask) + if (has_mask || src_luminance) src = ureg_DECL_temporary(ureg); else src = out; @@ -582,10 +583,18 @@ create_fs(struct pipe_context *pipe, } else debug_assert(!"Unknown fill type!"); } + if (src_luminance) { + ureg_MOV(ureg, src, + ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X)); + ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ), + ureg_scalar(imm0, TGSI_SWIZZLE_X)); + if (!has_mask) + ureg_MOV(ureg, out, ureg_src(src)); + } if (has_mask) { mask = ureg_DECL_temporary(ureg); - xrender_tex(ureg, mask, mask_pos, mask_sampler, + xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0, mask_repeat_none, mask_swizzle, mask_set_alpha); /* src IN mask */ src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c index bfeddc5e114..251f331ea7a 100644 --- a/src/gallium/state_trackers/xorg/xorg_output.c +++ b/src/gallium/state_trackers/xorg/xorg_output.c @@ -53,7 +53,7 @@ #include "xorg_tracker.h" -static char *connector_enum_list[] = { +static char *output_enum_list[] = { "Unknown", "VGA", "DVI", @@ -70,19 +70,19 @@ static char *connector_enum_list[] = { }; static void -create_resources(xf86OutputPtr output) +output_create_resources(xf86OutputPtr output) { #ifdef RANDR_12_INTERFACE #endif /* RANDR_12_INTERFACE */ } static void -dpms(xf86OutputPtr output, int mode) +output_dpms(xf86OutputPtr output, int mode) { } static xf86OutputStatus -detect(xf86OutputPtr output) +output_detect(xf86OutputPtr output) { drmModeConnectorPtr drm_connector = output->driver_private; @@ -97,7 +97,7 @@ detect(xf86OutputPtr output) } static DisplayModePtr -get_modes(xf86OutputPtr output) +output_get_modes(xf86OutputPtr output) { drmModeConnectorPtr drm_connector = output->driver_private; drmModeModeInfoPtr drm_mode = NULL; @@ -110,7 +110,6 @@ get_modes(xf86OutputPtr output) mode = xcalloc(1, sizeof(DisplayModeRec)); if (!mode) continue; - mode->type = 0; mode->Clock = drm_mode->clock; mode->HDisplay = drm_mode->hdisplay; mode->HSyncStart = drm_mode->hsync_start; @@ -125,6 +124,11 @@ get_modes(xf86OutputPtr output) mode->VScan = drm_mode->vscan; mode->VRefresh = xf86ModeVRefresh(mode); mode->Private = (void *)drm_mode; + mode->type = 0; + if (drm_mode->type & DRM_MODE_TYPE_PREFERRED) + mode->type |= M_T_PREFERRED; + if (drm_mode->type & DRM_MODE_TYPE_DRIVER) + mode->type |= M_T_DRIVER; xf86SetModeDefaultName(mode); modes = xf86ModesAdd(modes, mode); xf86PrintModeline(0, mode); @@ -135,14 +139,14 @@ get_modes(xf86OutputPtr output) } static int -mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { return MODE_OK; } #ifdef RANDR_12_INTERFACE static Bool -set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) +output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) { return TRUE; } @@ -150,36 +154,36 @@ set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) #ifdef RANDR_13_INTERFACE static Bool -get_property(xf86OutputPtr output, Atom property) +output_get_property(xf86OutputPtr output, Atom property) { return TRUE; } #endif /* RANDR_13_INTERFACE */ static void -destroy(xf86OutputPtr output) +output_destroy(xf86OutputPtr output) { drmModeFreeConnector(output->driver_private); } static const xf86OutputFuncsRec output_funcs = { - .create_resources = create_resources, + .create_resources = output_create_resources, #ifdef RANDR_12_INTERFACE - .set_property = set_property, + .set_property = output_set_property, #endif #ifdef RANDR_13_INTERFACE - .get_property = get_property, + .get_property = output_get_property, #endif - .dpms = dpms, - .detect = detect, + .dpms = output_dpms, + .detect = output_detect, - .get_modes = get_modes, - .mode_valid = mode_valid, - .destroy = destroy, + .get_modes = output_get_modes, + .mode_valid = output_mode_valid, + .destroy = output_destroy, }; void -output_init(ScrnInfoPtr pScrn) +xorg_output_init(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); xf86OutputPtr output; @@ -220,7 +224,7 @@ output_init(ScrnInfoPtr pScrn) #endif snprintf(name, 32, "%s%d", - connector_enum_list[drm_connector->connector_type], + output_enum_list[drm_connector->connector_type], drm_connector->connector_type_id); diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 723605312c5..8f73ec5fe11 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -13,11 +13,6 @@ #include <math.h> -enum AxisOrientation { - Y0_BOTTOM, - Y0_TOP -}; - #define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y))) #define floatIsZero(x) (floatsEqual((x) + 1, 1)) @@ -96,10 +91,18 @@ static void renderer_init_state(struct xorg_renderer *r) { struct pipe_depth_stencil_alpha_state dsa; + struct pipe_rasterizer_state raster; /* set common initial clip state */ memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); cso_set_depth_stencil_alpha(r->cso, &dsa); + + + /* XXX: move to renderer_init_state? */ + memset(&raster, 0, sizeof(struct pipe_rasterizer_state)); + raster.gl_rasterization_rules = 1; + cso_set_rasterizer(r->cso, &raster); + } @@ -167,14 +170,14 @@ add_vertex_data1(struct xorg_renderer *r, map_point(src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]); } - s0 = pt0[0] / src->width[0]; - s1 = pt1[0] / src->width[0]; - s2 = pt2[0] / src->width[0]; - s3 = pt3[0] / src->width[0]; - t0 = pt0[1] / src->height[0]; - t1 = pt1[1] / src->height[0]; - t2 = pt2[1] / src->height[0]; - t3 = pt3[1] / src->height[0]; + s0 = pt0[0] / src->width0; + s1 = pt1[0] / src->width0; + s2 = pt2[0] / src->width0; + s3 = pt3[0] / src->width0; + t0 = pt0[1] / src->height0; + t1 = pt1[1] / src->height0; + t2 = pt2[1] / src->height0; + t3 = pt3[1] / src->height0; /* 1st vertex */ add_vertex_1tex(r, dstX, dstY, s0, t0); @@ -186,23 +189,6 @@ add_vertex_data1(struct xorg_renderer *r, add_vertex_1tex(r, dstX, dstY + height, s3, t3); } -static struct pipe_buffer * -setup_vertex_data_tex(struct xorg_renderer *r, - float x0, float y0, float x1, float y1, - float s0, float t0, float s1, float t1, - float z) -{ - /* 1st vertex */ - add_vertex_1tex(r, x0, y0, s0, t0); - /* 2nd vertex */ - add_vertex_1tex(r, x1, y0, s1, t0); - /* 3rd vertex */ - add_vertex_1tex(r, x1, y1, s1, t1); - /* 4th vertex */ - add_vertex_1tex(r, x0, y1, s0, t1); - - return renderer_buffer_create(r); -} static INLINE void add_vertex_2tex(struct xorg_renderer *r, @@ -262,15 +248,15 @@ add_vertex_data2(struct xorg_renderer *r, map_point(mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]); } - src_s0 = spt0[0] / src->width[0]; - src_t0 = spt0[1] / src->height[0]; - src_s1 = spt1[0] / src->width[0]; - src_t1 = spt1[1] / src->height[0]; + src_s0 = spt0[0] / src->width0; + src_t0 = spt0[1] / src->height0; + src_s1 = spt1[0] / src->width0; + src_t1 = spt1[1] / src->height0; - mask_s0 = mpt0[0] / mask->width[0]; - mask_t0 = mpt0[1] / mask->height[0]; - mask_s1 = mpt1[0] / mask->width[0]; - mask_t1 = mpt1[1] / mask->height[0]; + mask_s0 = mpt0[0] / mask->width0; + mask_t0 = mpt0[1] / mask->height0; + mask_s1 = mpt1[0] / mask->width0; + mask_t1 = mpt1[1] / mask->height0; /* 1st vertex */ add_vertex_2tex(r, dstX, dstY, @@ -300,10 +286,10 @@ setup_vertex_data_yuv(struct xorg_renderer *r, spt1[0] = srcX + srcW; spt1[1] = srcY + srcH; - s0 = spt0[0] / tex[0]->width[0]; - t0 = spt0[1] / tex[0]->height[0]; - s1 = spt1[0] / tex[0]->width[0]; - t1 = spt1[1] / tex[0]->height[0]; + s0 = spt0[0] / tex[0]->width0; + t0 = spt0[1] / tex[0]->height0; + s1 = spt1[0] / tex[0]->width0; + t1 = spt1[1] / tex[0]->height0; /* 1st vertex */ add_vertex_1tex(r, dstX, dstY, s0, t0); @@ -322,15 +308,32 @@ setup_vertex_data_yuv(struct xorg_renderer *r, -static void -set_viewport(struct xorg_renderer *r, int width, int height, - enum AxisOrientation orientation) +/* Set up framebuffer, viewport and vertex shader constant buffer + * state for a particular destinaton surface. In all our rendering, + * these concepts are linked. + */ +void renderer_bind_destination(struct xorg_renderer *r, + struct pipe_surface *surface, + int width, + int height ) { + + struct pipe_framebuffer_state fb; struct pipe_viewport_state viewport; - float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f; + /* Framebuffer uses actual surface width/height + */ + memset(&fb, 0, sizeof fb); + fb.width = surface->width; + fb.height = surface->height; + fb.nr_cbufs = 1; + fb.cbufs[0] = surface; + fb.zsbuf = 0; + + /* Viewport just touches the bit we're interested in: + */ viewport.scale[0] = width / 2.f; - viewport.scale[1] = height / y_scale; + viewport.scale[1] = height / 2.f; viewport.scale[2] = 1.0; viewport.scale[3] = 1.0; viewport.translate[0] = width / 2.f; @@ -338,11 +341,28 @@ set_viewport(struct xorg_renderer *r, int width, int height, viewport.translate[2] = 0.0; viewport.translate[3] = 0.0; + /* Constant buffer set up to match viewport dimensions: + */ + if (r->fb_width != width || + r->fb_height != height) + { + float vs_consts[8] = { + 2.f/width, 2.f/height, 1, 1, + -1, -1, 0, 0 + }; + + r->fb_width = width; + r->fb_height = height; + + renderer_set_constants(r, PIPE_SHADER_VERTEX, + vs_consts, sizeof vs_consts); + } + + cso_set_framebuffer(r->cso, &fb); cso_set_viewport(r->cso, &viewport); } - struct xorg_renderer * renderer_create(struct pipe_context *pipe) { struct xorg_renderer *renderer = CALLOC_STRUCT(xorg_renderer); @@ -379,51 +399,9 @@ void renderer_destroy(struct xorg_renderer *r) } } -void renderer_bind_framebuffer(struct xorg_renderer *r, - struct exa_pixmap_priv *priv) -{ - unsigned i; - struct pipe_framebuffer_state state; - struct pipe_surface *surface = xorg_gpu_surface(r->pipe->screen, priv); - memset(&state, 0, sizeof(struct pipe_framebuffer_state)); - - state.width = priv->tex->width[0]; - state.height = priv->tex->height[0]; - - state.nr_cbufs = 1; - state.cbufs[0] = surface; - for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i) - state.cbufs[i] = 0; - - /* currently we don't use depth/stencil */ - state.zsbuf = 0; - - cso_set_framebuffer(r->cso, &state); - - /* we do fire and forget for the framebuffer, this is the forget part */ - pipe_surface_reference(&surface, NULL); -} - -void renderer_bind_viewport(struct xorg_renderer *r, - struct exa_pixmap_priv *dst) -{ - int width = dst->tex->width[0]; - int height = dst->tex->height[0]; - /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/ - set_viewport(r, width, height, Y0_TOP); -} -void renderer_bind_rasterizer(struct xorg_renderer *r) -{ - struct pipe_rasterizer_state raster; - - /* XXX: move to renderer_init_state? */ - memset(&raster, 0, sizeof(struct pipe_rasterizer_state)); - raster.gl_rasterization_rules = 1; - cso_set_rasterizer(r->cso, &raster); -} void renderer_set_constants(struct xorg_renderer *r, int shader_type, @@ -446,182 +424,20 @@ void renderer_set_constants(struct xorg_renderer *r, r->pipe->set_constant_buffer(r->pipe, shader_type, 0, cbuf); } -static void -setup_vs_constant_buffer(struct xorg_renderer *r, - int width, int height) -{ - const int param_bytes = 8 * sizeof(float); - float vs_consts[8] = { - 2.f/width, 2.f/height, 1, 1, - -1, -1, 0, 0 - }; - renderer_set_constants(r, PIPE_SHADER_VERTEX, - vs_consts, param_bytes); -} -static void -setup_fs_constant_buffer(struct xorg_renderer *r) -{ - const int param_bytes = 4 * sizeof(float); - const float fs_consts[8] = { - 0, 0, 0, 1, - }; - renderer_set_constants(r, PIPE_SHADER_FRAGMENT, - fs_consts, param_bytes); -} - -static INLINE void shift_rectx(float coords[4], - const float *bounds, - const float shift) -{ - coords[0] += shift; - coords[2] -= shift; - if (bounds) { - coords[2] = MIN2(coords[2], bounds[2]); - /* bound x/y + width/height */ - if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) { - coords[2] = (bounds[0] + bounds[2]) - coords[0]; - } - } -} - -static INLINE void shift_recty(float coords[4], - const float *bounds, - const float shift) -{ - coords[1] += shift; - coords[3] -= shift; - if (bounds) { - coords[3] = MIN2(coords[3], bounds[3]); - if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) { - coords[3] = (bounds[1] + bounds[3]) - coords[1]; - } - } -} - -static INLINE void bound_rect(float coords[4], - const float bounds[4], - float shift[4]) -{ - /* if outside the bounds */ - if (coords[0] > (bounds[0] + bounds[2]) || - coords[1] > (bounds[1] + bounds[3]) || - (coords[0] + coords[2]) < bounds[0] || - (coords[1] + coords[3]) < bounds[1]) { - coords[0] = 0.f; - coords[1] = 0.f; - coords[2] = 0.f; - coords[3] = 0.f; - shift[0] = 0.f; - shift[1] = 0.f; - return; - } - - /* bound x */ - if (coords[0] < bounds[0]) { - shift[0] = bounds[0] - coords[0]; - coords[2] -= shift[0]; - coords[0] = bounds[0]; - } else - shift[0] = 0.f; - - /* bound y */ - if (coords[1] < bounds[1]) { - shift[1] = bounds[1] - coords[1]; - coords[3] -= shift[1]; - coords[1] = bounds[1]; - } else - shift[1] = 0.f; - - shift[2] = bounds[2] - coords[2]; - shift[3] = bounds[3] - coords[3]; - /* bound width/height */ - coords[2] = MIN2(coords[2], bounds[2]); - coords[3] = MIN2(coords[3], bounds[3]); - - /* bound x/y + width/height */ - if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) { - coords[2] = (bounds[0] + bounds[2]) - coords[0]; - } - if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) { - coords[3] = (bounds[1] + bounds[3]) - coords[1]; - } - - /* if outside the bounds */ - if ((coords[0] + coords[2]) < bounds[0] || - (coords[1] + coords[3]) < bounds[1]) { - coords[0] = 0.f; - coords[1] = 0.f; - coords[2] = 0.f; - coords[3] = 0.f; - return; - } -} - -static INLINE void sync_size(float *src_loc, float *dst_loc) -{ - src_loc[2] = MIN2(src_loc[2], dst_loc[2]); - src_loc[3] = MIN2(src_loc[3], dst_loc[3]); - dst_loc[2] = src_loc[2]; - dst_loc[3] = src_loc[3]; -} - -static void renderer_copy_texture(struct xorg_renderer *r, - struct pipe_texture *src, - float sx1, float sy1, - float sx2, float sy2, - struct pipe_texture *dst, - float dx1, float dy1, - float dx2, float dy2) +void renderer_copy_prepare(struct xorg_renderer *r, + struct pipe_surface *dst_surface, + struct pipe_texture *src_texture) { struct pipe_context *pipe = r->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_buffer *buf; - struct pipe_surface *dst_surf = screen->get_tex_surface( - screen, dst, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - struct pipe_framebuffer_state fb; - float s0, t0, s1, t1; struct xorg_shader shader; - assert(src->width[0] != 0); - assert(src->height[0] != 0); - assert(dst->width[0] != 0); - assert(dst->height[0] != 0); - -#if 1 - s0 = sx1 / src->width[0]; - s1 = sx2 / src->width[0]; - t0 = sy1 / src->height[0]; - t1 = sy2 / src->height[0]; -#else - s0 = 0; - s1 = 1; - t0 = 0; - t1 = 1; -#endif - -#if 0 - debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n", - sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, - s0, t0, s1, t1); -#endif - - assert(screen->is_format_supported(screen, dst_surf->format, + assert(screen->is_format_supported(screen, dst_surface->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); - /* save state (restored below) */ - cso_save_blend(r->cso); - cso_save_samplers(r->cso); - cso_save_sampler_textures(r->cso); - cso_save_framebuffer(r->cso); - cso_save_fragment_shader(r->cso); - cso_save_vertex_shader(r->cso); - - cso_save_viewport(r->cso); - /* set misc state we care about */ { @@ -650,12 +466,12 @@ static void renderer_copy_texture(struct xorg_renderer *r, cso_single_sampler_done(r->cso); } - set_viewport(r, dst_surf->width, dst_surf->height, Y0_TOP); + renderer_bind_destination(r, dst_surface, + dst_surface->width, + dst_surface->height); /* texture */ - cso_set_sampler_textures(r->cso, 1, &src); - - renderer_bind_rasterizer(r); + cso_set_sampler_textures(r->cso, 1, &src_texture); /* shaders */ shader = xorg_shaders_get(r->shaders, @@ -664,51 +480,12 @@ static void renderer_copy_texture(struct xorg_renderer *r, cso_set_vertex_shader_handle(r->cso, shader.vs); cso_set_fragment_shader_handle(r->cso, shader.fs); - /* drawing dest */ - memset(&fb, 0, sizeof(fb)); - fb.width = dst_surf->width; - fb.height = dst_surf->height; - fb.nr_cbufs = 1; - fb.cbufs[0] = dst_surf; - { - int i; - for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i) - fb.cbufs[i] = 0; - } - cso_set_framebuffer(r->cso, &fb); - setup_vs_constant_buffer(r, fb.width, fb.height); - setup_fs_constant_buffer(r); - - /* draw quad */ - buf = setup_vertex_data_tex(r, - dx1, dy1, - dx2, dy2, - s0, t0, s1, t1, - 0.0f); - - if (buf) { - util_draw_vertex_buffer(r->pipe, buf, 0, - PIPE_PRIM_QUADS, - 4, /* verts */ - 2); /* attribs/vert */ - - pipe_buffer_reference(&buf, NULL); - } - - /* restore state we changed */ - cso_restore_blend(r->cso); - cso_restore_samplers(r->cso); - cso_restore_sampler_textures(r->cso); - cso_restore_framebuffer(r->cso); - cso_restore_vertex_shader(r->cso); - cso_restore_fragment_shader(r->cso); - cso_restore_viewport(r->cso); - - pipe_surface_reference(&dst_surf, NULL); + r->buffer_size = 0; + r->attrs_per_vertex = 2; } -static struct pipe_texture * -create_sampler_texture(struct xorg_renderer *r, +struct pipe_texture * +renderer_clone_texture(struct xorg_renderer *r, struct pipe_texture *src) { enum pipe_format format; @@ -717,7 +494,9 @@ create_sampler_texture(struct xorg_renderer *r, struct pipe_texture *pt; struct pipe_texture templ; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + if (pipe->is_texture_referenced(pipe, src, 0, 0) & + PIPE_REFERENCED_FOR_WRITE) + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* the coming in texture should already have that invariance */ debug_assert(screen->is_format_supported(screen, src->format, @@ -730,9 +509,9 @@ create_sampler_texture(struct xorg_renderer *r, templ.target = PIPE_TEXTURE_2D; templ.format = format; templ.last_level = 0; - templ.width[0] = src->width[0]; - templ.height[0] = src->height[0]; - templ.depth[0] = 1; + templ.width0 = src->width0; + templ.height0 = src->height0; + templ.depth0 = 1; pf_get_block(format, &templ.block); templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; @@ -754,13 +533,13 @@ create_sampler_texture(struct xorg_renderer *r, ps_tex, /* dest */ 0, 0, /* destx/y */ ps_read, - 0, 0, src->width[0], src->height[0]); + 0, 0, src->width0, src->height0); } else { util_surface_copy(pipe, FALSE, ps_tex, /* dest */ 0, 0, /* destx/y */ ps_read, - 0, 0, src->width[0], src->height[0]); + 0, 0, src->width0, src->height0); } pipe_surface_reference(&ps_read, NULL); pipe_surface_reference(&ps_tex, NULL); @@ -771,16 +550,16 @@ create_sampler_texture(struct xorg_renderer *r, void renderer_copy_pixmap(struct xorg_renderer *r, - struct exa_pixmap_priv *dst_priv, int dx, int dy, - struct exa_pixmap_priv *src_priv, int sx, int sy, - int width, int height) + int dx, int dy, + int sx, int sy, + int width, int height, + float src_width, + float src_height) { - float dst_loc[4], src_loc[4]; - float dst_bounds[4], src_bounds[4]; - float src_shift[4], dst_shift[4], shift[4]; - struct pipe_texture *dst = dst_priv->tex; - struct pipe_texture *src = src_priv->tex; + float s0, t0, s1, t1; + float x0, y0, x1, y1; +<<<<<<< HEAD:src/gallium/state_trackers/xorg/xorg_renderer.c if (r->pipe->is_texture_referenced(r->pipe, src, 0, 0) & PIPE_REFERENCED_FOR_WRITE) r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); @@ -791,8 +570,8 @@ void renderer_copy_pixmap(struct xorg_renderer *r, dst_loc[3] = height; dst_bounds[0] = 0.f; dst_bounds[1] = 0.f; - dst_bounds[2] = dst->width[0]; - dst_bounds[3] = dst->height[0]; + dst_bounds[2] = dst->width0; + dst_bounds[3] = dst->height0; src_loc[0] = sx; src_loc[1] = sy; @@ -800,8 +579,8 @@ void renderer_copy_pixmap(struct xorg_renderer *r, src_loc[3] = height; src_bounds[0] = 0.f; src_bounds[1] = 0.f; - src_bounds[2] = src->width[0]; - src_bounds[3] = src->height[0]; + src_bounds[2] = src->width0; + src_bounds[3] = src->height0; bound_rect(src_loc, src_bounds, src_shift); bound_rect(dst_loc, dst_bounds, dst_shift); @@ -842,8 +621,33 @@ void renderer_copy_pixmap(struct xorg_renderer *r, if (src == dst) pipe_texture_reference(&temp_src, NULL); } +======= + + /* XXX: could put the texcoord scaling calculation into the vertex + * shader. + */ + s0 = sx / src_width; + s1 = (sx + width) / src_width; + t0 = sy / src_height; + t1 = (sy + height) / src_height; + + x0 = dx; + x1 = dx + width; + y0 = dy; + y1 = dy + height; + + /* draw quad */ + renderer_draw_conditional(r, 4*8); + add_vertex_1tex(r, x0, y0, s0, t0); + add_vertex_1tex(r, x1, y0, s1, t0); + add_vertex_1tex(r, x1, y1, s1, t1); + add_vertex_1tex(r, x0, y1, s0, t1); +>>>>>>> origin/mesa_7_7_branch:src/gallium/state_trackers/xorg/xorg_renderer.c } + + + void renderer_draw_yuv(struct xorg_renderer *r, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h index 2f0b865dbdc..5272cde2b3f 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.h +++ b/src/gallium/state_trackers/xorg/xorg_renderer.h @@ -21,6 +21,8 @@ struct xorg_renderer { struct cso_context *cso; struct xorg_shaders *shaders; + int fb_width; + int fb_height; struct pipe_constant_buffer vs_const_buffer; struct pipe_constant_buffer fs_const_buffer; @@ -35,19 +37,19 @@ struct xorg_renderer { struct xorg_renderer *renderer_create(struct pipe_context *pipe); void renderer_destroy(struct xorg_renderer *renderer); +void renderer_bind_destination(struct xorg_renderer *r, + struct pipe_surface *surface, + int width, + int height ); + void renderer_bind_framebuffer(struct xorg_renderer *r, struct exa_pixmap_priv *priv); void renderer_bind_viewport(struct xorg_renderer *r, struct exa_pixmap_priv *dst); -void renderer_bind_rasterizer(struct xorg_renderer *r); void renderer_set_constants(struct xorg_renderer *r, int shader_type, const float *buffer, int size); -void renderer_copy_pixmap(struct xorg_renderer *r, - struct exa_pixmap_priv *dst_priv, int dx, int dy, - struct exa_pixmap_priv *src_priv, int sx, int sy, - int width, int height); void renderer_draw_yuv(struct xorg_renderer *r, @@ -74,5 +76,20 @@ void renderer_texture(struct xorg_renderer *r, void renderer_draw_flush(struct xorg_renderer *r); +struct pipe_texture * +renderer_clone_texture(struct xorg_renderer *r, + struct pipe_texture *src); + +void renderer_copy_prepare(struct xorg_renderer *r, + struct pipe_surface *dst_surface, + struct pipe_texture *src_texture); + +void renderer_copy_pixmap(struct xorg_renderer *r, + int dx, int dy, + int sx, int sy, + int width, int height, + float src_width, + float src_height); + #endif diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index 20c9259c7bc..c6c7b2fe158 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -51,6 +51,8 @@ #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); +struct kms_bo; +struct kms_driver; struct exa_context; typedef struct @@ -61,6 +63,8 @@ typedef struct ScrnInfoPtr pScrn_2; } EntRec, *EntPtr; +#define XORG_NR_FENCES 3 + typedef struct _modesettingRec { /* drm */ @@ -84,8 +88,19 @@ typedef struct _modesettingRec unsigned int SaveGeneration; void (*blockHandler)(int, pointer, pointer, pointer); + struct pipe_fence_handle *fence[XORG_NR_FENCES]; + CreateScreenResourcesProcPtr createScreenResources; + /* for frontbuffer backing store */ + Bool (*destroy_front_buffer)(ScrnInfoPtr pScrn); + Bool (*create_front_buffer)(ScrnInfoPtr pScrn); + Bool (*bind_front_buffer)(ScrnInfoPtr pScrn); + + /* kms */ + struct kms_driver *kms; + struct kms_bo *root_bo; + /* gallium */ struct drm_api *api; struct pipe_screen *screen; @@ -141,33 +156,34 @@ xorg_exa_close(ScrnInfoPtr pScrn); * xorg_dri2.c */ Bool -driScreenInit(ScreenPtr pScreen); +xorg_dri2_init(ScreenPtr pScreen); void -driCloseScreen(ScreenPtr pScreen); +xorg_dri2_close(ScreenPtr pScreen); /*********************************************************************** * xorg_crtc.c */ void -crtc_init(ScrnInfoPtr pScrn); +xorg_crtc_init(ScrnInfoPtr pScrn); void -crtc_cursor_destroy(xf86CrtcPtr crtc); +xorg_crtc_cursor_destroy(xf86CrtcPtr crtc); /*********************************************************************** * xorg_output.c */ void -output_init(ScrnInfoPtr pScrn); +xorg_output_init(ScrnInfoPtr pScrn); + /*********************************************************************** * xorg_xv.c */ void -xorg_init_video(ScreenPtr pScreen); +xorg_xv_init(ScreenPtr pScreen); #endif /* _XORG_TRACKER_H_ */ diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index 4a701e93ecc..b8eca8c8176 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -167,9 +167,9 @@ create_component_texture(struct pipe_context *pipe, templ.target = PIPE_TEXTURE_2D; templ.format = PIPE_FORMAT_L8_UNORM; templ.last_level = 0; - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; pf_get_block(PIPE_FORMAT_L8_UNORM, &templ.block); templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; @@ -183,18 +183,18 @@ check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height) { struct pipe_texture **dst = priv->yuv[priv->current_set]; if (!dst[0] || - dst[0]->width[0] != width || - dst[0]->height[0] != height) { + dst[0]->width0 != width || + dst[0]->height0 != height) { pipe_texture_reference(&dst[0], NULL); } if (!dst[1] || - dst[1]->width[0] != width || - dst[1]->height[0] != height) { + dst[1]->width0 != width || + dst[1]->height0 != height) { pipe_texture_reference(&dst[1], NULL); } if (!dst[2] || - dst[2]->width[0] != width || - dst[2]->height[0] != height) { + dst[2]->width0 != width || + dst[2]->height0 != height) { pipe_texture_reference(&dst[2], NULL); } @@ -319,21 +319,6 @@ copy_packed_data(ScrnInfoPtr pScrn, static void -setup_vs_video_constants(struct xorg_renderer *r, struct exa_pixmap_priv *dst) -{ - int width = dst->tex->width[0]; - int height = dst->tex->height[0]; - const int param_bytes = 8 * sizeof(float); - float vs_consts[8] = { - 2.f/width, 2.f/height, 1, 1, - -1, -1, 0, 0 - }; - - renderer_set_constants(r, PIPE_SHADER_VERTEX, - vs_consts, param_bytes); -} - -static void setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv) { const int param_bytes = 12 * sizeof(float); @@ -446,6 +431,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, Bool hdtv; int x, y, w, h; struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap); + struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst); if (dst && !dst->tex) { xorg_exa_set_shared_usage(pPixmap); @@ -466,13 +452,12 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, pbox = REGION_RECTS(dstRegion); nbox = REGION_NUM_RECTS(dstRegion); - renderer_bind_framebuffer(pPriv->r, dst); - renderer_bind_viewport(pPriv->r, dst); + renderer_bind_destination(pPriv->r, dst_surf, + dst_surf->width, dst_surf->height); + bind_blend_state(pPriv); - renderer_bind_rasterizer(pPriv->r); bind_shaders(pPriv); bind_samplers(pPriv); - setup_vs_video_constants(pPriv->r, dst); setup_fs_video_constants(pPriv->r, hdtv); exaMoveInPixmap(pPixmap); @@ -506,6 +491,8 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, } DamageRegionProcessPending(&pPixmap->drawable); + pipe_surface_reference(&dst_surf, NULL); + return TRUE; } @@ -689,7 +676,7 @@ xorg_setup_textured_adapter(ScreenPtr pScreen) } void -xorg_init_video(ScreenPtr pScreen) +xorg_xv_init(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; /*modesettingPtr ms = modesettingPTR(pScrn);*/ diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index bf9038f356e..8cb73f48970 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -103,9 +103,9 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u /* XXX: Needs to match the drawable's format? */ template.format = PIPE_FORMAT_X8R8G8B8_UNORM; template.last_level = 0; - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; + template.width0 = width; + template.height0 = height; + template.depth0 = 1; pf_get_block(template.format, &template.block); template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index 317dc44d22f..d4978613247 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -24,10 +24,10 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen, tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY; tmpl.target = PIPE_TEXTURE_2D; tmpl.last_level = 0; - tmpl.depth[0] = 1; + tmpl.depth0 = 1; tmpl.format = format; - tmpl.width[0] = width; - tmpl.height[0] = height; + tmpl.width0 = width; + tmpl.height0 = height; pf_get_block(tmpl.format, &tmpl.block); pt = api->texture_from_shared_handle(api, pscreen, &tmpl, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 81cd9dc4fb1..74afffc9cfa 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -317,9 +317,9 @@ struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_co memset(&tmpl, 0, sizeof(tmpl)); tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; tmpl.target = PIPE_TEXTURE_2D; - tmpl.width[0] = w; - tmpl.height[0] = h; - tmpl.depth[0] = 1; + tmpl.width0 = w; + tmpl.height0 = h; + tmpl.depth0 = 1; tmpl.format = format; pf_get_block(tmpl.format, &tmpl.block); tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.c b/src/gallium/winsys/drm/vmware/core/vmw_surface.c index c19e556df9f..64eb32f8b94 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_surface.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.c @@ -37,11 +37,13 @@ vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst, { struct pipe_reference *src_ref; struct pipe_reference *dst_ref; - struct vmw_svga_winsys_surface *dst = *pdst; - + struct vmw_svga_winsys_surface *dst; + if(pdst == NULL || *pdst == src) return; - + + dst = *pdst; + src_ref = src ? &src->refcnt : NULL; dst_ref = dst ? &dst->refcnt : NULL; diff --git a/src/gallium/winsys/drm/vmware/xorg/Makefile b/src/gallium/winsys/drm/vmware/xorg/Makefile index e152263256a..48a9b08aa76 100644 --- a/src/gallium/winsys/drm/vmware/xorg/Makefile +++ b/src/gallium/winsys/drm/vmware/xorg/Makefile @@ -7,7 +7,6 @@ include $(TOP)/configs/current INCLUDES = \ $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \ - -I../gem \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/auxiliary \ @@ -20,19 +19,29 @@ LIBS = \ $(TOP)/src/gallium/drivers/svga/libsvga.a \ $(GALLIUM_AUXILIARIES) +LINKS = \ + $(shell pkg-config --libs --silence-errors libkms) \ + $(shell pkg-config --libs libdrm) + DRIVER_DEFINES = \ -DHAVE_CONFIG_H +TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET) ############################################# -all default: $(TARGET) +all default: $(TARGET) $(TARGET_STAGING) + +$(TARGET): $(OBJECTS) Makefile $(LIBS) + $(MKLIB) -noprefix -o $@ $(OBJECTS) $(LIBS) $(LINKS) + +$(TOP)/$(LIB_DIR)/gallium: + mkdir -p $@ -$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS) - $(TOP)/bin/mklib -noprefix -o $@ \ - $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel +$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium + $(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium clean: rm -rf $(OBJECTS) $(TARGET) diff --git a/src/glu/sgi/libutil/mipmap.c b/src/glu/sgi/libutil/mipmap.c index c5faebd6a35..d1fd5a7d724 100644 --- a/src/glu/sgi/libutil/mipmap.c +++ b/src/glu/sgi/libutil/mipmap.c @@ -3608,6 +3608,7 @@ int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat, glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); + free(newImage); return GLU_OUT_OF_MEMORY; } } @@ -4107,6 +4108,7 @@ static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); + free(srcImage); return GLU_OUT_OF_MEMORY; } /* level userLevel+1 is in srcImage; level userLevel already saved */ @@ -4349,6 +4351,7 @@ static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); + free(srcImage); return GLU_OUT_OF_MEMORY; } } @@ -8098,6 +8101,7 @@ static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat, glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); + free(srcImage); return GLU_OUT_OF_MEMORY; } /* level userLevel+1 is in srcImage; level userLevel already saved */ @@ -8232,6 +8236,7 @@ static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat, glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); + free(srcImage); return GLU_OUT_OF_MEMORY; } } diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index e48e10d7c06..da81ec9de51 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -167,11 +167,12 @@ static int driBindContext(__DRIcontext *pcp, __DRIdrawable *pdp, __DRIdrawable *prp) { - __DRIscreenPrivate *psp = pcp->driScreenPriv; + __DRIscreenPrivate *psp; /* Bind the drawable to the context */ if (pcp) { + psp = pcp->driScreenPriv; pcp->driDrawablePriv = pdp; pcp->driReadablePriv = prp; if (pdp) { @@ -498,11 +499,11 @@ static void dri_put_drawable(__DRIdrawable *pdp) { __DRIscreenPrivate *psp; - pdp->refcount--; - if (pdp->refcount) - return; - if (pdp) { + pdp->refcount--; + if (pdp->refcount) + return; + psp = pdp->driScreenPriv; (*psp->DriverAPI.DestroyBuffer)(pdp); if (pdp->pClipRects) { diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 082d6144425..25418d5f7aa 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -39,6 +39,7 @@ #define I915_FALLBACK_LOGICOP 0x20000 #define I915_FALLBACK_POLYGON_SMOOTH 0x40000 #define I915_FALLBACK_POINT_SMOOTH 0x80000 +#define I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN 0x100000 #define I915_UPLOAD_CTX 0x1 #define I915_UPLOAD_BUFFERS 0x2 diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index b60efea75bd..cc98d125dbc 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -585,7 +585,7 @@ i915PointSize(GLcontext * ctx, GLfloat size) { struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; - GLint point_size = (int) size; + GLint point_size = (int) round(size); DBG("%s\n", __FUNCTION__); @@ -599,6 +599,24 @@ i915PointSize(GLcontext * ctx, GLfloat size) } +static void +i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_POINT_SPRITE_COORD_ORIGIN: + /* This could be supported, but it would require modifying the fragment + * program to invert the y component of the texture coordinate by + * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction. + */ + FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN, + (params[0] != GL_UPPER_LEFT)); + break; + } +} + + /* ============================================================= * Color masks */ @@ -939,6 +957,17 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) case GL_POLYGON_SMOOTH: break; + case GL_POINT_SPRITE: + /* This state change is handled in i915_reduced_primitive_state because + * the hardware bit should only be set when rendering points. + */ + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE; + break; + case GL_POINT_SMOOTH: break; @@ -1108,6 +1137,7 @@ i915InitStateFunctions(struct dd_function_table *functions) functions->LineWidth = i915LineWidth; functions->LogicOpcode = i915LogicOp; functions->PointSize = i915PointSize; + functions->PointParameterfv = i915PointParameterfv; functions->PolygonStipple = i915PolygonStipple; functions->Scissor = i915Scissor; functions->ShadeModel = i915ShadeModel; diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 48685c087b8..8bdda60697b 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -111,6 +111,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, ctx->Const.MaxTextureImageUnits); ctx->Const.MaxVertexTextureImageUnits = 0; /* no vertex shader textures */ + ctx->Const.MaxCombinedTextureImageUnits = 0; /* Mesa limits textures to 4kx4k; it would be nice to fix that someday */ diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 669becdab45..3b7015b5ad3 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -268,6 +268,8 @@ intel_bufferobj_map(GLcontext * ctx, if (intel_obj->sys_buffer) { obj->Pointer = intel_obj->sys_buffer; + obj->Length = obj->Size; + obj->Offset = 0; return obj->Pointer; } diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 7de29e5bb87..25314eff563 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -111,6 +111,7 @@ static const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_crossbar", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, @@ -327,7 +328,6 @@ static void r600InitGLExtensions(GLcontext *ctx) ctx->Extensions.ARB_shader_objects = GL_TRUE; ctx->Extensions.ARB_vertex_shader = GL_TRUE; ctx->Extensions.ARB_fragment_shader = GL_TRUE; - ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE; ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; ctx->Extensions.ATI_separate_stencil = GL_TRUE; diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index 8e57396a0d9..309c90fdd0c 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -1038,7 +1038,8 @@ GLboolean checkop2(r700_AssemblerBase* pAsm) checkop_init(pAsm); - if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[0].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) ) @@ -1049,7 +1050,8 @@ GLboolean checkop2(r700_AssemblerBase* pAsm) { bSrcConst[0] = GL_FALSE; } - if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[1].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) ) @@ -1082,7 +1084,8 @@ GLboolean checkop3(r700_AssemblerBase* pAsm) checkop_init(pAsm); - if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[0].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) ) @@ -1093,7 +1096,8 @@ GLboolean checkop3(r700_AssemblerBase* pAsm) { bSrcConst[0] = GL_FALSE; } - if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[1].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) ) @@ -1104,7 +1108,8 @@ GLboolean checkop3(r700_AssemblerBase* pAsm) { bSrcConst[1] = GL_FALSE; } - if( (pILInst->SrcReg[2].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[2].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[2].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[2].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[2].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[2].File == PROGRAM_STATE_VAR) ) @@ -1218,7 +1223,7 @@ GLboolean assemble_src(r700_AssemblerBase *pAsm, pAsm->S[fld].src.reg = pILInst->SrcReg[src].Index; break; case PROGRAM_INPUT: - setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE); + setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE); pAsm->S[fld].src.rtype = SRC_REG_INPUT; switch (pAsm->currentShaderType) { @@ -1346,6 +1351,7 @@ GLboolean tex_src(r700_AssemblerBase *pAsm) else { switch (pILInst->SrcReg[0].File) { + case PROGRAM_UNIFORM: case PROGRAM_CONSTANT: case PROGRAM_LOCAL_PARAM: case PROGRAM_ENV_PARAM: @@ -2117,7 +2123,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, if( is_gpr(sel) ) { if( GL_FALSE == cycle_for_vector_bank_swizzle(bank_swizzle, src, &cycle) ) - { + { return GL_FALSE; } @@ -2129,7 +2135,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, else { if( GL_FALSE == reserve_gpr(pAsm, sel, chan, cycle) ) - { + { return GL_FALSE; } } @@ -2141,7 +2147,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, if( is_cfile(sel) ) { if( GL_FALSE == reserve_cfile(pAsm, sel, chan) ) - { + { return GL_FALSE; } } @@ -2244,7 +2250,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) current_source_index, pcurrent_source, scalar_channel_index) ) - { + { return GL_FALSE; } @@ -2258,7 +2264,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) current_source_index, pcurrent_source, scalar_channel_index) ) - { + { return GL_FALSE; } } @@ -2287,7 +2293,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) alu_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg; } else - { + { radeon_error("Only temp destination registers supported for ALU dest regs.\n"); return GL_FALSE; } @@ -2401,7 +2407,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) } if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) ) - { + { return GL_FALSE; } @@ -2412,15 +2418,15 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) if (is_single_scalar_operation) { if(GL_FALSE == check_scalar(pAsm, alu_instruction_ptr) ) - { + { return GL_FALSE; } } else { if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) ) - { - return 1; + { + return GL_FALSE; } } @@ -2667,7 +2673,7 @@ GLboolean assemble_alu_instruction2(r700_AssemblerBase *pAsm) { if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) ) { - return 1; + return GL_FALSE; } } @@ -3642,6 +3648,7 @@ GLboolean assemble_LRP(r700_AssemblerBase *pAsm) { return GL_FALSE; } + if( GL_FALSE == assemble_src(pAsm, 2, -1) ) { return GL_FALSE; @@ -4598,6 +4605,7 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) switch (pAsm->pILInst[pAsm->uiCurInst].SrcReg[0].File) { + case PROGRAM_UNIFORM: case PROGRAM_CONSTANT: case PROGRAM_LOCAL_PARAM: case PROGRAM_ENV_PARAM: @@ -5663,6 +5671,8 @@ GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue) pAsm->D2.dst2.literal = 1; pAsm->D2.dst2.SaturateMode = SATURATE_OFF; pAsm->D.dst.predicated = 0; + /* in reloc where dislink flag init inst, only one slot alu inst is handled. */ + pAsm->D.dst.math = 1; /* TODO : not math really, but one channel op, more generic alu assembler needed */ #if 0 pAsm->S[0].src.rtype = SRC_REC_LITERAL; //pAsm->S[0].src.reg = 0; @@ -6457,6 +6467,7 @@ GLboolean AssembleInstr(GLuint uiFirstInst, GLboolean InitShaderProgram(r700_AssemblerBase * pAsm) { setRetInLoopFlag(pAsm, SQ_SEL_0); + pAsm->alu_x_opcode = SQ_CF_INST_ALU; return GL_TRUE; } @@ -6482,7 +6493,7 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm) if(SIT_CF_ALU == pInst->m_ShaderInstType) { pCF_ALU = (R700ControlFlowALUClause *)pInst; - if(1 == pCF_ALU->m_Word1.f.count) + if(0 == pCF_ALU->m_Word1.f.count) { pCF_ALU->m_Word1.f.cf_inst = SQ_CF_INST_NOP; } @@ -6503,14 +6514,14 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm) }; } - if(0 == pAsm->unSubArrayPointer) + if(pAsm->CALLSTACK[0].max > 0) { - return GL_TRUE; + pAsm->pR700Shader->uStackSize = ((pAsm->CALLSTACK[0].max + 3)>>2) + 2; } - if(pAsm->CALLSTACK[0].max > 0) + if(0 == pAsm->unSubArrayPointer) { - pAsm->pR700Shader->uStackSize = ((pAsm->CALLSTACK[0].max + 3)>>2) + 2; + return GL_TRUE; } unCFoffset = plstCFmain->uNumOfNode; @@ -6864,7 +6875,7 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode, export_starting_index++; } } - + for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++) { unBit = 1 << i; @@ -6876,7 +6887,7 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode, 1, pR700AsmCode->ucVP_OutputMap[i], GL_FALSE) ) - { + { return GL_FALSE; } diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c index 21ac46e7b88..e9ef6c86953 100644 --- a/src/mesa/drivers/dri/r600/r700_fragprog.c +++ b/src/mesa/drivers/dri/r600/r700_fragprog.c @@ -44,12 +44,18 @@ //TODO : Validate FP input with VP output. void Map_Fragment_Program(r700_AssemblerBase *pAsm, - struct gl_fragment_program *mesa_fp) + struct gl_fragment_program *mesa_fp, + GLcontext *ctx) { unsigned int unBit; unsigned int i; GLuint ui; + /* match fp inputs with vp exports. */ + struct r700_vertex_program_cont *vpc = + (struct r700_vertex_program_cont *)ctx->VertexProgram._Current; + GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten; + pAsm->number_used_registers = 0; //Input mapping : mesa_fp->Base.InputsRead set the flag, set in @@ -61,41 +67,41 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm, pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS] = pAsm->number_used_registers++; } - unBit = 1 << FRAG_ATTRIB_COL0; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL0; + if(OutputsWritten & unBit) { pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0] = pAsm->number_used_registers++; } - unBit = 1 << FRAG_ATTRIB_COL1; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL1; + if(OutputsWritten & unBit) { pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1] = pAsm->number_used_registers++; } - unBit = 1 << FRAG_ATTRIB_FOGC; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_FOGC; + if(OutputsWritten & unBit) { - pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++; + pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++; } for(i=0; i<8; i++) { - unBit = 1 << (FRAG_ATTRIB_TEX0 + i); - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << (VERT_RESULT_TEX0 + i); + if(OutputsWritten & unBit) { pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i] = pAsm->number_used_registers++; } } -/* order has been taken care of */ +/* order has been taken care of */ #if 1 - for(i=FRAG_ATTRIB_VAR0; i<FRAG_ATTRIB_MAX; i++) - { + for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++) + { unBit = 1 << i; - if(mesa_fp->Base.InputsRead & unBit) + if(OutputsWritten & unBit) { - pAsm->uiFP_AttributeMap[i] = pAsm->number_used_registers++; + pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0] = pAsm->number_used_registers++; } } #else @@ -291,7 +297,8 @@ GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp, } GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp, - struct gl_fragment_program *mesa_fp) + struct gl_fragment_program *mesa_fp, + GLcontext *ctx) { GLuint number_of_colors_exported; GLboolean z_enabled = GL_FALSE; @@ -299,7 +306,7 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp, //Init_Program Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) ); - Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp); + Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx); if( GL_FALSE == Find_Instruction_Dependencies_fp(fp, mesa_fp) ) { @@ -366,7 +373,7 @@ void r700SelectFragmentShader(GLcontext *ctx) } if (GL_FALSE == fp->translated) - r700TranslateFragmentShader(fp, &(fp->mesa_program)); + r700TranslateFragmentShader(fp, &(fp->mesa_program), ctx); } void * r700GetActiveFpShaderBo(GLcontext * ctx) @@ -460,6 +467,9 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) EXPORT_MODE_shift, EXPORT_MODE_mask); // emit ps input map + struct r700_vertex_program_cont *vpc = + (struct r700_vertex_program_cont *)ctx->VertexProgram._Current; + GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten; unBit = 1 << FRAG_ATTRIB_WPOS; if(mesa_fp->Base.InputsRead & unBit) { @@ -473,8 +483,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); } - unBit = 1 << FRAG_ATTRIB_COL0; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL0; + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -486,8 +496,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); } - unBit = 1 << FRAG_ATTRIB_COL1; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL1; + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -499,8 +509,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); } - unBit = 1 << FRAG_ATTRIB_FOGC; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_FOGC; + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -514,8 +524,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) for(i=0; i<8; i++) { - unBit = 1 << (FRAG_ATTRIB_TEX0 + i); - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << (VERT_RESULT_TEX0 + i); + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -525,12 +535,12 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) } } - for(i=FRAG_ATTRIB_VAR0; i<FRAG_ATTRIB_MAX; i++) + for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++) { - unBit = 1 << i; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << i; + if(OutputsWritten & unBit) { - ui = pAsm->uiFP_AttributeMap[i]; + ui = pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui, SEMANTIC_shift, SEMANTIC_mask); @@ -538,8 +548,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); else CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); - } - } + } + } exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift); if (r700->CB_SHADER_CONTROL.u32All != ((1 << exportCount) - 1)) @@ -551,7 +561,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) /* sent out shader constants. */ paramList = fp->mesa_program.Base.Parameters; - if(NULL != paramList) { + if(NULL != paramList) + { _mesa_load_state_parameters(ctx, paramList); if (paramList->NumParameters > R700_MAX_DX9_CONSTS) @@ -564,10 +575,10 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) unNumParamData = paramList->NumParameters; for(ui=0; ui<unNumParamData; ui++) { - r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; - r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; - r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; - r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; + r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; + r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; + r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; + r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; } } else r700->ps.num_consts = 0; diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.h b/src/mesa/drivers/dri/r600/r700_fragprog.h index cbb108d2128..e562bfa4789 100644 --- a/src/mesa/drivers/dri/r600/r700_fragprog.h +++ b/src/mesa/drivers/dri/r600/r700_fragprog.h @@ -49,12 +49,14 @@ struct r700_fragment_program /* Internal */ void Map_Fragment_Program(r700_AssemblerBase *pAsm, - struct gl_fragment_program *mesa_fp); + struct gl_fragment_program *mesa_fp, + GLcontext *ctx); GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp, struct gl_fragment_program *mesa_fp); GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp, - struct gl_fragment_program *mesa_vp); + struct gl_fragment_program *mesa_vp, + GLcontext *ctx); /* Interface */ extern void r700SelectFragmentShader(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index c8f72d588b4..d3d1da79592 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -631,6 +631,12 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) paramList = vp->mesa_program->Base.Parameters; if(NULL != paramList) { + /* vp->mesa_program was cloned, not updated by glsl shader api. */ + /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */ + /* so, use ctx->VertexProgem._Current */ + struct gl_program_parameter_list *paramListOrginal = + paramListOrginal = ctx->VertexProgram._Current->Base.Parameters; + _mesa_load_state_parameters(ctx, paramList); if (paramList->NumParameters > R700_MAX_DX9_CONSTS) @@ -643,10 +649,20 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) unNumParamData = paramList->NumParameters; for(ui=0; ui<unNumParamData; ui++) { - r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; - r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; - r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; - r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; + if(paramList->Parameters[ui].Type == PROGRAM_UNIFORM) + { + r700->vs.consts[ui][0].f32All = paramListOrginal->ParameterValues[ui][0]; + r700->vs.consts[ui][1].f32All = paramListOrginal->ParameterValues[ui][1]; + r700->vs.consts[ui][2].f32All = paramListOrginal->ParameterValues[ui][2]; + r700->vs.consts[ui][3].f32All = paramListOrginal->ParameterValues[ui][3]; + } + else + { + r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; + r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; + r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; + r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; + } } } else r700->vs.num_consts = 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 89a99974e29..b8c65f4ce62 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -205,6 +205,7 @@ again_alloc: counter on unused buffers for later freeing them from begin of list */ dma_bo = last_elem(&rmesa->dma.free); + assert(dma_bo->bo->cref == 1); remove_from_list(dma_bo); insert_at_head(&rmesa->dma.reserved, dma_bo); } @@ -301,10 +302,6 @@ static int radeon_bo_is_idle(struct radeon_bo* bo) WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n" "This may cause small performance drop for you.\n"); } - /* Protect against bug in legacy bo handling that causes bos stay - * referenced even after they should be freed */ - if (bo->cref != 1) - return 0; return ret != -EBUSY; } @@ -341,9 +338,7 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa) foreach_s(dma_bo, temp, &rmesa->dma.wait) { if (dma_bo->expire_counter == time) { WARN_ONCE("Leaking dma buffer object!\n"); - /* force free of buffer so we don't realy start - * leaking stuff now*/ - while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {} + radeon_bo_unref(dma_bo->bo); remove_from_list(dma_bo); FREE(dma_bo); continue; diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 02de8e5fd1d..7ad781ba619 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -62,8 +62,6 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) __DRIdrawablePrivate *const readable = radeon_get_readable(rmesa); __DRIscreenPrivate *sPriv = rmesa->dri.screen; - assert(drawable != NULL); - drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); /* The window might have moved, so we might need to get new clip @@ -74,12 +72,13 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); - if (drawable != readable) { + if (drawable) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (readable && drawable != readable) { DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); } - if (rmesa->lastStamp != drawable->lastStamp) { + if (drawable && (rmesa->lastStamp != drawable->lastStamp)) { radeon_window_moved(rmesa); rmesa->lastStamp = drawable->lastStamp; } diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 46603de2e76..bdbb9460bf0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -68,6 +68,19 @@ static unsigned get_compressed_image_size( return rowStride * ((height + blockHeight - 1) / blockHeight); } +static int find_next_power_of_two(GLuint value) +{ + int i, tmp; + + i = 0; + tmp = value - 1; + while (tmp) { + tmp >>= 1; + i++; + } + return (1 << i); +} + /** * Compute sizes and fill in offset and blit information for the given * image (determined by \p face and \p level). @@ -80,25 +93,28 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree { radeon_mipmap_level *lvl = &mt->levels[level]; uint32_t row_align; + GLuint height; + + height = find_next_power_of_two(lvl->height); /* Find image size in bytes */ if (_mesa_is_format_compressed(mt->mesaFormat)) { lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align); - lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, lvl->height); + lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, height); } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) { row_align = rmesa->texture_rect_row_align - 1; lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align; - lvl->size = lvl->rowstride * lvl->height; + lvl->size = lvl->rowstride * height; } else if (mt->tilebits & RADEON_TXO_MICRO_TILE) { /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, * though the actual offset may be different (if texture is less than * 32 bytes width) to the untiled case */ lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31; - lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth; + lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth; } else { row_align = rmesa->texture_row_align - 1; lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align; - lvl->size = lvl->rowstride * lvl->height * lvl->depth; + lvl->size = lvl->rowstride * height * lvl->depth; } assert(lvl->size > 0); @@ -110,7 +126,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree if (RADEON_DEBUG & RADEON_TEXTURE) fprintf(stderr, "level %d, face %d: rs:%d %dx%d at %d\n", - level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset); + level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset); } static GLuint minify(GLuint size, GLuint levels) @@ -124,20 +140,19 @@ static GLuint minify(GLuint size, GLuint levels) static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt) { - GLuint curOffset; - GLuint i; - GLuint face; + GLuint curOffset, i, face, level; assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels); curOffset = 0; for(face = 0; face < mt->faces; face++) { - for(i = 0; i < mt->numLevels; i++) { - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); - compute_tex_image_offset(rmesa, mt, face, i, &curOffset); + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); } } @@ -147,21 +162,21 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt) { - GLuint curOffset; - GLuint i; + GLuint curOffset, i, level; assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels); curOffset = 0; - for(i = 0; i < mt->numLevels; i++) { + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { GLuint face; - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); for(face = 0; face < mt->faces; face++) - compute_tex_image_offset(rmesa, mt, face, i, &curOffset); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); } /* Note the required size in memory */ @@ -277,18 +292,19 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj, * given face and level. */ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, - struct gl_texture_image *texImage, GLuint face, GLuint mtLevel) + struct gl_texture_image *texImage, GLuint face, GLuint level) { radeon_mipmap_level *lvl; - if (face >= mt->faces || mtLevel > mt->numLevels) + if (face >= mt->faces) return GL_FALSE; if (texImage->TexFormat != mt->mesaFormat) return GL_FALSE; - lvl = &mt->levels[mtLevel]; - if (lvl->width != texImage->Width || + lvl = &mt->levels[level]; + if (!lvl->valid || + lvl->width != texImage->Width || lvl->height != texImage->Height || lvl->depth != texImage->Depth) return GL_FALSE; @@ -394,38 +410,17 @@ radeon_miptree_image_offset(radeon_mipmap_tree *mt, } /** - * Convert radeon miptree texture level to GL texture level - * @param[in] tObj texture object whom level is to be converted - * @param[in] level radeon miptree texture level - * @return GL texture level - */ -unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level) -{ - return level + tObj->BaseLevel; -} - -/** - * Convert GL texture level to radeon miptree texture level - * @param[in] tObj texture object whom level is to be converted - * @param[in] level GL texture level - * @return radeon miptree texture level - */ -unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level) -{ - return level - tObj->BaseLevel; -} - -/** * Ensure that the given image is stored in the given miptree from now on. */ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, - int face, int mtLevel) + int face, int level) { - radeon_mipmap_level *dstlvl = &mt->levels[mtLevel]; + radeon_mipmap_level *dstlvl = &mt->levels[level]; unsigned char *dest; assert(image->mt != mt); + assert(dstlvl->valid); assert(dstlvl->width == image->base.Width); assert(dstlvl->height == image->base.Height); assert(dstlvl->depth == image->base.Depth); @@ -442,6 +437,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; + assert(image->mtlevel == level); assert(srclvl->size == dstlvl->size); assert(srclvl->rowstride == dstlvl->rowstride); @@ -479,7 +475,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_miptree_reference(mt, &image->mt); image->mtface = face; - image->mtlevel = mtLevel; + image->mtlevel = level; } /** @@ -506,7 +502,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, if (!img) break; - if (!img->mt || !radeon_miptree_matches_texture(img->mt, &texObj->base)) + if (!img->mt) continue; for (int i = 0; i < mtCount; ++i) { @@ -517,8 +513,8 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, } } - if (!found) { - mtSizes[mtCount] += img->mt->levels[img->mtlevel].size; + if (!found && radeon_miptree_matches_texture(img->mt, &texObj->base)) { + mtSizes[mtCount] = img->mt->levels[img->mtlevel].size; mts[mtCount] = img->mt; mtCount++; } @@ -576,6 +572,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); dst_miptree = t->mt; + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt); + } + } else if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt); } const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; @@ -594,7 +595,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t if (RADEON_DEBUG & RADEON_TEXTURE) { fprintf(stderr, "MIGRATING\n"); } - migrate_image_to_miptree(dst_miptree, img, face, radeon_gl_level_to_miptree_level(texObj, level)); + struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; + if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + migrate_image_to_miptree(dst_miptree, img, face, level); } else if (RADEON_DEBUG & RADEON_TEXTURE) { fprintf(stderr, "OK\n"); } diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index 28b84850954..a10649b5aea 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -44,6 +44,7 @@ struct _radeon_mipmap_level { GLuint depth; GLuint size; /** Size of each image, in bytes */ GLuint rowstride; /** in bytes */ + GLuint valid; radeon_mipmap_image faces[6]; }; @@ -70,9 +71,9 @@ struct _radeon_mipmap_tree { GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */ GLuint numLevels; /** Number of mip levels stored in this mipmap tree */ - GLuint width0; /** Width of firstLevel image */ - GLuint height0; /** Height of firstLevel image */ - GLuint depth0; /** Depth of firstLevel image */ + GLuint width0; /** Width of baseLevel image */ + GLuint height0; /** Height of baseLevel image */ + GLuint depth0; /** Depth of baseLevel image */ GLuint tilebits; /** RADEON_TXO_xxx_TILE */ @@ -89,8 +90,5 @@ GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level); void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); -unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level); -unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level); - uint32_t get_base_teximage_offset(radeonTexObj *texObj); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 1ee9e2792a5..0390d376ba2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -509,6 +509,27 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, return MESA_FORMAT_NONE; /* never get here */ } +/** Check if given image is valid within current texture object. + */ +static int image_matches_texture_obj(struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + unsigned level) +{ + const struct gl_texture_image *baseImage = texObj->Image[0][level]; + + if (level < texObj->BaseLevel || level > texObj->MaxLevel) + return 0; + + const unsigned levelDiff = level - texObj->BaseLevel; + const unsigned refWidth = baseImage->Width >> levelDiff; + const unsigned refHeight = baseImage->Height >> levelDiff; + const unsigned refDepth = baseImage->Depth >> levelDiff; + + return (texImage->Width == refWidth && + texImage->Height == refHeight && + texImage->Depth == refDepth); +} + static void teximage_assign_miptree(radeonContextPtr rmesa, struct gl_texture_object *texObj, struct gl_texture_image *texImage, @@ -518,18 +539,28 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, radeonTexObj *t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); + /* Since miptree holds only images for levels <BaseLevel..MaxLevel> + * don't allocate the miptree if the teximage won't fit. + */ + if (!image_matches_texture_obj(texObj, texImage, level)) + return; + /* Try using current miptree, or create new if there isn't any */ - if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, - radeon_gl_level_to_miptree_level(texObj, level))) { + if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " + "texObj miptree doesn't match, allocated new miptree %p\n", + __FUNCTION__, texObj, texImage, face, level, t->mt); + } } /* Miptree alocation may have failed, * when there was no image for baselevel specified */ if (t->mt) { image->mtface = face; - image->mtlevel = radeon_gl_level_to_miptree_level(texObj, level); + image->mtlevel = level; radeon_miptree_reference(t->mt, &image->mt); } } @@ -585,6 +616,8 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); } + assert(dstRowStride); + if (dims == 3) { unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); @@ -670,6 +703,11 @@ static void radeon_teximage( } } + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", + dims, texObj, texImage, face, level); + } + t->validated = GL_FALSE; if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { @@ -694,12 +732,17 @@ static void radeon_teximage( if (!t->bo) { teximage_assign_miptree(rmesa, texObj, texImage, face, level); - if (!t->mt) { + if (!image->mt) { int size = _mesa_format_image_size(texImage->TexFormat, texImage->Width, texImage->Height, texImage->Depth); texImage->Data = _mesa_alloc_texmemory(size); + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " + " no miptree assigned, using local memory %p\n", + dims, texObj, texImage, texImage->Data); + } } } @@ -801,6 +844,11 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve } } + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", + dims, texObj, texImage, radeon_face_for_target(target), level); + } + t->validated = GL_FALSE; if (compressed) { pixels = _mesa_validate_pbo_compressed_teximage( diff --git a/src/mesa/drivers/dri/swrast/swrast_span.c b/src/mesa/drivers/dri/swrast/swrast_span.c index 2d3c25dcbef..f8e503463fa 100644 --- a/src/mesa/drivers/dri/swrast/swrast_span.c +++ b/src/mesa/drivers/dri/swrast/swrast_span.c @@ -63,56 +63,42 @@ static const GLubyte kernel[16] = { /* 32-bit BGRA */ #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = VALUE[ACOMP]; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = VALUE[ACOMP] << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = 0xff; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \ - DST[ACOMP] = SRC[3]; \ - DST[RCOMP] = SRC[2]; \ - DST[GCOMP] = SRC[1]; \ - DST[BCOMP] = SRC[0] + DST[ACOMP] = *SRC >> 24; \ + DST[RCOMP] = (*SRC >> 16) & 0xff; \ + DST[GCOMP] = (*SRC >> 8) & 0xff; \ + DST[BCOMP] = *SRC & 0xff /* 32-bit BGRX */ #define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = 0xff; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = 0xff; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define FETCH_PIXEL_X8R8G8B8(DST, SRC) \ - DST[ACOMP] = 0xff; \ - DST[RCOMP] = SRC[2]; \ - DST[GCOMP] = SRC[1]; \ - DST[BCOMP] = SRC[0] + DST[ACOMP] = 0xff; \ + DST[RCOMP] = (*SRC >> 16) & 0xff; \ + DST[GCOMP] = (*SRC >> 8) & 0xff; \ + DST[BCOMP] = *SRC & 0xff /* 16-bit BGR */ #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \ do { \ int d = DITHER_COMP(X, Y) >> 6; \ - GLushort *p = (GLushort *)DST; \ - *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \ - ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \ - ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \ + *DST = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \ + ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \ + ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \ } while(0) #define FETCH_PIXEL_R5G6B5(DST, SRC) \ do { \ - GLushort p = *(GLushort *)SRC; \ DST[ACOMP] = 0xff; \ - DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ - DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ - DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + DST[RCOMP] = ((*SRC >> 8) & 0xf8) * 255 / 0xf8; \ + DST[GCOMP] = ((*SRC >> 3) & 0xfc) * 255 / 0xfc; \ + DST[BCOMP] = ((*SRC << 3) & 0xf8) * 255 / 0xf8; \ } while(0) @@ -145,8 +131,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X) +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -163,8 +149,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X); +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -181,8 +167,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2; -#define INC_PIXEL_PTR(P) P += 2 + GLushort *P = (GLushort *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 2 + (X); +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) #define FETCH_PIXEL(DST, SRC) \ @@ -234,8 +220,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)row; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)row; +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -252,8 +238,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)row; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)row; +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -270,7 +256,7 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)row; + GLushort *P = (GLushort *)row; #define INC_PIXEL_PTR(P) P += 2 #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h index 380663ec971..87c3b2e5621 100644 --- a/src/mesa/main/compiler.h +++ b/src/mesa/main/compiler.h @@ -234,7 +234,12 @@ extern "C" { #elif defined(__APPLE__) #include <CoreFoundation/CFByteOrder.h> #define CPU_TO_LE32( x ) CFSwapInt32HostToLittle( x ) -#else /*__linux__ __APPLE__*/ +#elif defined(_AIX) +#define CPU_TO_LE32( x ) x = ((x & 0x000000ff) << 24) | \ + ((x & 0x0000ff00) << 8) | \ + ((x & 0x00ff0000) >> 8) | \ + ((x & 0xff000000) >> 24); +#else /*__linux__ */ #include <sys/endian.h> #define CPU_TO_LE32( x ) bswap32( x ) #endif /*__linux__*/ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b5bf46718f7..03fc57e6654 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -575,6 +575,7 @@ _mesa_init_constants(GLcontext *ctx) #if FEATURE_ARB_vertex_shader ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; ctx->Const.MaxVarying = MAX_VARYING; #endif diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 6c5ce029135..e8932f83b6a 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1876,7 +1876,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxCombinedTextureImageUnits); break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetBooleanv"); @@ -3711,7 +3711,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + params[0] = (GLfloat)(ctx->Const.MaxCombinedTextureImageUnits); break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetFloatv"); @@ -5546,7 +5546,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS; + params[0] = ctx->Const.MaxCombinedTextureImageUnits; break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetIntegerv"); @@ -7382,7 +7382,7 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetInteger64v"); - params[0] = (GLint64)(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + params[0] = (GLint64)(ctx->Const.MaxCombinedTextureImageUnits); break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetInteger64v"); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index 930c3362fae..a29962d3348 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -1006,7 +1006,7 @@ StateVars = [ ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, - ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxCombinedTextureImageUnits"], "", ["ARB_vertex_shader"] ), # GL_ARB_shader_objects # Actually, this token isn't part of GL_ARB_shader_objects, but is diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 881d233ca3d..5f012448275 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2319,6 +2319,7 @@ struct gl_constants GLuint MaxTextureCoordUnits; GLuint MaxTextureImageUnits; GLuint MaxVertexTextureImageUnits; + GLuint MaxCombinedTextureImageUnits; GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */ GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 4c8fc1f72e0..b3305448904 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -200,7 +200,12 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params) } break; case GL_POINT_SPRITE_COORD_ORIGIN: - if (ctx->Extensions.ARB_point_sprite || ctx->Extensions.NV_point_sprite) { + /* This is not completely correct. GL_POINT_SPRITE_COORD_ORIGIN was + * added to point sprites when the extension was merged into OpenGL + * 2.0. It is expected that an implementation supporting OpenGL 1.4 + * and GL_ARB_point_sprite will generate an error here. + */ + if (ctx->Extensions.ARB_point_sprite) { GLenum value = (GLenum) params[0]; if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) { _mesa_error(ctx, GL_INVALID_VALUE, diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c index 6d86a4275cc..4442fb8cf8e 100644 --- a/src/mesa/main/texenv.c +++ b/src/mesa/main/texenv.c @@ -598,7 +598,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) void GLAPIENTRY _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) { - _mesa_TexEnvfv( target, pname, ¶m ); + GLfloat p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0.0; + _mesa_TexEnvfv( target, pname, p ); } diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c index 733e129fcfe..5abb1ff0ab6 100644 --- a/src/mesa/main/texgen.c +++ b/src/mesa/main/texgen.c @@ -211,14 +211,20 @@ _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) static void GLAPIENTRY _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) { - _mesa_TexGenfv(coord, pname, ¶m); + GLfloat p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0.0F; + _mesa_TexGenfv(coord, pname, p); } void GLAPIENTRY _mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) { - _mesa_TexGeniv( coord, pname, ¶m ); + GLint p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0; + _mesa_TexGeniv( coord, pname, p ); } diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index ab170cde35b..310d594cd55 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -547,13 +547,20 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) case GL_DEPTH_TEXTURE_MODE_ARB: { /* convert float param to int */ - GLint p = (GLint) param; - need_update = set_tex_parameteri(ctx, texObj, pname, &p); + GLint p[4]; + p[0] = (GLint) param; + p[1] = p[2] = p[3] = 0; + need_update = set_tex_parameteri(ctx, texObj, pname, p); } break; default: - /* this will generate an error if pname is illegal */ - need_update = set_tex_parameterf(ctx, texObj, pname, ¶m); + { + /* this will generate an error if pname is illegal */ + GLfloat p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0.0F; + need_update = set_tex_parameterf(ctx, texObj, pname, p); + } } if (ctx->Driver.TexParameter && need_update) { diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index 0e89a624c4e..73df44d1988 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -46,7 +46,8 @@ static const struct st_tracked_state *atoms[] = &st_update_clip, &st_finalize_textures, - &st_update_shader, + &st_update_fp, + &st_update_vp, &st_update_rasterizer, &st_update_polygon_stipple, diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index c7cffd85c8a..f34b49203b2 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -47,7 +47,8 @@ void st_validate_state( struct st_context *st ); extern const struct st_tracked_state st_update_framebuffer; extern const struct st_tracked_state st_update_clip; extern const struct st_tracked_state st_update_depth_stencil_alpha; -extern const struct st_tracked_state st_update_shader; +extern const struct st_tracked_state st_update_fp; +extern const struct st_tracked_state st_update_vp; extern const struct st_tracked_state st_update_rasterizer; extern const struct st_tracked_state st_update_polygon_stipple; extern const struct st_tracked_state st_update_viewport; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index e18c0f6e0a1..8ca4335e330 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -40,6 +40,7 @@ #include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_rect.h" +#include "util/u_math.h" @@ -64,8 +65,8 @@ update_renderbuffer_surface(struct st_context *st, GLuint level; /* find matching mipmap level size */ for (level = 0; level <= texture->last_level; level++) { - if (texture->width[level] == rtt_width && - texture->height[level] == rtt_height) { + if (u_minify(texture->width0, level) == rtt_width && + u_minify(texture->height0, level) == rtt_height) { pipe_surface_reference(&strb->surface, NULL); diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index babfcc87b4a..4b35f59cc2f 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -145,7 +145,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) const GLuint gSize = ctx->PixelMaps.GtoG.Size; const GLuint bSize = ctx->PixelMaps.BtoB.Size; const GLuint aSize = ctx->PixelMaps.AtoA.Size; - const uint texSize = pt->width[0]; + const uint texSize = pt->width0; uint *dest; uint i, j; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 6611956ae83..d6e3a3e5610 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -229,14 +229,23 @@ update_samplers(struct st_context *st) /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, sampler); + if (su < st->ctx->Const.MaxVertexTextureImageUnits) { + cso_single_vertex_sampler(st->cso_context, su, sampler); + } } else { /*printf("%s su=%u null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, NULL); + if (su < st->ctx->Const.MaxVertexTextureImageUnits) { + cso_single_vertex_sampler(st->cso_context, su, NULL); + } } } cso_single_sampler_done(st->cso_context); + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + cso_single_vertex_sampler_done(st->cso_context); + } } diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 6e311e537ef..09baff875bc 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -56,82 +56,18 @@ #include "st_mesa_to_tgsi.h" -/** - * This represents a vertex program, especially translated to match - * the inputs of a particular fragment shader. - */ -struct translated_vertex_program -{ - struct st_vertex_program *master; - - /** The fragment shader "signature" this vertex shader is meant for: */ - GLbitfield frag_inputs; - /** Compared against master vertex program's serialNo: */ - GLuint serialNo; - /** Maps VERT_RESULT_x to slot */ - GLuint output_to_slot[VERT_RESULT_MAX]; - ubyte output_to_semantic_name[VERT_RESULT_MAX]; - ubyte output_to_semantic_index[VERT_RESULT_MAX]; - - /** Pointer to the translated vertex program */ - struct st_vertex_program *vp; - - struct translated_vertex_program *next; /**< next in linked list */ -}; - - -/** - * Given a vertex program output attribute, return the corresponding - * fragment program input attribute. - * \return -1 for vertex outputs that have no corresponding fragment input +/* + * Translate fragment program if needed. */ -static GLint -vp_out_to_fp_in(GLuint vertResult) -{ - if (vertResult >= VERT_RESULT_TEX0 && - vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS) - return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0); - - if (vertResult >= VERT_RESULT_VAR0 && - vertResult < VERT_RESULT_VAR0 + MAX_VARYING) - return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0); - - switch (vertResult) { - case VERT_RESULT_HPOS: - return FRAG_ATTRIB_WPOS; - case VERT_RESULT_COL0: - return FRAG_ATTRIB_COL0; - case VERT_RESULT_COL1: - return FRAG_ATTRIB_COL1; - case VERT_RESULT_FOGC: - return FRAG_ATTRIB_FOGC; - default: - /* Back-face colors, edge flags, etc */ - return -1; - } -} - - -/** - * Find a translated vertex program that corresponds to stvp and - * has outputs matched to stfp's inputs. - * This performs vertex and fragment translation (to TGSI) when needed. - */ -static struct translated_vertex_program * -find_translated_vp(struct st_context *st, - struct st_vertex_program *stvp, - struct st_fragment_program *stfp) +static void +translate_fp(struct st_context *st, + struct st_fragment_program *stfp) { - static const GLuint UNUSED = ~0; - struct translated_vertex_program *xvp; const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead; - /* - * Translate fragment program if needed. - */ if (!stfp->state.tokens) { GLuint inAttr, numIn = 0; @@ -141,7 +77,7 @@ find_translated_vp(struct st_context *st, numIn++; } else { - stfp->input_to_slot[inAttr] = UNUSED; + stfp->input_to_slot[inAttr] = -1; } } @@ -151,170 +87,63 @@ find_translated_vp(struct st_context *st, st_translate_fragment_program(st, stfp, stfp->input_to_slot); } +} - /* See if we've got a translated vertex program whose outputs match - * the fragment program's inputs. - * XXX This could be a hash lookup, using InputsRead as the key. - */ - for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) { - if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) { - break; - } - } - /* No? Allocate translated vp object now */ - if (!xvp) { - xvp = ST_CALLOC_STRUCT(translated_vertex_program); - xvp->frag_inputs = fragInputsRead; - xvp->master = stvp; +/** + * Find a translated vertex program that corresponds to stvp and + * has outputs matched to stfp's inputs. + * This performs vertex and fragment translation (to TGSI) when needed. + */ +static struct st_vp_varient * +find_translated_vp(struct st_context *st, + struct st_vertex_program *stvp ) +{ + struct st_vp_varient *vpv; + struct st_vp_varient_key key; - xvp->next = stfp->vertex_programs; - stfp->vertex_programs = xvp; - } + /* Nothing in our key yet. This will change: + */ + memset(&key, 0, sizeof key); + key.dummy = 0; - /* See if we need to translate vertex program to TGSI form */ - if (xvp->serialNo != stvp->serialNo) { - GLuint outAttr; - const GLbitfield64 outputsWritten = stvp->Base.Base.OutputsWritten; - GLuint numVpOuts = 0; - GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE; - GLbitfield usedGenerics = 0x0; - GLbitfield usedOutputSlots = 0x0; - - /* Compute mapping of vertex program outputs to slots, which depends - * on the fragment program's input->slot mapping. + /* Do we need to throw away old translations after a change in the + * GL program string? + */ + if (stvp->serialNo != stvp->lastSerialNo) { + /* These may have changed if the program string changed. */ - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - /* set defaults: */ - xvp->output_to_slot[outAttr] = UNUSED; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT; - xvp->output_to_semantic_index[outAttr] = 99; - - if (outAttr == VERT_RESULT_HPOS) { - /* always put xformed position into slot zero */ - GLuint slot = 0; - xvp->output_to_slot[VERT_RESULT_HPOS] = slot; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION; - xvp->output_to_semantic_index[outAttr] = 0; - numVpOuts++; - usedOutputSlots |= (1 << slot); - } - else if (outputsWritten & (1 << outAttr)) { - /* see if the frag prog wants this vert output */ - GLint fpInAttrib = vp_out_to_fp_in(outAttr); - if (fpInAttrib >= 0) { - GLuint fpInSlot = stfp->input_to_slot[fpInAttrib]; - if (fpInSlot != ~0) { - /* match this vp output to the fp input */ - GLuint vpOutSlot = stfp->input_map[fpInSlot]; - xvp->output_to_slot[outAttr] = vpOutSlot; - xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot]; - xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot]; - numVpOuts++; - usedOutputSlots |= (1 << vpOutSlot); - } - else { -#if 0 /*debug*/ - printf("VP output %d not used by FP\n", outAttr); -#endif - } - } - else if (outAttr == VERT_RESULT_PSIZ) - emitPntSize = GL_TRUE; - else if (outAttr == VERT_RESULT_BFC0) - emitBFC0 = GL_TRUE; - else if (outAttr == VERT_RESULT_BFC1) - emitBFC1 = GL_TRUE; - } -#if 0 /*debug*/ - printf("assign vp output_to_slot[%d] = %d\n", outAttr, - xvp->output_to_slot[outAttr]); -#endif - } - - /* must do these last */ - if (emitPntSize) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_PSIZ] = slot; - xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE; - xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0; - usedOutputSlots |= (1 << slot); - } - if (emitBFC0) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_BFC0] = slot; - xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0; - usedOutputSlots |= (1 << slot); - } - if (emitBFC1) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_BFC1] = slot; - xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1; - usedOutputSlots |= (1 << slot); - } - - /* build usedGenerics mask */ - usedGenerics = 0x0; - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) { - usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]); - } - } + st_prepare_vertex_program( st, stvp ); - /* For each vertex program output that doesn't match up to a fragment - * program input, map the vertex program output to a free slot and - * free generic attribute. + /* We are now up-to-date: */ - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - if (outputsWritten & (1 << outAttr)) { - if (xvp->output_to_slot[outAttr] == UNUSED) { - GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1; - GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1; - usedGenerics |= (1 << freeGeneric); - usedOutputSlots |= (1 << freeSlot); - xvp->output_to_slot[outAttr] = freeSlot; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC; - xvp->output_to_semantic_index[outAttr] = freeGeneric; - } - } - -#if 0 /*debug*/ - printf("vp output_to_slot[%d] = %d\n", outAttr, - xvp->output_to_slot[outAttr]); -#endif + stvp->lastSerialNo = stvp->serialNo; + } + + /* See if we've got a translated vertex program whose outputs match + * the fragment program's inputs. + */ + for (vpv = stvp->varients; vpv; vpv = vpv->next) { + if (memcmp(&vpv->key, &key, sizeof key) == 0) { + break; } + } - assert(stvp->Base.Base.NumInstructions > 1); - - st_translate_vertex_program(st, stvp, xvp->output_to_slot, - xvp->output_to_semantic_name, - xvp->output_to_semantic_index); - - xvp->vp = stvp; - - /* translated VP is up to date now */ - xvp->serialNo = stvp->serialNo; + /* No? Perform new translation here. */ + if (!vpv) { + vpv = st_translate_vertex_program(st, stvp, &key); + if (!vpv) + return NULL; + + vpv->next = stvp->varients; + stvp->varients = vpv; } - return xvp; + return vpv; } -void -st_free_translated_vertex_programs(struct st_context *st, - struct translated_vertex_program *xvp) -{ - struct translated_vertex_program *next; - - while (xvp) { - next = xvp->next; - _mesa_free(xvp); - xvp = next; - } -} static void * @@ -328,32 +157,19 @@ get_passthrough_fs(struct st_context *st) return st->passthrough_fs; } - static void -update_linkage( struct st_context *st ) +update_fp( struct st_context *st ) { - struct st_vertex_program *stvp; struct st_fragment_program *stfp; - struct translated_vertex_program *xvp; - - /* find active shader and params -- Should be covered by - * ST_NEW_VERTEX_PROGRAM - */ - assert(st->ctx->VertexProgram._Current); - stvp = st_vertex_program(st->ctx->VertexProgram._Current); - assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); assert(st->ctx->FragmentProgram._Current); stfp = st_fragment_program(st->ctx->FragmentProgram._Current); assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); - xvp = find_translated_vp(st, stvp, stfp); + translate_fp(st, stfp); - st_reference_vertprog(st, &st->vp, stvp); st_reference_fragprog(st, &st->fp, stfp); - cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); - if (st->missing_textures) { /* use a pass-through frag shader that uses no textures */ void *fs = get_passthrough_fs(st); @@ -362,16 +178,48 @@ update_linkage( struct st_context *st ) else { cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); } +} + +const struct st_tracked_state st_update_fp = { + "st_update_fp", /* name */ + { /* dirty */ + 0, /* mesa */ + ST_NEW_FRAGMENT_PROGRAM /* st */ + }, + update_fp /* update */ +}; + + + + +static void +update_vp( struct st_context *st ) +{ + struct st_vertex_program *stvp; + + /* find active shader and params -- Should be covered by + * ST_NEW_VERTEX_PROGRAM + */ + assert(st->ctx->VertexProgram._Current); + stvp = st_vertex_program(st->ctx->VertexProgram._Current); + assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); + + st->vp_varient = find_translated_vp(st, stvp); + + st_reference_vertprog(st, &st->vp, stvp); + + cso_set_vertex_shader_handle(st->cso_context, + st->vp_varient->driver_shader); - st->vertex_result_to_slot = xvp->output_to_slot; + st->vertex_result_to_slot = stvp->result_to_output; } -const struct st_tracked_state st_update_shader = { - "st_update_shader", /* name */ +const struct st_tracked_state st_update_vp = { + "st_update_vp", /* name */ { /* dirty */ 0, /* mesa */ - ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM /* st */ + ST_NEW_VERTEX_PROGRAM /* st */ }, - update_linkage /* update */ + update_vp /* update */ }; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 4d4f97da7ed..0b68447d212 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -32,6 +32,8 @@ */ +#include "main/macros.h" + #include "st_context.h" #include "st_atom.h" #include "st_texture.h" @@ -99,6 +101,12 @@ update_textures(struct st_context *st) cso_set_sampler_textures(st->cso_context, st->state.num_textures, st->state.sampler_texture); + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + cso_set_vertex_sampler_textures(st->cso_context, + MIN2(st->state.num_textures, + st->ctx->Const.MaxVertexTextureImageUnits), + st->state.sampler_texture); + } } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 1960d171bf6..1bdeaccda3e 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -169,11 +169,6 @@ make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex) stfp = (struct st_fragment_program *) p; stfp->Base.UsesKill = GL_TRUE; - /* No need to send this incomplete program down to hardware: - * - * st_translate_fragment_program(ctx->st, stfp, NULL); - */ - return stfp; } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 1d33e81c2c9..03617b7a939 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -60,6 +60,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "tgsi/tgsi_ureg.h" #include "util/u_tile.h" #include "util/u_draw_quad.h" #include "util/u_math.h" @@ -236,78 +237,41 @@ make_fragment_shader_z(struct st_context *st) * Create a simple vertex shader that just passes through the * vertex position and texcoord (and optionally, color). */ -static struct st_vertex_program * -st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor) +static void * +st_make_passthrough_vertex_shader(struct st_context *st, + GLboolean passColor) { - GLcontext *ctx = st->ctx; - struct st_vertex_program *stvp; - struct gl_program *p; - GLuint ic = 0; - - if (st->drawpix.vert_shaders[passColor]) - return st->drawpix.vert_shaders[passColor]; - - /* - * Create shader now - */ - p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); - if (!p) - return NULL; - - if (passColor) - p->NumInstructions = 4; - else - p->NumInstructions = 3; - - p->Instructions = _mesa_alloc_instructions(p->NumInstructions); - if (!p->Instructions) { - ctx->Driver.DeleteProgram(ctx, p); - return NULL; - } - _mesa_init_instructions(p->Instructions, p->NumInstructions); - /* MOV result.pos, vertex.pos; */ - p->Instructions[0].Opcode = OPCODE_MOV; - p->Instructions[0].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[0].DstReg.Index = VERT_RESULT_HPOS; - p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[0].SrcReg[0].Index = VERT_ATTRIB_POS; - /* MOV result.texcoord0, vertex.texcoord0; */ - p->Instructions[1].Opcode = OPCODE_MOV; - p->Instructions[1].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[1].DstReg.Index = VERT_RESULT_TEX0; - p->Instructions[1].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[1].SrcReg[0].Index = VERT_ATTRIB_TEX0; - ic = 2; - if (passColor) { - /* MOV result.color0, vertex.color0; */ - p->Instructions[ic].Opcode = OPCODE_MOV; - p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[ic].DstReg.Index = VERT_RESULT_COL0; - p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[ic].SrcReg[0].Index = VERT_ATTRIB_COLOR0; - ic++; - } - - /* END; */ - p->Instructions[ic].Opcode = OPCODE_END; - ic++; - - assert(ic == p->NumInstructions); + if (!st->drawpix.vert_shaders[passColor]) { + struct ureg_program *ureg = + ureg_create( TGSI_PROCESSOR_VERTEX ); + + if (ureg == NULL) + return NULL; + + /* MOV result.pos, vertex.pos; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), + ureg_DECL_vs_input( ureg, 0 )); + + /* MOV result.texcoord0, vertex.texcoord0; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), + ureg_DECL_vs_input( ureg, 1 )); + + if (passColor) { + /* MOV result.color0, vertex.color0; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), + ureg_DECL_vs_input( ureg, 2 )); + } - p->InputsRead = VERT_BIT_POS | VERT_BIT_TEX0; - p->OutputsWritten = ((1 << VERT_RESULT_TEX0) | - (1 << VERT_RESULT_HPOS)); - if (passColor) { - p->InputsRead |= VERT_BIT_COLOR0; - p->OutputsWritten |= (1 << VERT_RESULT_COL0); + ureg_END( ureg ); + + st->drawpix.vert_shaders[passColor] = + ureg_create_shader_and_destroy( ureg, st->pipe ); } - stvp = (struct st_vertex_program *) p; - st_translate_vertex_program(st, stvp, NULL, NULL, NULL); - - st->drawpix.vert_shaders[passColor] = stvp; - - return stvp; + return st->drawpix.vert_shaders[passColor]; } @@ -539,8 +503,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, GLfloat zoomX, GLfloat zoomY, struct pipe_texture *pt, - struct st_vertex_program *stvp, - struct st_fragment_program *stfp, + void *driver_vp, + void *driver_fp, const GLfloat *color, GLboolean invertTex) { @@ -575,10 +539,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* fragment shader state: TEX lookup program */ - cso_set_fragment_shader_handle(cso, stfp->driver_shader); + cso_set_fragment_shader_handle(cso, driver_fp); /* vertex shader state: position + texcoord pass-through */ - cso_set_vertex_shader_handle(cso, stvp->driver_shader); + cso_set_vertex_shader_handle(cso, driver_vp); /* texture sampling state: */ @@ -621,10 +585,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, struct pipe_texture *textures[2]; textures[0] = pt; textures[1] = st->pixel_xfer.pixelmap_texture; - pipe->set_sampler_textures(pipe, 2, textures); + pipe->set_fragment_sampler_textures(pipe, 2, textures); } else { - pipe->set_sampler_textures(pipe, 1, &pt); + pipe->set_fragment_sampler_textures(pipe, 1, &pt); } /* Compute window coords (y=0=bottom) with pixel zoom. @@ -637,8 +601,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, y1 = y + height * ctx->Pixel.ZoomY; draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, - (GLfloat) width / pt->width[0], - (GLfloat) height / pt->height[0]); + (GLfloat) width / pt->width0, + (GLfloat) height / pt->height0); /* restore state */ cso_restore_rasterizer(cso); @@ -806,7 +770,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { struct st_fragment_program *stfp; - struct st_vertex_program *stvp; + void *driver_vp; struct st_context *st = st_context(ctx); struct pipe_surface *ps; const GLfloat *color; @@ -826,13 +790,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (format == GL_DEPTH_COMPONENT) { ps = st->state.framebuffer.zsbuf; stfp = make_fragment_shader_z(st); - stvp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); color = ctx->Current.RasterColor; } else { ps = st->state.framebuffer.cbufs[0]; stfp = combined_drawpix_fragment_program(ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); color = NULL; } @@ -843,7 +807,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (pt) { draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, stvp, stfp, color, GL_FALSE); + pt, + driver_vp, + stfp->driver_shader, + color, GL_FALSE); pipe_texture_reference(&pt, NULL); } } @@ -960,7 +927,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *rbRead; - struct st_vertex_program *stvp; + void *driver_vp; struct st_fragment_program *stfp; struct pipe_texture *pt; GLfloat *color; @@ -1009,14 +976,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, rbRead = st_get_color_read_renderbuffer(ctx); color = NULL; stfp = combined_drawpix_fragment_program(ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); } else { assert(type == GL_DEPTH); rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; stfp = make_fragment_shader_z(st); - stvp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); } srcFormat = rbRead->texture->format; @@ -1148,7 +1115,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* draw textured quad */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, stvp, stfp, color, GL_TRUE); + pt, + driver_vp, + stfp->driver_shader, + color, GL_TRUE); pipe_texture_reference(&pt, NULL); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 65ce12ccd4f..659a6c91938 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -128,9 +128,9 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, template.target = PIPE_TEXTURE_2D; template.format = format; pf_get_block(format, &template.block); - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; + template.width0 = width; + template.height0 = height; + template.depth0 = 1; template.last_level = 0; template.nr_samples = rb->NumSamples; if (pf_is_depth_stencil(format)) { @@ -376,7 +376,7 @@ st_render_texture(GLcontext *ctx, rb->_BaseFormat = texImage->_BaseFormat; /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/ - /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/ + /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/ pipe_texture_reference( &strb->texture, pt ); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index b2d5c39a3a0..8c276f8128e 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -138,24 +138,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } - - if (stvp->draw_shader) { -#if FEATURE_feedback || FEATURE_drawpix - /* this would only have been allocated for the RasterPos path */ - draw_delete_vertex_shader(st->draw, stvp->draw_shader); - stvp->draw_shader = NULL; -#endif - } - - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } + st_vp_release_varients( st, stvp ); } break; case GL_FRAGMENT_PROGRAM_ARB: @@ -177,8 +160,6 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) _mesa_reference_program(ctx, &prg, NULL); stfp->bitmap_program = NULL; } - - st_free_translated_vertex_programs(st, stfp->vertex_programs); } break; default: @@ -219,8 +200,6 @@ static void st_program_string_notify( GLcontext *ctx, stfp->state.tokens = NULL; } - stfp->param_state = stfp->Base.Base.Parameters->StateFlags; - if (st->fp == stfp) st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; } @@ -229,25 +208,7 @@ static void st_program_string_notify( GLcontext *ctx, stvp->serialNo++; - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } - - if (stvp->draw_shader) { -#if FEATURE_feedback || FEATURE_drawpix - /* this would only have been allocated for the RasterPos path */ - draw_delete_vertex_shader(st->draw, stvp->draw_shader); - stvp->draw_shader = NULL; -#endif - } - - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } - - stvp->param_state = stvp->Base.Base.Parameters->StateFlags; + st_vp_release_varients( st, stvp ); if (st->vp == stvp) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 772bb3bb69e..103861d6f9c 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -243,7 +243,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, GLint row, col, dy, dstStride; if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - y = strb->texture->height[0] - y - height; + y = strb->texture->height0 - y - height; } trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index d4630a514f8..3a2337802fa 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -406,9 +406,9 @@ compress_with_blit(GLcontext * ctx, templ.target = PIPE_TEXTURE_2D; templ.format = st_mesa_format_to_pipe_format(mesa_format); pf_get_block(templ.format, &templ.block); - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; templ.last_level = 0; templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; src_tex = screen->texture_create(screen, &templ); @@ -1761,9 +1761,9 @@ st_finalize_texture(GLcontext *ctx, if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || stObj->pt->format != fmt || stObj->pt->last_level < stObj->lastLevel || - stObj->pt->width[0] != firstImage->base.Width2 || - stObj->pt->height[0] != firstImage->base.Height2 || - stObj->pt->depth[0] != firstImage->base.Depth2 || + stObj->pt->width0 != firstImage->base.Width2 || + stObj->pt->height0 != firstImage->base.Height2 || + stObj->pt->depth0 != firstImage->base.Depth2 || stObj->pt->block.size != blockSize) { pipe_texture_reference(&stObj->pt, NULL); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 18adb35e872..b7607286583 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -127,6 +127,8 @@ struct st_context struct st_vertex_program *vp; /**< Currently bound vertex program */ struct st_fragment_program *fp; /**< Currently bound fragment program */ + struct st_vp_varient *vp_varient; + struct gl_texture_object *default_texture; struct { diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c index 3009cde9d51..6e699ca5522 100644 --- a/src/mesa/state_tracker/st_debug.c +++ b/src/mesa/state_tracker/st_debug.c @@ -86,7 +86,8 @@ st_print_current(void) } #endif - tgsi_dump( st->vp->state.tokens, 0 ); + if (st->vp->varients) + tgsi_dump( st->vp->varients[0].state.tokens, 0 ); if (st->vp->Base.Base.Parameters) _mesa_print_parameter_list(st->vp->Base.Base.Parameters); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 68bc76b5723..e13ae57a0ec 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -573,7 +573,7 @@ st_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; - vs = &ctx->st->vp->state; + vs = &ctx->st->vp_varient->state; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index b2d682ef640..d793f820bc3 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -120,10 +120,10 @@ st_feedback_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; - vs = &st->vp->state; + vs = &st->vp_varient->state; - if (!st->vp->draw_shader) { - st->vp->draw_shader = draw_create_vertex_shader(draw, vs); + if (!st->vp_varient->draw_shader) { + st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs); } /* @@ -136,7 +136,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_viewport_state(draw, &st->state.viewport); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer); - draw_bind_vertex_shader(draw, st->vp->draw_shader); + draw_bind_vertex_shader(draw, st->vp_varient->draw_shader); set_feedback_vertex_format(ctx); /* loop over TGSI shader inputs to determine vertex buffer diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 57fe72d76a7..ef3cbc53ee0 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -92,6 +92,10 @@ void st_init_limits(struct st_context *st) = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS), MAX_VERTEX_TEXTURE_IMAGE_UNITS); + c->MaxCombinedTextureImageUnits + = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS), + MAX_COMBINED_TEXTURE_IMAGE_UNITS); + c->MaxTextureCoordUnits = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 16ca2771b0f..f8068fa12be 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -38,6 +38,7 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "util/u_gen_mipmap.h" +#include "util/u_math.h" #include "cso_cache/cso_cache.h" #include "cso_cache/cso_context.h" @@ -133,14 +134,14 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel)); dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel)); srcData = (ubyte *) screen->transfer_map(screen, srcTrans); dstData = (ubyte *) screen->transfer_map(screen, dstTrans); @@ -149,13 +150,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, dstStride = dstTrans->stride / dstTrans->block.size; _mesa_generate_mipmap_level(target, datatype, comps, - 0 /*border*/, - pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], - srcData, - srcStride, /* stride in texels */ - pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], - dstData, - dstStride); /* stride in texels */ + 0 /*border*/, + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel), + u_minify(pt->depth0, srcLevel), + srcData, + srcStride, /* stride in texels */ + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel), + u_minify(pt->depth0, dstLevel), + dstData, + dstStride); /* stride in texels */ screen->transfer_unmap(screen, srcTrans); screen->transfer_unmap(screen, dstTrans); @@ -232,9 +237,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, oldTex->target, oldTex->format, lastLevel, - oldTex->width[0], - oldTex->height[0], - oldTex->depth[0], + oldTex->width0, + oldTex->height0, + oldTex->depth0, oldTex->tex_usage); /* The texture isn't in a "complete" state yet so set the expected @@ -269,9 +274,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, = _mesa_get_tex_image(ctx, texObj, target, srcLevel); struct gl_texture_image *dstImage; struct st_texture_image *stImage; - uint dstWidth = pt->width[dstLevel]; - uint dstHeight = pt->height[dstLevel]; - uint dstDepth = pt->depth[dstLevel]; + uint dstWidth = u_minify(pt->width0, dstLevel); + uint dstHeight = u_minify(pt->height0, dstLevel); + uint dstDepth = u_minify(pt->depth0, dstLevel); uint border = srcImage->Border; dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel); diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 3d6c2158191..5e8e61135e6 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -676,6 +676,31 @@ emit_inverted_wpos( struct st_translate *t, /** + * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. + * TGSI uses +1 for front, -1 for back. + * This function converts the TGSI value to the GL value. Simply clamping/ + * saturating the value to [0,1] does the job. + */ +static void +emit_face_var( struct st_translate *t, + const struct gl_program *program ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst face_temp = ureg_DECL_temporary( ureg ); + struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; + + /* MOV_SAT face_temp, input[face] + */ + face_temp = ureg_saturate( face_temp ); + ureg_MOV( ureg, face_temp, face_input ); + + /* Use face_temp as face input from here on: + */ + t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); +} + + +/** * Translate Mesa program to TGSI format. * \param program the program to translate * \param numInputs number of input registers used @@ -704,12 +729,10 @@ st_translate_mesa_program( const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], - const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], - const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[] ) + const ubyte outputSemanticIndex[] ) { struct st_translate translate, *t; struct ureg_program *ureg; @@ -748,6 +771,10 @@ st_translate_mesa_program( emit_inverted_wpos( t, program ); } + if (program->InputsRead & FRAG_BIT_FACE) { + emit_face_var( t, program ); + } + /* * Declare output attributes. */ diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h index c0d1ff59e1f..dc0362fe790 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.h +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h @@ -49,12 +49,10 @@ st_translate_mesa_program( const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], - const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], - const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[] ); + const ubyte outputSemanticIndex[] ); void st_free_tokens(const struct tgsi_token *tokens); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 190b6a5526d..d66f45d13ea 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -49,6 +49,36 @@ #include "st_mesa_to_tgsi.h" #include "cso_cache/cso_context.h" + /* Clean out any old compilations: + */ +void +st_vp_release_varients( struct st_context *st, + struct st_vertex_program *stvp ) +{ + struct st_vp_varient *vpv; + + for (vpv = stvp->varients; vpv; ) { + struct st_vp_varient *next = vpv->next; + + if (vpv->driver_shader) + cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); + + if (vpv->draw_shader) + draw_delete_vertex_shader( st->draw, vpv->draw_shader ); + + if (vpv->state.tokens) + st_free_tokens(vpv->state.tokens); + + FREE( vpv ); + + vpv = next; + } + + stvp->varients = NULL; +} + + + /** * Translate a Mesa vertex shader into a TGSI shader. @@ -58,31 +88,13 @@ * \return pointer to cached pipe_shader object. */ void -st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *stvp, - const GLuint outputMapping[], - const ubyte *outputSemanticName, - const ubyte *outputSemanticIndex) +st_prepare_vertex_program(struct st_context *st, + struct st_vertex_program *stvp) { - struct pipe_context *pipe = st->pipe; - GLuint defaultOutputMapping[VERT_RESULT_MAX]; - GLuint attr, i; - GLuint num_generic = 0; - - ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS]; - ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - uint vs_num_inputs = 0; - - ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; - ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - uint vs_num_outputs = 0; - - GLbitfield input_flags[MAX_PROGRAM_INPUTS]; - GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; + GLuint attr; - /*memset(&vs, 0, sizeof(vs));*/ - memset(input_flags, 0, sizeof(input_flags)); - memset(output_flags, 0, sizeof(output_flags)); + stvp->num_inputs = 0; + stvp->num_outputs = 0; if (stvp->Base.IsPositionInvariant) _mesa_insert_mvp_code(st->ctx, &stvp->Base); @@ -93,162 +105,56 @@ st_translate_vertex_program(struct st_context *st, */ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { if (stvp->Base.Base.InputsRead & (1 << attr)) { - const GLuint slot = vs_num_inputs; - - vs_num_inputs++; - - stvp->input_to_index[attr] = slot; - stvp->index_to_input[slot] = attr; - - switch (attr) { - case VERT_ATTRIB_POS: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_WEIGHT: - /* fall-through */ - case VERT_ATTRIB_NORMAL: - /* just label as a generic */ - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_COLOR0: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_COLOR1: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_input_semantic_index[slot] = 1; - break; - case VERT_ATTRIB_FOG: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_POINT_SIZE: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_TEX0: - case VERT_ATTRIB_TEX1: - case VERT_ATTRIB_TEX2: - case VERT_ATTRIB_TEX3: - case VERT_ATTRIB_TEX4: - case VERT_ATTRIB_TEX5: - case VERT_ATTRIB_TEX6: - case VERT_ATTRIB_TEX7: - assert(slot < Elements(vs_input_semantic_name)); - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = num_generic++; - break; - case VERT_ATTRIB_GENERIC0: - case VERT_ATTRIB_GENERIC1: - case VERT_ATTRIB_GENERIC2: - case VERT_ATTRIB_GENERIC3: - case VERT_ATTRIB_GENERIC4: - case VERT_ATTRIB_GENERIC5: - case VERT_ATTRIB_GENERIC6: - case VERT_ATTRIB_GENERIC7: - case VERT_ATTRIB_GENERIC8: - case VERT_ATTRIB_GENERIC9: - case VERT_ATTRIB_GENERIC10: - case VERT_ATTRIB_GENERIC11: - case VERT_ATTRIB_GENERIC12: - case VERT_ATTRIB_GENERIC13: - case VERT_ATTRIB_GENERIC14: - case VERT_ATTRIB_GENERIC15: - assert(attr < VERT_ATTRIB_MAX); - assert(slot < Elements(vs_input_semantic_name)); - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = num_generic++; - break; - default: - assert(0); - } - - input_flags[slot] = stvp->Base.Base.InputFlags[attr]; + stvp->input_to_index[attr] = stvp->num_inputs; + stvp->index_to_input[stvp->num_inputs] = attr; + stvp->num_inputs++; } } -#if 0 - if (outputMapping && outputSemanticName) { - printf("VERT_RESULT written out_slot semantic_name semantic_index\n"); - for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - printf(" %-2d %c %3d %2d %2d\n", - attr, - ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '), - outputMapping[attr], - outputSemanticName[attr], - outputSemanticIndex[attr]); - } - } -#endif - - /* initialize output semantics to defaults */ - for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { - assert(i < Elements(vs_output_semantic_name)); - vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC; - vs_output_semantic_index[i] = 0; - output_flags[i] = 0x0; - } - - num_generic = 0; - /* - * Determine number of outputs, the (default) output register - * mapping and the semantic information for each output. + /* Compute mapping of vertex program outputs to slots. */ for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - if (stvp->Base.Base.OutputsWritten & (1 << attr)) { - GLuint slot; - - /* XXX - * Pass in the fragment program's input's semantic info. - * Use the generic semantic indexes from there, instead of - * guessing below. - */ - - if (outputMapping) { - slot = outputMapping[attr]; - assert(slot != ~0); - } - else { - slot = vs_num_outputs; - vs_num_outputs++; - defaultOutputMapping[attr] = slot; - } + if ((stvp->Base.Base.OutputsWritten & (1 << attr)) == 0) { + stvp->result_to_output[attr] = ~0; + } + else { + unsigned slot = stvp->num_outputs++; + + stvp->result_to_output[attr] = slot; switch (attr) { case VERT_RESULT_HPOS: - assert(slot == 0); - vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_COL0: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_COL1: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_output_semantic_index[slot] = 1; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + stvp->output_semantic_index[slot] = 1; break; case VERT_RESULT_BFC0: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_BFC1: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs_output_semantic_index[slot] = 1; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + stvp->output_semantic_index[slot] = 1; break; case VERT_RESULT_FOGC: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_PSIZ: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_EDGE: assert(0); break; + case VERT_RESULT_TEX0: case VERT_RESULT_TEX1: case VERT_RESULT_TEX2: @@ -257,92 +163,50 @@ st_translate_vertex_program(struct st_context *st, case VERT_RESULT_TEX5: case VERT_RESULT_TEX6: case VERT_RESULT_TEX7: - /* fall-through */ + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0; + break; + case VERT_RESULT_VAR0: - /* fall-through */ default: - assert(slot < Elements(vs_output_semantic_name)); - if (outputSemanticName) { - /* use provided semantic into */ - assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT); - vs_output_semantic_name[slot] = outputSemanticName[attr]; - vs_output_semantic_index[slot] = outputSemanticIndex[attr]; - } - else { - /* use default semantic info */ - vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_output_semantic_index[slot] = num_generic++; - } + assert(attr < VERT_RESULT_MAX); + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 - + FRAG_ATTRIB_TEX0 + + attr - + VERT_RESULT_VAR0); + break; } - - assert(slot < Elements(output_flags)); - output_flags[slot] = stvp->Base.Base.OutputFlags[attr]; } } +} - if (outputMapping) { - /* find max output slot referenced to compute vs_num_outputs */ - GLuint maxSlot = 0; - for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot) - maxSlot = outputMapping[attr]; - } - vs_num_outputs = maxSlot + 1; - } - else { - outputMapping = defaultOutputMapping; - } - -#if 0 /* debug */ - { - GLuint i; - printf("outputMapping? %d\n", outputMapping ? 1 : 0); - if (outputMapping) { - printf("attr -> slot\n"); - for (i = 0; i < 16; i++) { - printf(" %2d %3d\n", i, outputMapping[i]); - } - } - printf("slot sem_name sem_index\n"); - for (i = 0; i < vs_num_outputs; i++) { - printf(" %2d %d %d\n", - i, - vs_output_semantic_name[i], - vs_output_semantic_index[i]); - } - } -#endif - /* free old shader state, if any */ - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } +struct st_vp_varient * +st_translate_vertex_program(struct st_context *st, + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key) +{ + struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient); + struct pipe_context *pipe = st->pipe; - stvp->state.tokens = + vpv->state.tokens = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_VERTEX, &stvp->Base.Base, /* inputs */ - vs_num_inputs, + stvp->num_inputs, stvp->input_to_index, - vs_input_semantic_name, - vs_input_semantic_index, + NULL, /* input semantic name */ + NULL, /* input semantic index */ NULL, - input_flags, /* outputs */ - vs_num_outputs, - outputMapping, - vs_output_semantic_name, - vs_output_semantic_index, - output_flags ); + stvp->num_outputs, + stvp->result_to_output, + stvp->output_semantic_name, + stvp->output_semantic_index ); - stvp->num_inputs = vs_num_inputs; - stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state); + vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { _mesa_print_program(&stvp->Base.Base); @@ -350,9 +214,11 @@ st_translate_vertex_program(struct st_context *st, } if (ST_DEBUG & DEBUG_TGSI) { - tgsi_dump( stvp->state.tokens, 0 ); + tgsi_dump( vpv->state.tokens, 0 ); debug_printf("\n"); } + + return vpv; } @@ -375,7 +241,6 @@ st_translate_fragment_program(struct st_context *st, GLuint attr; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; GLuint vslot = 0; - GLuint num_generic = 0; uint fs_num_inputs = 0; @@ -383,13 +248,6 @@ st_translate_fragment_program(struct st_context *st, ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; uint fs_num_outputs = 0; - GLbitfield input_flags[MAX_PROGRAM_INPUTS]; - GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; - - /*memset(&fs, 0, sizeof(fs));*/ - memset(input_flags, 0, sizeof(input_flags)); - memset(output_flags, 0, sizeof(output_flags)); - /* which vertex output goes to the first fragment input: */ if (inputsRead & FRAG_BIT_WPOS) vslot = 0; @@ -432,14 +290,25 @@ st_translate_fragment_program(struct st_context *st, break; case FRAG_ATTRIB_FACE: stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE; - stfp->input_semantic_index[slot] = num_generic++; + stfp->input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; - case FRAG_ATTRIB_PNTC: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + + /* In most cases, there is nothing special about these + * inputs, so adopt a convention to use the generic + * semantic name and the mesa FRAG_ATTRIB_ number as the + * index. + * + * All that is required is that the vertex shader labels + * its own outputs similarly, and that the vertex shader + * generates at least every output required by the + * fragment shader plus fixed-function hardware (such as + * BFC). + * + * There is no requirement that semantic indexes start at + * zero or be restricted to a particular range -- nobody + * should be building tables based on semantic index. + */ case FRAG_ATTRIB_TEX0: case FRAG_ATTRIB_TEX1: case FRAG_ATTRIB_TEX2: @@ -448,19 +317,18 @@ st_translate_fragment_program(struct st_context *st, case FRAG_ATTRIB_TEX5: case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + case FRAG_ATTRIB_PNTC: case FRAG_ATTRIB_VAR0: - /* fall-through */ default: + /* Actually, let's try and zero-base this just for + * readability of the generated TGSI. + */ + assert(attr >= FRAG_ATTRIB_TEX0); + stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; + break; } - - input_flags[slot] = stfp->Base.Base.InputFlags[attr]; } } @@ -498,8 +366,6 @@ st_translate_fragment_program(struct st_context *st, break; } - output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr]; - fs_num_outputs++; } } @@ -518,13 +384,11 @@ st_translate_fragment_program(struct st_context *st, stfp->input_semantic_name, stfp->input_semantic_index, interpMode, - input_flags, /* outputs */ fs_num_outputs, outputMapping, fs_output_semantic_name, - fs_output_semantic_index, - output_flags ); + fs_output_semantic_index ); stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index e2e5eddef22..88aadbd7510 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -64,41 +64,70 @@ struct st_fragment_program struct pipe_shader_state state; void *driver_shader; - GLuint param_state; - - /** List of vertex programs which have been translated such that their - * outputs match this fragment program's inputs. - */ - struct translated_vertex_program *vertex_programs; - /** Program prefixed with glBitmap prologue */ struct st_fragment_program *bitmap_program; uint bitmap_sampler; }; + +struct st_vp_varient_key +{ + char dummy; /* currently unused */ +}; + + +/** + * This represents a vertex program, especially translated to match + * the inputs of a particular fragment shader. + */ +struct st_vp_varient +{ + /* Parameters which generated this translated version of a vertex + * shader: + */ + struct st_vp_varient_key key; + + /** TGSI tokens -- why? + */ + struct pipe_shader_state state; + + /** Driver's compiled shader */ + void *driver_shader; + + /** For using our private draw module (glRasterPos) */ + struct draw_vertex_shader *draw_shader; + + /** Next in linked list */ + struct st_vp_varient *next; +}; + + + + /** * Derived from Mesa gl_fragment_program: */ struct st_vertex_program { struct gl_vertex_program Base; /**< The Mesa vertex program */ - GLuint serialNo; + GLuint serialNo, lastSerialNo; /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */ GLuint input_to_index[VERT_ATTRIB_MAX]; /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */ GLuint index_to_input[PIPE_MAX_SHADER_INPUTS]; - GLuint num_inputs; - struct pipe_shader_state state; - void *driver_shader; + /** Maps VERT_RESULT_x to slot */ + GLuint result_to_output[VERT_RESULT_MAX]; + ubyte output_semantic_name[VERT_RESULT_MAX]; + ubyte output_semantic_index[VERT_RESULT_MAX]; + GLuint num_outputs; - /** For using our private draw module (glRasterPos) */ - struct draw_vertex_shader *draw_shader; - - GLuint param_state; + /** List of translated varients of this vertex program. + */ + struct st_vp_varient *varients; }; @@ -143,13 +172,21 @@ st_translate_fragment_program(struct st_context *st, const GLuint inputMapping[]); +/* Called after program string change, discard all previous + * compilation results. + */ extern void +st_prepare_vertex_program(struct st_context *st, + struct st_vertex_program *stvp); + +extern struct st_vp_varient * st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *vp, - const GLuint vert_output_to_slot[], - const ubyte *fs_input_semantic_name, - const ubyte *fs_input_semantic_index); + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key); +void +st_vp_release_varients( struct st_context *st, + struct st_vertex_program *stvp ); extern void st_print_shaders(GLcontext *ctx); diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 10f13512830..dbccee86c1c 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -44,6 +44,7 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "util/u_rect.h" +#include "util/u_math.h" #define DBG if(0) printf @@ -100,9 +101,9 @@ st_texture_create(struct st_context *st, pt.target = target; pt.format = format; pt.last_level = last_level; - pt.width[0] = width0; - pt.height[0] = height0; - pt.depth[0] = depth0; + pt.width0 = width0; + pt.height0 = height0; + pt.depth0 = depth0; pf_get_block(format, &pt.block); pt.tex_usage = usage; @@ -135,9 +136,9 @@ st_texture_match_image(const struct pipe_texture *pt, /* Test if this image's size matches what's expected in the * established texture. */ - if (image->Width != pt->width[level] || - image->Height != pt->height[level] || - image->Depth != pt->depth[level]) + if (image->Width != u_minify(pt->width0, level) || + image->Height != u_minify(pt->height0, level) || + image->Depth != u_minify(pt->depth0, level)) return GL_FALSE; return GL_TRUE; @@ -265,7 +266,7 @@ st_texture_image_data(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - GLuint depth = dst->depth[level]; + GLuint depth = u_minify(dst->depth0, level); GLuint i; const GLubyte *srcUB = src; struct pipe_transfer *dst_transfer; @@ -275,15 +276,16 @@ st_texture_image_data(struct st_context *st, for (i = 0; i < depth; i++) { dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i, PIPE_TRANSFER_WRITE, 0, 0, - dst->width[level], - dst->height[level]); + u_minify(dst->width0, level), + u_minify(dst->height0, level)); st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ srcUB, src_row_stride, 0, 0, /* source x, y */ - dst->width[level], dst->height[level]); /* width, height */ + u_minify(dst->width0, level), + u_minify(dst->height0, level)); /* width, height */ screen->tex_transfer_destroy(dst_transfer); @@ -301,9 +303,9 @@ st_texture_image_copy(struct pipe_context *pipe, GLuint face) { struct pipe_screen *screen = pipe->screen; - GLuint width = dst->width[dstLevel]; - GLuint height = dst->height[dstLevel]; - GLuint depth = dst->depth[dstLevel]; + GLuint width = u_minify(dst->width0, dstLevel); + GLuint height = u_minify(dst->height0, dstLevel); + GLuint depth = u_minify(dst->depth0, dstLevel); struct pipe_surface *src_surface; struct pipe_surface *dst_surface; GLuint i; @@ -313,13 +315,13 @@ st_texture_image_copy(struct pipe_context *pipe, /* find src texture level of needed size */ for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) { - if (src->width[srcLevel] == width && - src->height[srcLevel] == height) { + if (u_minify(src->width0, srcLevel) == width && + u_minify(src->height0, srcLevel) == height) { break; } } - assert(src->width[srcLevel] == width); - assert(src->height[srcLevel] == height); + assert(u_minify(src->width0, srcLevel) == width); + assert(u_minify(src->height0, srcLevel) == height); #if 0 { |