summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2013-01-28 19:10:22 +0000
committerJosé Fonseca <[email protected]>2013-01-29 07:06:36 +0000
commit0ca384fb39f6d98af2de5654c46394743147d228 (patch)
treeb258feddab93dd6601564c04ed9a322d1065a5f4
parent9add4e803877f97ad7f6d479d81d537426f09b6f (diff)
llvmpipe: Support Z16_UNORM as depth-stencil format.
Simply by adjusting the vector element width after/before reading/writing the depth-stencil values. Ran several GL_DEPTH_COMPONENT16 piglit tests without regressions. Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]>
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_depth.c46
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_depth.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c8
4 files changed, 43 insertions, 22 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
index 5c3715aa8fb..1c899b31cc9 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
@@ -299,7 +299,7 @@ lp_build_stencil_op(struct lp_build_context *bld,
/**
- * Return a type appropriate for depth/stencil testing.
+ * Return a type that matches the depth/stencil format.
*/
struct lp_type
lp_depth_type(const struct util_format_description *format_desc,
@@ -336,8 +336,7 @@ lp_depth_type(const struct util_format_description *format_desc,
else
assert(0);
- assert(type.width <= length);
- type.length = length / type.width;
+ type.length = length;
return type;
}
@@ -546,6 +545,7 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
boolean do_branch)
{
LLVMBuilderRef builder = gallivm->builder;
+ struct lp_type zs_type;
struct lp_type z_type;
struct lp_build_context z_bld;
struct lp_build_context s_bld;
@@ -573,11 +573,14 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
assert(z_src_type.norm);
}
- /* Pick the depth type. */
- z_type = lp_depth_type(format_desc, z_src_type.width*z_src_type.length);
+ /* Pick the type matching the depth-stencil format. */
+ zs_type = lp_depth_type(format_desc, z_src_type.length);
- /* FIXME: Cope with a depth test type with a different bit width. */
- assert(z_type.width == z_src_type.width);
+ /* Pick the intermediate type for depth operations. */
+ z_type = zs_type;
+ /* FIXME: Cope with a depth test type with higher bit width. */
+ assert(zs_type.width <= z_src_type.width);
+ z_type.width = z_src_type.width;
assert(z_type.length == z_src_type.length);
/* FIXME: for non-float depth/stencil might generate better code
@@ -606,7 +609,7 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
}
assert(z_swizzle < 4);
- assert(format_desc->block.bits == z_type.width);
+ assert(format_desc->block.bits <= z_type.width);
if (z_type.floating) {
assert(z_swizzle == 0);
assert(format_desc->channel[z_swizzle].type ==
@@ -633,8 +636,12 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
/* Load current z/stencil value from z/stencil buffer */
zs_dst_ptr = LLVMBuildBitCast(builder,
zs_dst_ptr,
- LLVMPointerType(z_bld.vec_type, 0), "");
+ LLVMPointerType(lp_build_vec_type(gallivm, zs_type), 0), "");
zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, "");
+ if (format_desc->block.bits < z_type.width) {
+ /* Extend destination ZS values (e.g., when reading from Z16_UNORM) */
+ zs_dst = LLVMBuildZExt(builder, zs_dst, z_bld.vec_type, "");
+ }
lp_build_name(zs_dst, "zs_dst");
@@ -850,11 +857,23 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
void
-lp_build_depth_write(LLVMBuilderRef builder,
+lp_build_depth_write(struct gallivm_state *gallivm,
+ struct lp_type z_src_type,
const struct util_format_description *format_desc,
LLVMValueRef zs_dst_ptr,
LLVMValueRef zs_value)
{
+ LLVMBuilderRef builder = gallivm->builder;
+
+ if (format_desc->block.bits < z_src_type.width) {
+ /* Truncate income ZS values (e.g., when writing to Z16_UNORM) */
+ LLVMTypeRef zs_type = LLVMIntTypeInContext(gallivm->context, format_desc->block.bits);
+ if (z_src_type.length > 1) {
+ zs_type = LLVMVectorType(zs_type, z_src_type.length);
+ }
+ zs_value = LLVMBuildTrunc(builder, zs_value, zs_type, "");
+ }
+
zs_dst_ptr = LLVMBuildBitCast(builder, zs_dst_ptr,
LLVMPointerType(LLVMTypeOf(zs_value), 0), "");
@@ -877,13 +896,18 @@ lp_build_deferred_depth_write(struct gallivm_state *gallivm,
/* XXX: pointlessly redo type logic:
*/
- z_type = lp_depth_type(format_desc, z_src_type.width*z_src_type.length);
+ z_type = lp_depth_type(format_desc, z_src_type.length);
lp_build_context_init(&z_bld, gallivm, z_type);
zs_dst_ptr = LLVMBuildBitCast(builder, zs_dst_ptr,
LLVMPointerType(z_bld.vec_type, 0), "");
z_dst = LLVMBuildLoad(builder, zs_dst_ptr, "zsbufval");
+
+ if (z_type.width < z_src_type.width) {
+ zs_value = LLVMBuildTrunc(builder, zs_value, z_bld.vec_type, "");
+ }
+
z_dst = lp_build_select(&z_bld, lp_build_mask_value(mask), zs_value, z_dst);
LLVMBuildStore(builder, z_dst, zs_dst_ptr);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.h b/src/gallium/drivers/llvmpipe/lp_bld_depth.h
index e01fc46ec16..33cb0dd4a9e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_depth.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.h
@@ -69,7 +69,8 @@ lp_build_depth_stencil_test(struct gallivm_state *gallivm,
boolean do_branch);
void
-lp_build_depth_write(LLVMBuilderRef builder,
+lp_build_depth_write(struct gallivm_state *gallivm,
+ struct lp_type z_src_type,
const struct util_format_description *format_desc,
LLVMValueRef zs_dst_ptr,
LLVMValueRef zs_value);
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 872967caeef..de80c6fdc6b 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -302,10 +302,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
if (!format_desc)
return FALSE;
- /* Z16 support is missing, which breaks the blit */
- if (format == PIPE_FORMAT_Z16_UNORM)
- return FALSE;
-
assert(target == PIPE_BUFFER ||
target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_1D_ARRAY ||
@@ -360,8 +356,8 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
- /* FIXME: Temporary restriction. See lp_state_fs.c. */
- if (format_desc->block.bits != 32)
+ /* FIXME: Temporary restriction. See lp_bld_depth.c. */
+ if (format_desc->block.bits > 32)
return FALSE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 09f37e0cead..00f3b6990e3 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -335,7 +335,7 @@ generate_fs(struct gallivm_state *gallivm,
!simple_shader);
if (depth_mode & EARLY_DEPTH_WRITE) {
- lp_build_depth_write(builder, zs_format_desc, depth_ptr, zs_value);
+ lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr, zs_value);
}
}
@@ -392,7 +392,7 @@ generate_fs(struct gallivm_state *gallivm,
!simple_shader);
/* Late Z write */
if (depth_mode & LATE_DEPTH_WRITE) {
- lp_build_depth_write(builder, zs_format_desc, depth_ptr, zs_value);
+ lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr, zs_value);
}
}
else if ((depth_mode & EARLY_DEPTH_TEST) &&
@@ -574,7 +574,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
!simple_shader);
if (depth_mode & EARLY_DEPTH_WRITE) {
- lp_build_depth_write(builder, zs_format_desc, depth_ptr_i, zs_value);
+ lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr_i, zs_value);
}
}
@@ -631,7 +631,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
!simple_shader);
/* Late Z write */
if (depth_mode & LATE_DEPTH_WRITE) {
- lp_build_depth_write(builder, zs_format_desc, depth_ptr_i, zs_value);
+ lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr_i, zs_value);
}
}
else if ((depth_mode & EARLY_DEPTH_TEST) &&