summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-05-15 19:26:53 +0200
committerChristian König <[email protected]>2011-05-15 19:26:53 +0200
commit828540e491d88b9b6217e6568873a78462919ae8 (patch)
treec952145c1188cdf6b9c56902f8f5c189e090c278 /src/gallium/drivers
parent3db6514357a7c634045ae7bc7bba7d7dbf9d58c5 (diff)
parentbd5b7a6f7113da38a2c1f07a4a71e9993666a567 (diff)
Merge remote-tracking branch 'origin/master' into pipe-video
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.c2
-rw-r--r--src/gallium/drivers/i915/i915_screen.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_debug.c4
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c3
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc_optimize.c44
-rw-r--r--src/gallium/drivers/nvc0/nvc0_transfer.c3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c6
-rw-r--r--src/gallium/drivers/r300/r300_blit.c62
-rw-r--r--src/gallium/drivers/r300/r300_context.c26
-rw-r--r--src/gallium/drivers/r300/r300_context.h29
-rw-r--r--src/gallium/drivers/r300/r300_emit.c3
-rw-r--r--src/gallium/drivers/r300/r300_flush.c82
-rw-r--r--src/gallium/drivers/r300/r300_hyperz.c94
-rw-r--r--src/gallium/drivers/r300/r300_state.c15
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c2
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c10
-rw-r--r--src/gallium/drivers/r600/evergreend.h6
-rw-r--r--src/gallium/drivers/r600/r600.h6
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h9
-rw-r--r--src/gallium/drivers/r600/r600_state.c9
-rw-r--r--src/gallium/drivers/r600/r600d.h9
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c4
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;
}