[Mesa-dev] [PATCH 1/4] gallium/radeon: add clear_texture function

Jakob Sinclair sinclair.jakob at openmailbox.org
Fri Apr 15 16:33:23 UTC 2016


This patch adds the needed function for ARB_clear_texture.
The function itself is mostly based on the nouveau implementation.

Signed-off-by: Jakob Sinclair <sinclair.jakob at openmailbox.org>
---
 src/gallium/drivers/radeon/r600_texture.c | 72 +++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 72af534..ee77a37 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1392,6 +1392,77 @@ static void r600_surface_destroy(struct pipe_context *pipe,
 	FREE(surface);
 }
 
+static void r600_clear_texture(struct pipe_context *pipe,
+			struct pipe_resource *res,
+			unsigned level,
+			const struct pipe_box *box,
+			const void *data)
+{
+	struct pipe_surface tmpl = {{0}}, *sf;
+
+	tmpl.format = res->format;
+	tmpl.u.tex.first_layer = box->z;
+	tmpl.u.tex.last_layer = box->z + box->depth - 1;
+	tmpl.u.tex.level = level;
+	sf = pipe->create_surface(pipe, res, &tmpl);
+	if (!sf)
+		return;
+
+	if (util_format_is_depth_or_stencil(res->format)) {
+		float depth = 0;
+		uint8_t stencil = 0;
+		unsigned clear = 0;
+		const struct util_format_description *desc =
+		util_format_description(res->format);
+
+		if (util_format_has_depth(desc)) {
+			clear |= PIPE_CLEAR_DEPTH;
+			desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
+		}
+		if (util_format_has_stencil(desc)) {
+			clear |= PIPE_CLEAR_STENCIL;
+			desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+		}
+		pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
+					  box->x, box->y, box->width, box->height);
+	} else {
+		union pipe_color_union color;
+		switch (util_format_get_blocksizebits(res->format)) {
+		case 128:
+			sf->format = PIPE_FORMAT_R32G32B32A32_UINT;
+			memcpy(&color.ui, data, 128 / 8);
+			break;
+		case 64:
+			sf->format = PIPE_FORMAT_R32G32_UINT;
+			memcpy(&color.ui, data, 64 / 8);
+			memset(&color.ui[2], 0, 64 / 8);
+			break;
+		case 32:
+			sf->format = PIPE_FORMAT_R32_UINT;
+			memcpy(&color.ui, data, 32 / 8);
+			memset(&color.ui[1], 0, 96 / 8);
+			break;
+		case 16:
+			sf->format = PIPE_FORMAT_R16_UINT;
+			color.ui[0] = util_cpu_to_le32(
+			util_le16_to_cpu(*(unsigned short *)data));
+			memset(&color.ui[1], 0, 96 / 8);
+			break;
+		case 8:
+			sf->format = PIPE_FORMAT_R8_UINT;
+			color.ui[0] = util_cpu_to_le32(*(unsigned char *)data);
+			memset(&color.ui[1], 0, 96 / 8);
+			break;
+			default:
+			assert(!"Unknown texel element size");
+			return;
+	}
+		pipe->clear_render_target(pipe, sf, &color,
+					  box->x, box->y, box->width, box->height);
+	}
+	pipe->surface_destroy(pipe, sf);
+}
+
 unsigned r600_translate_colorswap(enum pipe_format format)
 {
 	const struct util_format_description *desc = util_format_description(format);
@@ -1658,4 +1729,5 @@ void r600_init_context_texture_functions(struct r600_common_context *rctx)
 {
 	rctx->b.create_surface = r600_create_surface;
 	rctx->b.surface_destroy = r600_surface_destroy;
+        rctx->b.clear_texture = r600_clear_texture;
 }
-- 
2.8.0



More information about the mesa-dev mailing list