summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/util/u_transfer_helper.c63
-rw-r--r--src/gallium/auxiliary/util/u_transfer_helper.h11
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c2
-rw-r--r--src/gallium/drivers/v3d/v3d_resource.c3
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c3
5 files changed, 60 insertions, 22 deletions
diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c
index df67f828852..14c4d56392d 100644
--- a/src/gallium/auxiliary/util/u_transfer_helper.c
+++ b/src/gallium/auxiliary/util/u_transfer_helper.c
@@ -33,7 +33,8 @@
struct u_transfer_helper {
const struct u_transfer_vtbl *vtbl;
- bool separate_z32s8;
+ bool separate_z32s8; /**< separate z32 and s8 */
+ bool separate_stencil; /**< separate stencil for all formats */
bool fake_rgtc;
bool msaa_map;
};
@@ -88,11 +89,12 @@ u_transfer_helper_resource_create(struct pipe_screen *pscreen,
enum pipe_format format = templ->format;
struct pipe_resource *prsc;
- if ((format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) && helper->separate_z32s8) {
+ if ((helper->separate_stencil && util_format_is_depth_and_stencil(format)) ||
+ (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && helper->separate_z32s8)) {
struct pipe_resource t = *templ;
struct pipe_resource *stencil;
- t.format = PIPE_FORMAT_Z32_FLOAT;
+ t.format = util_format_get_depth_only(format);
prsc = helper->vtbl->resource_create(pscreen, &t);
if (!prsc)
@@ -266,22 +268,37 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx,
if (!trans->ptr)
goto fail;
- if (prsc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
+ if (util_format_is_depth_and_stencil(prsc->format)) {
struct pipe_resource *stencil = helper->vtbl->get_stencil(prsc);
trans->ptr2 = helper->vtbl->transfer_map(pctx, stencil, level,
usage, box, &trans->trans2);
if (needs_pack(usage)) {
- util_format_z32_float_s8x24_uint_pack_z_float(trans->staging,
- ptrans->stride,
- trans->ptr,
- trans->trans->stride,
- width, height);
- util_format_z32_float_s8x24_uint_pack_s_8uint(trans->staging,
- ptrans->stride,
- trans->ptr2,
- trans->trans2->stride,
- width, height);
+ switch (prsc->format) {
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ util_format_z32_float_s8x24_uint_pack_z_float(trans->staging,
+ ptrans->stride,
+ trans->ptr,
+ trans->trans->stride,
+ width, height);
+ util_format_z32_float_s8x24_uint_pack_s_8uint(trans->staging,
+ ptrans->stride,
+ trans->ptr2,
+ trans->trans2->stride,
+ width, height);
+ break;
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ util_format_z24_unorm_s8_uint_pack_separate(trans->staging,
+ ptrans->stride,
+ trans->ptr,
+ trans->trans->stride,
+ trans->ptr2,
+ trans->trans2->stride,
+ width, height);
+ break;
+ default:
+ unreachable("Unexpected format");
+ }
}
} else if (needs_pack(usage) &&
util_format_description(prsc->format)->layout == UTIL_FORMAT_LAYOUT_RGTC) {
@@ -395,6 +412,22 @@ flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans,
ptrans->stride,
width, height);
break;
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ /* just do a strided 32-bit copy for depth; s8 can become garbage x8 */
+ util_format_z32_unorm_unpack_z_32unorm(dst, trans->trans->stride,
+ src, ptrans->stride,
+ width, height);
+ /* fallthru */
+ case PIPE_FORMAT_X24S8_UINT:
+ dst = (uint8_t *)trans->ptr2 +
+ (box->y * trans->trans2->stride) +
+ (box->x * util_format_get_blocksize(PIPE_FORMAT_S8_UINT));
+
+ util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, trans->trans2->stride,
+ src, ptrans->stride,
+ width, height);
+ break;
+
case PIPE_FORMAT_RGTC1_UNORM:
case PIPE_FORMAT_RGTC1_SNORM:
case PIPE_FORMAT_LATC1_UNORM:
@@ -487,6 +520,7 @@ u_transfer_helper_transfer_unmap(struct pipe_context *pctx,
struct u_transfer_helper *
u_transfer_helper_create(const struct u_transfer_vtbl *vtbl,
bool separate_z32s8,
+ bool separate_stencil,
bool fake_rgtc,
bool msaa_map)
{
@@ -494,6 +528,7 @@ u_transfer_helper_create(const struct u_transfer_vtbl *vtbl,
helper->vtbl = vtbl;
helper->separate_z32s8 = separate_z32s8;
+ helper->separate_stencil = separate_stencil;
helper->fake_rgtc = fake_rgtc;
helper->msaa_map = msaa_map;
diff --git a/src/gallium/auxiliary/util/u_transfer_helper.h b/src/gallium/auxiliary/util/u_transfer_helper.h
index b13a1ec06c1..9e5f889f9d8 100644
--- a/src/gallium/auxiliary/util/u_transfer_helper.h
+++ b/src/gallium/auxiliary/util/u_transfer_helper.h
@@ -33,7 +33,7 @@ extern "C" {
/* A helper to implement various "lowering" for transfers:
*
- * - exposing separate z32 and s8 as z32x24s8
+ * - exposing separate depth and stencil resources as packed depth-stencil
* - fake RGTC support for GLES class hardware which needs it to expose GL3+
* - MSAA resolves
*
@@ -79,16 +79,16 @@ struct u_transfer_vtbl {
*/
/**
- * Must be implemented if separate_z32s8 or fake_rgtc is used. The
+ * Must be implemented if separate stencil or fake_rgtc is used. The
* internal_format is the format the resource was created with. In
- * the case of separate_z32s8 or fake_rgtc, prsc->format is set back
- * to the state tracker visible format (Z32_FLOAT_S8X24_UINT or
+ * the case of separate stencil or fake_rgtc, prsc->format is set back
+ * to the state tracker visible format (e.g. Z32_FLOAT_S8X24_UINT or
* PIPE_FORMAT_{RTGC,LATC}* after the resource is created.
*/
enum pipe_format (*get_internal_format)(struct pipe_resource *prsc);
/**
- * Must be implemented if separate_z32s8 is used. Used to set/get
+ * Must be implemented if separate stencil is lowered. Used to set/get
* the separate s8 stencil buffer.
*
* These two do not get/put references to the pipe_resource. The
@@ -123,6 +123,7 @@ struct u_transfer_helper;
struct u_transfer_helper * u_transfer_helper_create(const struct u_transfer_vtbl *vtbl,
bool separate_z32s8,
+ bool separate_stencil,
bool fake_rgtc,
bool msaa_map);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 8fbc7819303..c82be3e2032 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -1183,7 +1183,7 @@ fd_resource_screen_init(struct pipe_screen *pscreen)
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
- true, fake_rgtc, true);
+ true, false, fake_rgtc, true);
if (!screen->setup_slices)
screen->setup_slices = fd_setup_slices;
diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c
index 8bf6a97c394..dd0db8cfd89 100644
--- a/src/gallium/drivers/v3d/v3d_resource.c
+++ b/src/gallium/drivers/v3d/v3d_resource.c
@@ -909,7 +909,8 @@ v3d_resource_screen_init(struct pipe_screen *pscreen)
pscreen->resource_get_handle = v3d_resource_get_handle;
pscreen->resource_destroy = u_transfer_helper_resource_destroy;
pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
- true, true, true);
+ true, false,
+ true, true);
}
void
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index e169303f4a3..94784bbdc0a 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -1129,7 +1129,8 @@ vc4_resource_screen_init(struct pipe_screen *pscreen)
pscreen->resource_get_handle = vc4_resource_get_handle;
pscreen->resource_destroy = vc4_resource_destroy;
pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
- false, false, true);
+ false, false,
+ false, true);
/* Test if the kernel has GET_TILING; it will return -EINVAL if the
* ioctl does not exist, but -ENOENT if we pass an impossible handle.