nv50, nvc0: clear out RT on a null cbuf
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 15 Jan 2014 07:14:06 +0000 (02:14 -0500)
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>
Mon, 27 Jan 2014 15:40:42 +0000 (16:40 +0100)
This is needed since commit 9baa45f78b (st/mesa: bind NULL colorbuffers
as specified by glDrawBuffers).

This implementation is highly based on a larger commit by
Christoph Bumiller <e0425955@student.tuwien.ac.at> in his gallium-nine
branch.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
src/gallium/drivers/nouveau/nv50/nv50_defs.xml.h
src/gallium/drivers/nouveau/nv50/nv50_formats.c
src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c

index 2e42843fa56cf66268272f904e12848a8d46cbc4..80de3be9a7d7cb921f098fbc70060faf2783e9d8 100644 (file)
@@ -78,6 +78,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_VSTATUS_BLOCKED                                   0x00000005
 #define NV50_VSTATUS_FAULTED                                   0x00000006
 #define NV50_VSTATUS_PAUSED                                    0x00000007
+#define NV50_SURFACE_FORMAT_NONE                               0x00000000
 #define NV50_SURFACE_FORMAT_BITMAP                             0x0000001c
 #define NV50_SURFACE_FORMAT_UNK1D                              0x0000001d
 #define NV50_SURFACE_FORMAT_RGBA32_FLOAT                       0x000000c0
index 0a7e812ba13f02ccef14ab0d16b63c54baeb2d80..d21905dae5a1fe2f2603447ecc5bea2d24ae92d3 100644 (file)
@@ -71,7 +71,6 @@
 # define U_tV  U_V
 #endif
 
-#define NV50_SURFACE_FORMAT_NONE 0
 #define NV50_ZETA_FORMAT_NONE 0
 
 /* for vertex buffers: */
index 86b9a236fb679a795c1a07be74b9c28a62f880fa..bb05f033b8135499b1606ad93e7542f250f99aa5 100644 (file)
@@ -1,6 +1,19 @@
 
 #include "nv50/nv50_context.h"
-#include "os/os_time.h"
+#include "nv50/nv50_defs.xml.h"
+
+static INLINE void
+nv50_fb_set_null_rt(struct nouveau_pushbuf *push, unsigned i)
+{
+   BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 4);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, NV50_SURFACE_FORMAT_NONE);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
+   PUSH_DATA (push, 64);
+   PUSH_DATA (push, 0);
+}
 
 static void
 nv50_validate_fb(struct nv50_context *nv50)
@@ -20,9 +33,18 @@ nv50_validate_fb(struct nv50_context *nv50)
    PUSH_DATA (push, fb->height << 16);
 
    for (i = 0; i < fb->nr_cbufs; ++i) {
-      struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
-      struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
-      struct nouveau_bo *bo = mt->base.bo;
+      struct nv50_miptree *mt;
+      struct nv50_surface *sf;
+      struct nouveau_bo *bo;
+
+      if (!fb->cbufs[i]) {
+         nv50_fb_set_null_rt(push, i);
+         continue;
+      }
+
+      mt = nv50_miptree(fb->cbufs[i]->texture);
+      sf = nv50_surface(fb->cbufs[i]);
+      bo = mt->base.bo;
 
       array_size = MIN2(array_size, sf->depth);
       if (mt->layout_3d)
index 0ba4bad154a89366aa302127517ac7ef6d4c6e84..dd71c6587a63315e426fa2ed2379ead85ef96bc5 100644 (file)
@@ -2,6 +2,7 @@
 #include "util/u_math.h"
 
 #include "nvc0/nvc0_context.h"
+#include "nv50/nv50_defs.xml.h"
 
 #if 0
 static void
@@ -54,6 +55,18 @@ nvc0_validate_zcull(struct nvc0_context *nvc0)
 }
 #endif
 
+static INLINE void
+nvc0_fb_set_null_rt(struct nouveau_pushbuf *push, unsigned i)
+{
+   BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 6);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 64);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, NV50_SURFACE_FORMAT_NONE);
+   PUSH_DATA (push, 0);
+}
+
 static void
 nvc0_validate_fb(struct nvc0_context *nvc0)
 {
@@ -72,9 +85,18 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
     PUSH_DATA (push, fb->height << 16);
 
     for (i = 0; i < fb->nr_cbufs; ++i) {
-        struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
-        struct nv04_resource *res = nv04_resource(sf->base.texture);
-        struct nouveau_bo *bo = res->bo;
+        struct nv50_surface *sf;
+        struct nv04_resource *res;
+        struct nouveau_bo *bo;
+
+        if (!fb->cbufs[i]) {
+           nvc0_fb_set_null_rt(push, i);
+           continue;
+        }
+
+        sf = nv50_surface(fb->cbufs[i]);
+        res = nv04_resource(sf->base.texture);
+        bo = res->bo;
 
         BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 9);
         PUSH_DATAh(push, res->address + sf->offset);