summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/svga/svga_context.h2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c74
-rw-r--r--src/gallium/drivers/svga/svga_shader.h5
-rw-r--r--src/gallium/drivers/svga/svga_state_sampler.c21
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_vgpu10.c12
5 files changed, 78 insertions, 36 deletions
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 80c59c05e86..fd0c31222e6 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -211,7 +211,7 @@ struct svga_sampler_state {
unsigned view_min_lod;
unsigned view_max_lod;
- SVGA3dSamplerId id;
+ SVGA3dSamplerId id[2];
};
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index 2e98eb457e0..e9d1d6f4527 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -183,8 +183,6 @@ define_sampler_state_object(struct svga_context *svga,
COPY_4V(bcolor.value, ps->border_color.f);
- ss->id = util_bitmask_add(svga->sampler_object_id_bm);
-
assert(ps->min_lod <= ps->max_lod);
if (ps->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
@@ -196,24 +194,41 @@ define_sampler_state_object(struct svga_context *svga,
max_lod = ps->max_lod;
}
- /* Loop in case command buffer is full and we need to flush and retry */
- for (try = 0; try < 2; try++) {
- enum pipe_error ret =
- SVGA3D_vgpu10_DefineSamplerState(svga->swc,
- ss->id,
- filter,
- ss->addressu,
- ss->addressv,
- ss->addressw,
- ss->lod_bias, /* float */
- max_aniso,
- compare_func,
- bcolor,
- min_lod, /* float */
- max_lod); /* float */
- if (ret == PIPE_OK)
- return;
- svga_context_flush(svga, NULL);
+ /* If shadow comparisons are enabled, create two sampler states: one
+ * with the given shadow compare mode, another with shadow comparison off.
+ * We need the later because in some cases, we have to do the shadow
+ * compare in the shader. So, we don't want to do it twice.
+ */
+ STATIC_ASSERT(PIPE_TEX_COMPARE_NONE == 0);
+ STATIC_ASSERT(PIPE_TEX_COMPARE_R_TO_TEXTURE == 1);
+ ss->id[1] = SVGA3D_INVALID_ID;
+
+ unsigned i;
+ for (i = 0; i <= ss->compare_mode; i++) {
+ ss->id[i] = util_bitmask_add(svga->sampler_object_id_bm);
+
+ /* Loop in case command buffer is full and we need to flush and retry */
+ for (try = 0; try < 2; try++) {
+ enum pipe_error ret =
+ SVGA3D_vgpu10_DefineSamplerState(svga->swc,
+ ss->id[i],
+ filter,
+ ss->addressu,
+ ss->addressv,
+ ss->addressw,
+ ss->lod_bias, /* float */
+ max_aniso,
+ compare_func,
+ bcolor,
+ min_lod, /* float */
+ max_lod); /* float */
+ if (ret == PIPE_OK)
+ break;
+ svga_context_flush(svga, NULL);
+ }
+
+ /* turn off the shadow compare option for second iteration */
+ filter &= ~SVGA3D_FILTER_COMPARE;
}
}
@@ -332,16 +347,21 @@ svga_delete_sampler_state(struct pipe_context *pipe, void *sampler)
struct svga_context *svga = svga_context(pipe);
if (svga_have_vgpu10(svga)) {
- enum pipe_error ret;
+ unsigned i;
+ for (i = 0; i < 2; i++) {
+ enum pipe_error ret;
- svga_hwtnl_flush_retry(svga);
+ if (ss->id[i] != SVGA3D_INVALID_ID) {
+ svga_hwtnl_flush_retry(svga);
- ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id);
+ ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id[i]);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id[i]);
+ }
+ util_bitmask_clear(svga->sampler_object_id_bm, ss->id[i]);
+ }
}
- util_bitmask_clear(svga->sampler_object_id_bm, ss->id);
}
FREE(sampler);
diff --git a/src/gallium/drivers/svga/svga_shader.h b/src/gallium/drivers/svga/svga_shader.h
index dc462c94af6..70d12469827 100644
--- a/src/gallium/drivers/svga/svga_shader.h
+++ b/src/gallium/drivers/svga/svga_shader.h
@@ -158,6 +158,11 @@ struct svga_shader_variant
/** Is the color output just a constant value? (fragment shader only) */
boolean constant_color_output;
+ /** Bitmask indicating which texture units are doing the shadow
+ * comparison test in the shader rather than the sampler state.
+ */
+ unsigned fs_shadow_compare_units;
+
/** For FS-based polygon stipple */
unsigned pstipple_sampler_unit;
diff --git a/src/gallium/drivers/svga/svga_state_sampler.c b/src/gallium/drivers/svga/svga_state_sampler.c
index 763437d9b87..9bd0d5303bd 100644
--- a/src/gallium/drivers/svga/svga_state_sampler.c
+++ b/src/gallium/drivers/svga/svga_state_sampler.c
@@ -391,8 +391,21 @@ update_samplers(struct svga_context *svga, unsigned dirty )
unsigned nsamplers;
for (i = 0; i < count; i++) {
+ bool fs_shadow = false;
+
+ if (shader == PIPE_SHADER_FRAGMENT) {
+ struct svga_shader_variant *fs = svga->state.hw_draw.fs;
+ /* If the fragment shader is doing the shadow comparison
+ * for this texture unit, don't enable shadow compare in
+ * the texture sampler state.
+ */
+ if (fs->fs_shadow_compare_units & (1 << i)) {
+ fs_shadow = true;
+ }
+ }
+
if (svga->curr.sampler[shader][i]) {
- ids[i] = svga->curr.sampler[shader][i]->id;
+ ids[i] = svga->curr.sampler[shader][i]->id[fs_shadow];
assert(ids[i] != SVGA3D_INVALID_ID);
}
else {
@@ -435,18 +448,18 @@ update_samplers(struct svga_context *svga, unsigned dirty )
}
if (svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit]
- != sampler->id) {
+ != sampler->id[0]) {
ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
1, /* count */
unit, /* start */
SVGA3D_SHADERTYPE_PS,
- &sampler->id);
+ &sampler->id[0]);
if (ret != PIPE_OK)
return ret;
/* save the polygon stipple sampler in the hw draw state */
svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit] =
- sampler->id;
+ sampler->id[0];
}
}
diff --git a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
index c718eae8f3a..deb8e5a1eff 100644
--- a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
+++ b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
@@ -181,6 +181,9 @@ struct svga_shader_emitter_v10
unsigned fragcoord_input_index; /**< real fragment position input reg */
unsigned fragcoord_tmp_index; /**< 1/w modified position temp reg */
+
+ /** Which texture units are doing shadow comparison in the FS code */
+ unsigned shadow_compare_units;
} fs;
/* For geometry shaders only */
@@ -4851,6 +4854,8 @@ begin_tex_swizzle(struct svga_shader_emitter_v10 *emit,
}
swz->inst_dst = &inst->Dst[0];
swz->coord_src = &inst->Src[0];
+
+ emit->fs.shadow_compare_units |= shadow_compare << unit;
}
@@ -4909,11 +4914,8 @@ end_tex_swizzle(struct svga_shader_emitter_v10 *emit,
}
/* COMPARE tmp, coord, texel */
- /* XXX it would seem that the texel and coord arguments should
- * be transposed here, but piglit tests indicate otherwise.
- */
emit_comparison(emit, compare_func,
- &swz->tmp_dst, &texel_src, &coord_src);
+ &swz->tmp_dst, &coord_src, &texel_src);
/* AND dest, tmp, {1.0} */
begin_emit_instruction(emit);
@@ -6565,6 +6567,8 @@ svga_tgsi_vgpu10_translate(struct svga_context *svga,
}
}
+ variant->fs_shadow_compare_units = emit->fs.shadow_compare_units;
+
if (SVGA_DEBUG & DEBUG_TGSI) {
debug_printf("#####################################\n");
debug_printf("### TGSI Shader %u\n", shader->id);