[Mesa-dev] [PATCH] llvmpipe: Support Z16_UNORM as depth-stencil format.
jfonseca at vmware.com
jfonseca at vmware.com
Mon Jan 28 11:10:22 PST 2013
From: José Fonseca <jfonseca at vmware.com>
Simply by adjusting the vector element width after/before
reading/writing the depth-stencil values.
Ran several GL_DEPTH_COMPONENT16 piglit tests without regressions.
---
src/gallium/drivers/llvmpipe/lp_bld_depth.c | 46 ++++++++++++++++++++-------
src/gallium/drivers/llvmpipe/lp_bld_depth.h | 3 +-
src/gallium/drivers/llvmpipe/lp_screen.c | 8 ++---
src/gallium/drivers/llvmpipe/lp_state_fs.c | 8 ++---
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 5c3715a..1c899b3 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 e01fc46..33cb0dd 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 872967c..de80c6f 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 09f37e0..00f3b69 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) &&
--
1.7.9.5
More information about the mesa-dev
mailing list