diff options
author | Christian König <[email protected]> | 2011-05-15 19:26:53 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-05-15 19:26:53 +0200 |
commit | 828540e491d88b9b6217e6568873a78462919ae8 (patch) | |
tree | c952145c1188cdf6b9c56902f8f5c189e090c278 /src/gallium/drivers | |
parent | 3db6514357a7c634045ae7bc7bba7d7dbf9d58c5 (diff) | |
parent | bd5b7a6f7113da38a2c1f07a4a71e9993666a567 (diff) |
Merge remote-tracking branch 'origin/master' into pipe-video
Diffstat (limited to 'src/gallium/drivers')
23 files changed, 281 insertions, 156 deletions
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index 3e9804bf8ee..d6febd36f41 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -188,7 +188,7 @@ run_vertex_program(struct spu_vs_context *draw, PIPE_ALIGN_VAR(16) unsigned char -immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32]); +immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32]; void diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 0e427749636..da96b420f2c 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -167,7 +167,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) return 0; default: - debug_printf("%s: Unkown cap %u.\n", __FUNCTION__, cap); + debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); return 0; } } @@ -218,7 +218,7 @@ i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_sha case PIPE_SHADER_CAP_SUBROUTINES: return 0; default: - debug_printf("%s: Unkown cap %u.\n", __FUNCTION__, cap); + debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); return 0; } } @@ -244,7 +244,7 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap) return 16.0; default: - debug_printf("%s: Unkown cap %u.\n", __FUNCTION__, cap); + debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); return 0; } } diff --git a/src/gallium/drivers/llvmpipe/lp_rast_debug.c b/src/gallium/drivers/llvmpipe/lp_rast_debug.c index 64ac616f629..03e67dc8177 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_debug.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_debug.c @@ -397,8 +397,8 @@ lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene ) for (y = 0; y < scene->tiles_y; y++) { for (x = 0; x < scene->tiles_x; x++) { const char *bits = " ...,-~:;=o+xaw*#XAWWWWWWWWWWWWWWWW"; - int sz = lp_scene_bin_size(scene, x, y); - int sz2 = util_unsigned_logbase2(sz); + unsigned sz = lp_scene_bin_size(scene, x, y); + unsigned sz2 = util_logbase2(sz); debug_printf("%c", bits[MIN2(sz2,32)]); } debug_printf("\n"); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 4dad8599870..cc921d08666 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -89,6 +89,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; case PIPE_CAP_SEAMLESS_CUBE_MAP: return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D; case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: @@ -488,7 +489,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3); OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); - OUT_RING (chan, util_unsigned_logbase2(tls_space / 8)); + OUT_RING (chan, util_logbase2(tls_space / 8)); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, &screen->uniforms); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 74869774595..d9fb22aa673 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -209,6 +209,9 @@ nv50_miptree_transfer_new(struct pipe_context *pctx, uint32_t w, h, d, z, layer; int ret; + if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + return NULL; + if (mt->layout_3d) { z = box->z; d = u_minify(res->depth0, level); diff --git a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c index 7f5fbaff690..82a8397238d 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c +++ b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c @@ -1293,31 +1293,45 @@ nv_pass_cse(struct nv_pass *ctx, struct nv_basic_block *b) * neighbouring registers. CSE might have messed this up. * Just generate a MOV for each source to avoid conflicts if they're used in * multiple NV_OP_BIND at different positions. + * + * Add a dummy use of the pointer source of >= 8 byte loads after the load + * to prevent it from being assigned a register which overlaps the load's + * destination, which would produce random corruptions. */ static int -nv_pass_fix_bind(struct nv_pass *ctx, struct nv_basic_block *b) +nv_pass_fixups(struct nv_pass *ctx, struct nv_basic_block *b) { struct nv_value *val; - struct nv_instruction *bnd, *nvi, *next; + struct nv_instruction *fix, *nvi, *next; int s; - for (bnd = b->entry; bnd; bnd = next) { - next = bnd->next; - if (bnd->opcode != NV_OP_BIND) + for (fix = b->entry; fix; fix = next) { + next = fix->next; + + if (fix->opcode == NV_OP_LD) { + if (fix->indirect >= 0 && fix->src[0]->value->reg.size >= 8) { + nvi = nv_alloc_instruction(ctx->pc, NV_OP_UNDEF); + nv_reference(ctx->pc, nvi, 0, fix->src[fix->indirect]->value); + + nvc0_insn_insert_after(fix, nvi); + } continue; - for (s = 0; s < 4 && bnd->src[s]; ++s) { - val = bnd->src[s]->value; + } else + if (fix->opcode == NV_OP_BIND) { + for (s = 0; s < 4 && fix->src[s]; ++s) { + val = fix->src[s]->value; - nvi = nv_alloc_instruction(ctx->pc, NV_OP_MOV); - nvi->def[0] = new_value_like(ctx->pc, val); - nvi->def[0]->insn = nvi; - nv_reference(ctx->pc, nvi, 0, val); - nv_reference(ctx->pc, bnd, s, nvi->def[0]); + nvi = nv_alloc_instruction(ctx->pc, NV_OP_MOV); + nvi->def[0] = new_value_like(ctx->pc, val); + nvi->def[0]->insn = nvi; + nv_reference(ctx->pc, nvi, 0, val); + nv_reference(ctx->pc, fix, s, nvi->def[0]); - nvc0_insn_insert_before(bnd, nvi); + nvc0_insn_insert_before(fix, nvi); + } } } - DESCEND_ARBITRARY(s, nv_pass_fix_bind); + DESCEND_ARBITRARY(s, nv_pass_fixups); return 0; } @@ -1403,7 +1417,7 @@ nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root) return ret; pc->pass_seq++; - ret = nv_pass_fix_bind(&pass, root); + ret = nv_pass_fixups(&pass, root); return ret; } diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index 7bbfe057e58..0509113e005 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -246,6 +246,9 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx, uint32_t w, h, d, z, layer; int ret; + if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + return NULL; + tx = CALLOC_STRUCT(nvc0_transfer); if (!tx) return NULL; diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 4a97dfb9c25..78212029534 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -81,6 +81,12 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 0; // TODO: implement depth clamp case PIPE_CAP_PRIMITIVE_RESTART: return 0; // TODO: implement primitive restart + case PIPE_CAP_ARRAY_TEXTURES: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: + case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: case PIPE_CAP_SHADER_STENCIL_EXPORT: return 0; case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 1217488bac7..4ec77df8fb7 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -113,7 +113,7 @@ static boolean r300_fast_zclear_allowed(struct r300_context *r300) struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - return r300_resource(fb->zsbuf->texture)->tex.zmask_dwords[fb->zsbuf->u.tex.level]; + return r300_resource(fb->zsbuf->texture)->tex.zmask_dwords[fb->zsbuf->u.tex.level] != 0; } static boolean r300_hiz_clear_allowed(struct r300_context *r300) @@ -121,7 +121,7 @@ static boolean r300_hiz_clear_allowed(struct r300_context *r300) struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - return r300_resource(fb->zsbuf->texture)->tex.hiz_dwords[fb->zsbuf->u.tex.level]; + return r300_resource(fb->zsbuf->texture)->tex.hiz_dwords[fb->zsbuf->u.tex.level] != 0; } static uint32_t r300_depth_clear_value(enum pipe_format format, @@ -206,23 +206,47 @@ static void r300_clear(struct pipe_context* pipe, (struct r300_hyperz_state*)r300->hyperz_state.state; uint32_t width = fb->width; uint32_t height = fb->height; - boolean can_hyperz = r300->rws->get_value(r300->rws, RADEON_VID_CAN_HYPERZ); uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; /* Enable fast Z clear. * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ - if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) { - if (r300_fast_zclear_allowed(r300)) { - hyperz_dcv = hyperz->zb_depthclearvalue = - r300_depth_clear_value(fb->zsbuf->format, depth, stencil); - - r300_mark_atom_dirty(r300, &r300->zmask_clear); - buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; - } - - if (r300_hiz_clear_allowed(r300)) { - r300->hiz_clear_value = r300_hiz_clear_value(depth); - r300_mark_atom_dirty(r300, &r300->hiz_clear); + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + boolean zmask_clear, hiz_clear; + + zmask_clear = r300_fast_zclear_allowed(r300); + hiz_clear = r300_hiz_clear_allowed(r300); + + /* If we need Hyper-Z. */ + if (zmask_clear || hiz_clear) { + r300->num_z_clears++; + + /* Try to obtain the access to Hyper-Z buffers if we don't have one. */ + if (!r300->hyperz_enabled) { + r300->hyperz_enabled = + r300->rws->cs_request_feature(r300->cs, + RADEON_FID_HYPERZ_RAM_ACCESS, + TRUE); + if (r300->hyperz_enabled) { + /* Need to emit HyperZ buffer regs for the first time. */ + r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); + } + } + + /* Setup Hyper-Z clears. */ + if (r300->hyperz_enabled) { + if (zmask_clear) { + hyperz_dcv = hyperz->zb_depthclearvalue = + r300_depth_clear_value(fb->zsbuf->format, depth, stencil); + + r300_mark_atom_dirty(r300, &r300->zmask_clear); + buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; + } + + if (hiz_clear) { + r300->hiz_clear_value = r300_hiz_clear_value(depth); + r300_mark_atom_dirty(r300, &r300->hiz_clear); + } + } } } @@ -323,7 +347,7 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe, struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - if (r300->zmask_in_use && !r300->hyperz_locked) { + if (r300->zmask_in_use && !r300->locked_zbuffer) { if (fb->zsbuf->texture == dst->texture) { r300_decompress_zmask(r300); } @@ -341,7 +365,7 @@ void r300_decompress_zmask(struct r300_context *r300) struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - if (!r300->zmask_in_use || r300->hyperz_locked) + if (!r300->zmask_in_use || r300->locked_zbuffer) return; r300->zmask_decompress = TRUE; @@ -377,6 +401,8 @@ void r300_decompress_zmask_locked(struct r300_context *r300) r300_decompress_zmask_locked_unsafe(r300); r300->context.set_framebuffer_state(&r300->context, &saved_fb); util_unreference_framebuffer_state(&saved_fb); + + pipe_surface_reference(&r300->locked_zbuffer, NULL); } /* Copy a block of pixels from one surface to another using HW. */ @@ -423,7 +449,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe, return; } - if (r300->zmask_in_use && !r300->hyperz_locked) { + if (r300->zmask_in_use && !r300->locked_zbuffer) { if (fb->zsbuf->texture == src || fb->zsbuf->texture == dst) { r300_decompress_zmask(r300); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 15d1278c3bb..0554c40eef0 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -26,6 +26,7 @@ #include "util/u_sampler.h" #include "util/u_simple_list.h" #include "util/u_upload_mgr.h" +#include "os/os_time.h" #include "r300_cb.h" #include "r300_context.h" @@ -95,6 +96,10 @@ static void r300_destroy_context(struct pipe_context* context) { struct r300_context* r300 = r300_context(context); + if (r300->cs && r300->hyperz_enabled) { + r300->rws->cs_request_feature(r300->cs, RADEON_FID_HYPERZ_RAM_ACCESS, FALSE); + } + if (r300->blitter) util_blitter_destroy(r300->blitter); if (r300->draw) @@ -167,8 +172,6 @@ static boolean r300_setup_atoms(struct r300_context* r300) boolean is_r500 = r300->screen->caps.is_r500; boolean has_tcl = r300->screen->caps.has_tcl; boolean drm_2_6_0 = r300->rws->get_value(r300->rws, RADEON_VID_DRM_2_6_0); - boolean can_hyperz = r300->rws->get_value(r300->rws, RADEON_VID_CAN_HYPERZ); - boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0; /* Create the actual atom list. * @@ -219,13 +222,10 @@ static boolean r300_setup_atoms(struct r300_context* r300) /* TX. */ R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); - if (can_hyperz) { - /* HiZ Clear */ - if (has_hiz_ram) - R300_INIT_ATOM(hiz_clear, 4); - /* zmask clear */ - R300_INIT_ATOM(zmask_clear, 4); - } + /* HiZ Clear */ + R300_INIT_ATOM(hiz_clear, r300->screen->caps.hiz_ram > 0 ? 4 : 0); + /* zmask clear */ + R300_INIT_ATOM(zmask_clear, r300->screen->caps.zmask_ram > 0 ? 4 : 0); /* ZB (unpipelined), SU. */ R300_INIT_ATOM(query_start, 4); @@ -503,6 +503,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, &dsa); } + r300->hyperz_time_of_last_flush = os_time_get(); + /* Print driver info. */ #ifdef DEBUG { @@ -512,7 +514,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, fprintf(stderr, "r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n" "r300: GART size: %d MB, VRAM size: %d MB\n" - "r300: AA compression: %s, Z compression: %s, HiZ: %s\n", + "r300: AA compression RAM: %s, Z compression RAM: %s, HiZ RAM: %s\n", rws->get_value(rws, RADEON_VID_DRM_MAJOR), rws->get_value(rws, RADEON_VID_DRM_MINOR), rws->get_value(rws, RADEON_VID_DRM_PATCHLEVEL), @@ -522,10 +524,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, rws->get_value(rws, RADEON_VID_R300_Z_PIPES), rws->get_value(rws, RADEON_VID_GART_SIZE) >> 20, rws->get_value(rws, RADEON_VID_VRAM_SIZE) >> 20, - rws->get_value(rws, RADEON_VID_CAN_AACOMPRESS) ? "YES" : "NO", - rws->get_value(rws, RADEON_VID_CAN_HYPERZ) && + "YES", /* XXX really? */ r300->screen->caps.zmask_ram ? "YES" : "NO", - rws->get_value(rws, RADEON_VID_CAN_HYPERZ) && r300->screen->caps.hiz_ram ? "YES" : "NO"); } diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8a0a54cf1e9..139dd210b8f 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -592,20 +592,6 @@ struct r300_context { boolean frag_clamp; /* Whether fast color clear is enabled. */ boolean cbzb_clear; - /* Whether ZMASK is enabled. */ - boolean zmask_in_use; - /* Whether ZMASK is being decompressed. */ - boolean zmask_decompress; - /* Whether ZMASK/HIZ is locked, i.e. should be disabled and cannot be taken over. */ - boolean hyperz_locked; - /* The zbuffer the ZMASK of which is locked. */ - struct pipe_surface *locked_zbuffer; - /* Whether HIZ is enabled. */ - boolean hiz_in_use; - /* HiZ function. Can be either MIN or MAX. */ - enum r300_hiz_func hiz_func; - /* HiZ clear value. */ - uint32_t hiz_clear_value; /* Whether fragment shader needs to be validated. */ enum r300_fs_validity_status fs_status; /* Framebuffer multi-write. */ @@ -629,6 +615,21 @@ struct r300_context { int vertex_arrays_offset; int vertex_arrays_instance_id; boolean instancing_enabled; + + /* Hyper-Z stats. */ + boolean hyperz_enabled; /* Whether it owns Hyper-Z access. */ + int64_t hyperz_time_of_last_flush; /* Time of the last flush with Z clear. */ + unsigned num_z_clears; /* Since the last flush. */ + + /* ZMask state. */ + boolean zmask_in_use; /* Whether ZMASK is enabled. */ + boolean zmask_decompress; /* Whether ZMASK is being decompressed. */ + struct pipe_surface *locked_zbuffer; /* Unbound zbuffer which still has data in ZMASK. */ + + /* HiZ state. */ + boolean hiz_in_use; /* Whether HIZ is enabled. */ + enum r300_hiz_func hiz_func; /* HiZ function. Can be either MIN or MAX. */ + uint32_t hiz_clear_value; /* HiZ clear value. */ }; #define foreach_atom(r300, atom) \ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 62435c5e2e2..874037ed9fd 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -375,7 +375,6 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_surface* surf; unsigned i; - boolean can_hyperz = r300->rws->get_value(r300->rws, RADEON_VID_CAN_HYPERZ); uint32_t rb3d_cctl = 0; CS_LOCALS(r300); @@ -432,7 +431,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG(R300_ZB_DEPTHPITCH, surf->pitch); OUT_CS_RELOC(surf); - if (can_hyperz) { + if (r300->hyperz_enabled) { /* HiZ RAM. */ OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0); OUT_CS_REG(R300_ZB_HIZ_PITCH, surf->pitch_hiz); diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index de7d77d608b..34f5419a864 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -27,17 +27,46 @@ #include "util/u_simple_list.h" #include "util/u_upload_mgr.h" +#include "os/os_time.h" + #include "r300_context.h" #include "r300_cs.h" #include "r300_emit.h" +static void r300_flush_and_cleanup(struct r300_context *r300, unsigned flags) +{ + struct r300_atom *atom; + + r300_emit_hyperz_end(r300); + r300_emit_query_end(r300); + if (r300->screen->caps.is_r500) + r500_emit_index_bias(r300, 0); + + r300->flush_counter++; + r300->rws->cs_flush(r300->cs, flags); + r300->dirty_hw = 0; + + /* New kitchen sink, baby. */ + foreach_atom(r300, atom) { + if (atom->state || atom->allow_null_state) { + r300_mark_atom_dirty(r300, atom); + } + } + r300->vertex_arrays_dirty = TRUE; + + /* Unmark HWTCL state for SWTCL. */ + if (!r300->screen->caps.has_tcl) { + r300->vs_state.dirty = FALSE; + r300->vs_constants.dirty = FALSE; + } +} + void r300_flush(struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence) { struct r300_context *r300 = r300_context(pipe); - struct r300_atom *atom; struct pb_buffer **rfence = (struct pb_buffer**)fence; if (r300->draw && !r300->draw_vbo_locked) @@ -56,32 +85,11 @@ void r300_flush(struct pipe_context *pipe, } if (r300->dirty_hw) { - r300_emit_hyperz_end(r300); - r300_emit_query_end(r300); - if (r300->screen->caps.is_r500) - r500_emit_index_bias(r300, 0); - - r300->flush_counter++; - r300->rws->cs_flush(r300->cs, flags); - r300->dirty_hw = 0; - - /* New kitchen sink, baby. */ - foreach_atom(r300, atom) { - if (atom->state || atom->allow_null_state) { - r300_mark_atom_dirty(r300, atom); - } - } - r300->vertex_arrays_dirty = TRUE; - - /* Unmark HWTCL state for SWTCL. */ - if (!r300->screen->caps.has_tcl) { - r300->vs_state.dirty = FALSE; - r300->vs_constants.dirty = FALSE; - } + r300_flush_and_cleanup(r300, flags); } else { if (rfence) { /* We have to create a fence object, but the command stream is empty - * and we cannot emit an empty CS. We must write some regs then. */ + * and we cannot emit an empty CS. Let's write to some reg. */ CS_LOCALS(r300); OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0); r300->rws->cs_flush(r300->cs, flags); @@ -91,6 +99,32 @@ void r300_flush(struct pipe_context *pipe, r300->rws->cs_flush(r300->cs, flags); } } + + /* Update Hyper-Z status. */ + if (r300->num_z_clears) { + r300->hyperz_time_of_last_flush = os_time_get(); + } else if (!r300->hyperz_time_of_last_flush > 2000000) { + /* 2 seconds without a Z clear pretty much means a dead context + * for HyperZ. */ + + r300->hiz_in_use = FALSE; + + /* Decompress Z buffer. */ + if (r300->zmask_in_use) { + if (r300->locked_zbuffer) { + r300_decompress_zmask_locked(r300); + } else { + r300_decompress_zmask(r300); + } + + r300_flush_and_cleanup(r300, flags); + } + + /* Release HyperZ. */ + r300->rws->cs_request_feature(r300->cs, RADEON_FID_HYPERZ_RAM_ACCESS, + FALSE); + } + r300->num_z_clears = 0; } static void r300_flush_wrapped(struct pipe_context *pipe, diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index ef330f34c9e..e946d61d0ed 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -43,16 +43,13 @@ static enum r300_hiz_func r300_get_hiz_func(struct r300_context *r300) { struct r300_dsa_state *dsa = r300->dsa_state.state; - if (!dsa->dsa.depth.enabled || !dsa->dsa.depth.writemask) - return HIZ_FUNC_NONE; - switch (dsa->dsa.depth.func) { case PIPE_FUNC_NEVER: case PIPE_FUNC_EQUAL: case PIPE_FUNC_NOTEQUAL: case PIPE_FUNC_ALWAYS: - return HIZ_FUNC_NONE; - + default: + /* Guess MAX for uncertain cases. */ case PIPE_FUNC_LESS: case PIPE_FUNC_LEQUAL: return HIZ_FUNC_MAX; @@ -60,10 +57,6 @@ static enum r300_hiz_func r300_get_hiz_func(struct r300_context *r300) case PIPE_FUNC_GREATER: case PIPE_FUNC_GEQUAL: return HIZ_FUNC_MIN; - - default: - assert(0); - return HIZ_FUNC_NONE; } } @@ -103,18 +96,21 @@ static boolean r300_dsa_stencil_op_not_keep(struct pipe_stencil_state *s) s->zfail_op != PIPE_STENCIL_OP_KEEP); } -static boolean r300_can_hiz(struct r300_context *r300) +static boolean r300_hiz_allowed(struct r300_context *r300) { struct r300_dsa_state *dsa = r300->dsa_state.state; struct r300_screen *r300screen = r300->screen; - /* shader writes depth - no HiZ */ - if (r300_fragment_shader_writes_depth(r300_fs(r300))) /* (5) */ + if (r300_fragment_shader_writes_depth(r300_fs(r300))) return FALSE; if (r300->query_current) return FALSE; + /* If the depth function is inverted, HiZ must be disabled. */ + if (!r300_is_hiz_func_valid(r300)) + return FALSE; + /* if stencil fail/zfail op is not KEEP */ if (r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[0]) || r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[1])) @@ -138,6 +134,7 @@ static void r300_update_hyperz(struct r300_context* r300) (struct r300_hyperz_state*)r300->hyperz_state.state; struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_dsa_state *dsa = r300->dsa_state.state; struct r300_resource *zstex = fb->zsbuf ? r300_resource(fb->zsbuf->texture) : NULL; @@ -151,55 +148,70 @@ static void r300_update_hyperz(struct r300_context* r300) return; } - if (!zstex || - !r300->rws->get_value(r300->rws, RADEON_VID_CAN_HYPERZ)) + if (!zstex || !r300->hyperz_enabled) return; - /* Zbuffer compression. */ - if (r300->zmask_in_use && !r300->hyperz_locked) { + /* Set the size of ZMASK tiles. */ + if (zstex->tex.zcomp8x8[fb->zsbuf->u.tex.level]) { + z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; + } + + /* R500-specific features and optimizations. */ + if (r300->screen->caps.is_r500) { + z->zb_bw_cntl |= R500_PEQ_PACKING_ENABLE | + R500_COVERED_PTR_MASKING_ENABLE; + } + + /* Setup decompression if needed. No other HyperZ setting is required. */ + if (r300->zmask_decompress) { z->zb_bw_cntl |= R300_FAST_FILL_ENABLE | - /*R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE |*/ R300_RD_COMP_ENABLE; + return; + } - if (!r300->zmask_decompress) { - z->zb_bw_cntl |= R300_WR_COMP_ENABLE; - } + /* Do not set anything if depth and stencil tests are off. */ + if (!dsa->dsa.depth.enabled && + !dsa->dsa.stencil[0].enabled && + !dsa->dsa.stencil[1].enabled) { + assert(!dsa->dsa.depth.writemask); + return; } - if (zstex->tex.zcomp8x8[fb->zsbuf->u.tex.level]) { - z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; + /* Zbuffer compression. */ + if (r300->zmask_in_use && !r300->locked_zbuffer) { + z->zb_bw_cntl |= R300_FAST_FILL_ENABLE | + R300_RD_COMP_ENABLE | + R300_WR_COMP_ENABLE; } /* HiZ. */ - if (r300->hiz_in_use && !r300->hyperz_locked) { + if (r300->hiz_in_use && !r300->locked_zbuffer) { + /* HiZ cannot be used under some circumstances. */ + if (!r300_hiz_allowed(r300)) { + /* If writemask is disabled, the HiZ memory will not be changed, + * so we can keep its content for later. */ + if (dsa->dsa.depth.writemask) { + r300->hiz_in_use = FALSE; + } + return; + } + /* Set the HiZ function if needed. */ if (r300->hiz_func == HIZ_FUNC_NONE) { r300->hiz_func = r300_get_hiz_func(r300); } - /* If the depth function is inverted, HiZ must be disabled. */ - if (!r300_is_hiz_func_valid(r300)) { - r300->hiz_in_use = FALSE; - } else if (r300_can_hiz(r300)) { - /* Setup the HiZ bits. */ - z->zb_bw_cntl |= - R300_HIZ_ENABLE | + /* Setup the HiZ bits. */ + z->zb_bw_cntl |= R300_HIZ_ENABLE | (r300->hiz_func == HIZ_FUNC_MIN ? R300_HIZ_MIN : R300_HIZ_MAX); - z->sc_hyperz |= R300_SC_HYPERZ_ENABLE | - r300_get_sc_hz_max(r300); + z->sc_hyperz |= R300_SC_HYPERZ_ENABLE | + r300_get_sc_hz_max(r300); - if (r300->screen->caps.is_r500) { - z->zb_bw_cntl |= R500_HIZ_EQUAL_REJECT_ENABLE; - } + if (r300->screen->caps.is_r500) { + z->zb_bw_cntl |= R500_HIZ_EQUAL_REJECT_ENABLE; } } - - /* R500-specific features and optimizations. */ - if (r300->screen->caps.is_r500) { - z->zb_bw_cntl |= R500_PEQ_PACKING_ENABLE | - R500_COVERED_PTR_MASKING_ENABLE; - } } /*****************************************************************************/ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 24b41d5085d..bc6c67dd034 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -768,7 +768,6 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; - boolean can_hyperz = r300->rws->get_value(r300->rws, RADEON_VID_CAN_HYPERZ); r300_mark_atom_dirty(r300, &r300->gpu_flush); r300_mark_atom_dirty(r300, &r300->fb_state); @@ -797,7 +796,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, r300->fb_state.size += 10; else if (state->zsbuf) { r300->fb_state.size += 10; - if (can_hyperz) + if (r300->hyperz_enabled) r300->fb_state.size += 8; } @@ -813,6 +812,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe, struct pipe_framebuffer_state *old_state = r300->fb_state.state; unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; + boolean unlock_zbuffer = FALSE; if (r300->screen->caps.is_r500) { max_width = max_height = 4096; @@ -828,7 +828,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe, return; } - if (old_state->zsbuf && r300->zmask_in_use && !r300->hyperz_locked) { + if (old_state->zsbuf && r300->zmask_in_use && !r300->locked_zbuffer) { /* There is a zmask in use, what are we gonna do? */ if (state->zsbuf) { if (!pipe_surface_equal(old_state->zsbuf, state->zsbuf)) { @@ -838,10 +838,9 @@ r300_set_framebuffer_state(struct pipe_context* pipe, } } else { /* We don't bind another zbuffer, so lock the current one. */ - r300->hyperz_locked = TRUE; pipe_surface_reference(&r300->locked_zbuffer, old_state->zsbuf); } - } else if (r300->hyperz_locked && r300->locked_zbuffer) { + } else if (r300->locked_zbuffer) { /* We have a locked zbuffer now, what are we gonna do? */ if (state->zsbuf) { if (!pipe_surface_equal(r300->locked_zbuffer, state->zsbuf)) { @@ -851,11 +850,11 @@ r300_set_framebuffer_state(struct pipe_context* pipe, r300->hiz_in_use = FALSE; } else { /* We are binding the locked zbuffer again, so unlock it. */ - r300->hyperz_locked = FALSE; + unlock_zbuffer = TRUE; } } } - assert(state->zsbuf || r300->hyperz_locked || !r300->zmask_in_use); + assert(state->zsbuf || (r300->locked_zbuffer && !unlock_zbuffer) || !r300->zmask_in_use); /* Need to reset clamping or colormask. */ r300_mark_atom_dirty(r300, &r300->blend_state); @@ -870,7 +869,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe, util_copy_framebuffer_state(r300->fb_state.state, state); - if (!r300->hyperz_locked) { + if (unlock_zbuffer) { pipe_surface_reference(&r300->locked_zbuffer, NULL); } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index afc1451183d..04499c78cc6 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -965,7 +965,7 @@ static void r300_decompress_depth_textures(struct r300_context *r300) state->sampler_state_count); unsigned i; - if (!r300->hyperz_locked || !r300->locked_zbuffer) { + if (!r300->locked_zbuffer) { return; } diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 502f2663e8b..654b04ea1bd 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -310,6 +310,7 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; + unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0; if (rstate == NULL) { return NULL; @@ -321,9 +322,10 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | - S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) | - S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter) | aniso_flag_offset) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter) | aniso_flag_offset) | S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_MAX_ANISO(r600_tex_aniso_filter(state->max_anisotropy)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, @@ -429,7 +431,9 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte S_030014_LAST_LEVEL(state->u.tex.last_level) | S_030014_BASE_ARRAY(0) | S_030014_LAST_ARRAY(0), 0xffffffff, NULL); - r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, 0x0, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, + S_030018_MAX_ANISO(4 /* max 16 samples */), + 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, S_03001C_DATA_FORMAT(format) | S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE), 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index 670606d9b07..3e878106bea 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1027,6 +1027,9 @@ #define G_030014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) #define C_030014_LAST_ARRAY 0xC001FFFF #define R_030018_SQ_TEX_RESOURCE_WORD6_0 0x030018 +#define S_030018_MAX_ANISO(x) (((x) & 0x7) << 0) +#define G_030018_MAX_ANISO(x) (((x) >> 0) & 0x7) +#define C_030018_MAX_ANISO 0xFFFFFFF8 #define S_030018_PERF_MODULATION(x) (((x) & 0x7) << 3) #define G_030018_PERF_MODULATION(x) (((x) >> 3) & 0x7) #define C_030018_PERF_MODULATION 0xFFFFFFC7 @@ -1141,6 +1144,9 @@ #define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 15) #define G_03C000_MIP_FILTER(x) (((x) >> 15) & 0x3) #define C_03C000_MIP_FILTER 0xFFFE7FFF +#define S_03C000_MAX_ANISO(x) (((x) & 0x7) << 17) +#define G_03C000_MAX_ANISO(x) (((x) >> 17) & 0x7) +#define C_03C000_MAX_ANISO 0xFFF1FFFF #define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 20) #define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 20) & 0x3) #define C_03C000_BORDER_COLOR_TYPE 0xFFCFFFFF diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 33aa45088a8..7b57fc80dc2 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -193,8 +193,6 @@ struct r600_block { }; struct r600_range { - unsigned start_offset; - unsigned end_offset; struct r600_block **blocks; }; @@ -239,9 +237,7 @@ struct r600_query { struct r600_context { struct radeon *radeon; - unsigned hash_size; - unsigned hash_shift; - struct r600_range range[256]; + struct r600_range *range; unsigned nblocks; struct r600_block **blocks; struct list_head dirty; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index aa5ef4efb3b..0e4cfeb5b80 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -317,4 +317,13 @@ static INLINE u32 S_FIXED(float value, u32 frac_bits) } #define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) +static inline unsigned r600_tex_aniso_filter(unsigned filter) +{ + if (filter <= 1) return 0; + if (filter <= 2) return 1; + if (filter <= 4) return 2; + if (filter <= 8) return 3; + /* else */ return 4; +} + #endif diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index b9084c953ee..8098e489d0f 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -374,6 +374,7 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; + unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0; if (rstate == NULL) { return NULL; @@ -385,9 +386,10 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | - S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) | - S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter) | aniso_flag_offset) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter) | aniso_flag_offset) | S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_MAX_ANISO(r600_tex_aniso_filter(state->max_anisotropy)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, @@ -497,7 +499,8 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c S_038014_BASE_ARRAY(state->u.tex.first_layer) | S_038014_LAST_ARRAY(state->u.tex.last_layer), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6, - S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE), 0xFFFFFFFF, NULL); + S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) | + S_038018_MAX_ANISO(4 /* max 16 samples */), 0xFFFFFFFF, NULL); return &resource->base; } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 8296b52eb94..9281b08bd82 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -1012,6 +1012,9 @@ #define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0) #define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3) #define C_038018_MPEG_CLAMP 0xFFFFFFFC +#define S_038018_MAX_ANISO(x) (((x) & 0x7) << 2) +#define G_038018_MAX_ANISO(x) (((x) >> 2) & 0x7) +#define C_038018_MAX_ANISO 0xFFFFFFE3 #define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5) #define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7) #define C_038018_PERF_MODULATION 0xFFFFFF1F @@ -1090,6 +1093,9 @@ #define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17) #define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3) #define C_03C000_MIP_FILTER 0xFFF9FFFF +#define S_03C000_MAX_ANISO(x) (((x) & 0x7) << 19) +#define G_03C000_MAX_ANISO(x) (((x) >> 19) & 0x7) +#define C_03C000_MAX_ANISO 0xFFB7FFFF #define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22) #define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3) #define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF @@ -1152,6 +1158,9 @@ #define S_03C008_PERF_Z(x) (((x) & 0x3) << 18) #define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3) #define C_03C008_PERF_Z 0xFFF3FFFF +#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22) +#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f) +#define C_03C008_ANISO_BIAS (~(0x3f << 22)) #define S_03C008_FETCH_4(x) (((x) & 0x1) << 26) #define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1) #define C_03C008_FETCH_4 0xFBFFFFFF diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 02892c16bde..1446aee2aa4 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -2243,8 +2243,8 @@ sp_sampler_variant_bind_view( struct sp_sampler_variant *samp, samp->view = view; samp->cache = tex_cache; - samp->xpot = util_unsigned_logbase2( texture->width0 ); - samp->ypot = util_unsigned_logbase2( texture->height0 ); + samp->xpot = util_logbase2( texture->width0 ); + samp->ypot = util_logbase2( texture->height0 ); samp->level = view->u.tex.first_level; } |