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) {
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;
}
}
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);
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 {
}
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];
}
}
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 */
}
swz->inst_dst = &inst->Dst[0];
swz->coord_src = &inst->Src[0];
+
+ emit->fs.shadow_compare_units |= shadow_compare << unit;
}
}
/* 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);
}
}
+ 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);