Mesa (nvfx-next-6): nvfx: new 2D: add support for render temporaries

Luca Barbieri lb at kemper.freedesktop.org
Sun Apr 18 14:25:33 UTC 2010


Module: Mesa
Branch: nvfx-next-6
Commit: 47534d89ebfb589584fe786e38e99ed936988947
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=47534d89ebfb589584fe786e38e99ed936988947

Author: Luca Barbieri <luca at luca-barbieri.com>
Date:   Wed Mar 17 21:56:00 2010 +0100

nvfx: new 2D: add support for render temporaries

Use the render temporaries infrastructures introduced in the previous patch.

---

 src/gallium/drivers/nvfx/nvfx_context.c    |    6 ++
 src/gallium/drivers/nvfx/nvfx_context.h    |    3 +
 src/gallium/drivers/nvfx/nvfx_state_emit.c |   16 +++++
 src/gallium/drivers/nvfx/nvfx_state_fb.c   |   96 ++++++++++++---------------
 4 files changed, 68 insertions(+), 53 deletions(-)

diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c
index d4a3ac1..aee7587 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.c
+++ b/src/gallium/drivers/nvfx/nvfx_context.c
@@ -14,6 +14,9 @@ nvfx_flush(struct pipe_context *pipe, unsigned flags,
 	struct nouveau_channel *chan = screen->base.channel;
 	struct nouveau_grobj *eng3d = screen->eng3d;
 
+	if (flags & PIPE_FLUSH_RENDER_CACHE)
+		nvfx_surface_flush_render_cache(&nvfx->render_cache);
+
 	if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
 		BEGIN_RING(chan, eng3d, 0x1fd8, 1);
 		OUT_RING  (chan, 2);
@@ -80,5 +83,8 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
 	/* set these to that we init them on first validation */
 	nvfx->state.scissor_enabled = ~0;
 	nvfx->state.stipple_enabled = ~0;
+
+	LIST_INITHEAD(&nvfx->render_cache);
+
 	return &nvfx->pipe;
 }
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index 9b848b0..3acdd7a 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -11,6 +11,7 @@
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "util/u_inlines.h"
+#include "util/u_double_list.h"
 
 #include "draw/draw_vertex.h"
 
@@ -67,6 +68,7 @@ struct nvfx_state {
 	unsigned scissor_enabled;
 	unsigned stipple_enabled;
 	unsigned fp_samplers;
+	unsigned render_temps;
 };
 
 struct nvfx_vtxelt_state {
@@ -89,6 +91,7 @@ struct nvfx_context {
 	unsigned is_nv4x; /* either 0 or ~0 */
 
 	struct draw_context *draw;
+	struct list_head render_cache;
 
 	/* HW state derived from pipe states */
 	struct nvfx_state state;
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
index 4137849..8489b3e 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_emit.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -1,5 +1,6 @@
 #include "nvfx_context.h"
 #include "nvfx_state.h"
+#include "nvfx_resource.h"
 #include "draw/draw_context.h"
 
 static boolean
@@ -99,6 +100,21 @@ nvfx_state_emit(struct nvfx_context *nvfx)
 	      ;
 	MARK_RING(chan, max_relocs * 2, max_relocs * 2);
 	nvfx_state_relocate(nvfx);
+
+	unsigned render_temps = nvfx->state.render_temps;
+	if(render_temps)
+	{
+		for(int i = 0; i < nvfx->framebuffer.nr_cbufs; ++i)
+		{
+			if(render_temps & (1 << i))
+				nvfx_surface_use_render_temp(nvfx->framebuffer.cbufs[i], &nvfx->render_cache);
+		}
+
+		if(render_temps & 0x80)
+		{
+			nvfx_surface_use_render_temp(nvfx->framebuffer.zsbuf, &nvfx->render_cache);
+		}
+	}
 }
 
 void
diff --git a/src/gallium/drivers/nvfx/nvfx_state_fb.c b/src/gallium/drivers/nvfx/nvfx_state_fb.c
index e111d11..d13cf9f 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_fb.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_fb.c
@@ -1,6 +1,7 @@
 #include "nvfx_context.h"
 #include "nvfx_resource.h"
 #include "nouveau/nouveau_util.h"
+#include "util/u_format.h"
 
 void
 nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
@@ -9,11 +10,11 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
 	struct nouveau_channel *chan = nvfx->screen->base.channel;
 	uint32_t rt_enable = 0, rt_format = 0;
 	int i, colour_format = 0, zeta_format = 0;
-	int depth_only = 0;
 	unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
 	unsigned w = fb->width;
 	unsigned h = fb->height;
-	int colour_bits = 32, zeta_bits = 32;
+	int all_swizzled = 1;
+	int render_temps = 0;
 
 	if(!nvfx->is_nv4x)
 		assert(fb->nr_cbufs <= 2);
@@ -27,9 +28,23 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
 			colour_format = fb->cbufs[i]->format;
 
 		rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
-		nvfx->hw_rt[i].bo = ((struct nvfx_miptree*)fb->cbufs[i]->texture)->base.bo;
-		nvfx->hw_rt[i].offset = fb->cbufs[i]->offset;
-		nvfx->hw_rt[i].pitch = ((struct nvfx_surface *)fb->cbufs[i])->pitch;
+
+		if(((struct nvfx_miptree*)fb->cbufs[i]->texture)->linear_pitch
+				|| (fb->cbufs[i]->texture->target == PIPE_TEXTURE_3D && u_minify(fb->cbufs[i]->texture->depth0, fb->cbufs[0]->level) > 1)
+				|| (fb->cbufs[i]->offset & 63)
+				|| (fb->cbufs[i]->width != fb->width)
+				|| (fb->cbufs[i]->height != fb->height)
+				)
+			all_swizzled = 0;
+	}
+
+	for (i = 0; i < fb->nr_cbufs; i++)
+	{
+		nvfx_surface_get_render_target(fb->cbufs[i], all_swizzled, &nvfx->hw_rt[i]);
+		if(nvfx->hw_rt[i].bo != ((struct nvfx_miptree*)fb->cbufs[i]->texture)->base.bo)
+			render_temps |= (1 << i);
+		assert(util_format_get_stride(fb->cbufs[i]->format, fb->width) <= nvfx->hw_rt[i].pitch);
+		assert(all_swizzled || nvfx->hw_rt[i].offset + nvfx->hw_rt[i].pitch * fb->height <= nvfx->hw_rt[i].bo->size);
 	}
 	for(; i < 4; ++i)
 		nvfx->hw_rt[i].bo = 0;
@@ -40,44 +55,26 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
 
 	if (fb->zsbuf) {
 		zeta_format = fb->zsbuf->format;
-		nvfx->hw_zeta.bo = ((struct nvfx_miptree*)fb->zsbuf->texture)->base.bo;
-		nvfx->hw_zeta.offset = fb->zsbuf->offset;
-		nvfx->hw_zeta.pitch = ((struct nvfx_surface *)fb->zsbuf)->pitch;
-	}
-	else
-		nvfx->hw_zeta.bo = 0;
-
-	if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0 | NV34TCL_RT_ENABLE_COLOR1 |
-		NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3)) {
-		/* Render to at least a colour buffer */
-		if (!(fb->cbufs[0]->texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
-			assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
-			for (i = 1; i < fb->nr_cbufs; i++)
-				assert(!(fb->cbufs[i]->texture->flags & NVFX_RESOURCE_FLAG_LINEAR));
-
-			rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
-				(log2i(fb->cbufs[0]->width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
-				(log2i(fb->cbufs[0]->height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
-		}
-		else
-			rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
-	} else if (fb->zsbuf) {
-		depth_only = 1;
+		nvfx_surface_get_render_target(fb->zsbuf, 0, &nvfx->hw_zeta);
 
-		/* Render to depth buffer only */
-		if (!(fb->zsbuf->texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
-			assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
+		if(nvfx->hw_zeta.bo != ((struct nvfx_miptree*)fb->zsbuf->texture)->base.bo)
+			render_temps |= 0x80;
 
-			rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
-				(log2i(fb->zsbuf->width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
-				(log2i(fb->zsbuf->height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
-		}
-		else
-			rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
-	} else {
-		return;
+		assert(util_format_get_stride(fb->zsbuf->format, fb->width) <= nvfx->hw_zeta.pitch);
+		assert(nvfx->hw_zeta.offset + nvfx->hw_zeta.pitch * fb->height <= nvfx->hw_zeta.bo->size);
 	}
 
+	nvfx->state.render_temps = render_temps;
+
+	if (fb->nr_cbufs && all_swizzled) {
+		assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
+
+		rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
+			(log2i(fb->width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
+			(log2i(fb->height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
+	} else
+		rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
+
 	switch (colour_format) {
 	case PIPE_FORMAT_B8G8R8X8_UNORM:
 		rt_format |= NV34TCL_RT_FORMAT_COLOR_X8R8G8B8;
@@ -88,7 +85,6 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
 		break;
 	case PIPE_FORMAT_B5G6R5_UNORM:
 		rt_format |= NV34TCL_RT_FORMAT_COLOR_R5G6B5;
-		colour_bits = 16;
 		break;
 	default:
 		assert(0);
@@ -97,7 +93,6 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
 	switch (zeta_format) {
 	case PIPE_FORMAT_Z16_UNORM:
 		rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16;
-		zeta_bits = 16;
 		break;
 	case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
 	case PIPE_FORMAT_X8Z24_UNORM:
@@ -108,24 +103,19 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
 		assert(0);
 	}
 
-	if ((!nvfx->is_nv4x) && colour_bits > zeta_bits) {
-		/* TODO: does this limitation really exist?
-		   TODO: can it be worked around somehow? */
-		assert(0);
-	}
-
-	if ((rt_enable & NV34TCL_RT_ENABLE_COLOR0)
-		|| ((!nvfx->is_nv4x) && depth_only)) {
-		struct nvfx_render_target *rt0 = (depth_only ? &nvfx->hw_zeta : &nvfx->hw_rt[0]);
+	if ((rt_enable & NV34TCL_RT_ENABLE_COLOR0) || fb->zsbuf) {
+		struct nvfx_render_target *rt0 = &nvfx->hw_rt[0];
 		uint32_t pitch = rt0->pitch;
 
+		if(!(rt_enable & NV34TCL_RT_ENABLE_COLOR0))
+			rt0 = &nvfx->hw_zeta;
+
 		if(!nvfx->is_nv4x)
 		{
-			if (nvfx->hw_zeta.bo) {
+			if (nvfx->hw_zeta.bo)
 				pitch |= (nvfx->hw_zeta.pitch << 16);
-			} else {
+			else
 				pitch |= (pitch << 16);
-			}
 		}
 
 		OUT_RING(chan, RING_3D(NV34TCL_DMA_COLOR0, 1));




More information about the mesa-commit mailing list