gallium: Put no.of {samples,layers} into pipe_framebuffer_state
authorEdward O'Callaghan <eocallaghan@alterapraxis.com>
Sat, 2 Jan 2016 14:44:55 +0000 (01:44 +1100)
committerDave Airlie <airlied@redhat.com>
Thu, 7 Apr 2016 02:03:58 +0000 (12:03 +1000)
Here we store the number of samples and layers directly in the
pipe_framebuffer_state so that in the case of
ARB_framebuffer_no_attachment we may make use of them directly.

Further, we adjust various gallium/auxiliary helper functions
accordingly.

V2:
  Convert branches in util_framebuffer_get_num_layers() and
  util_framebuffer_get_num_samples() to their canonical form.

V3:
  'git stash pop' the typo fix of 'cbufs' which should be
  'nr_cbufs' that was missing in V2, woops! Thanks Marek for
  pointing this out yet again.

V4:
  Squash in the following patch:

  'gallium/util: Ensure util_framebuffer_get_num_samples() is valid'

   Upon context creation, internal driver structures are malloc()'ed
   and memset() to zero them. This results in a invalid number of
   samples 'by default'. Handle this in the simplest way to avoid
   elaborate and probably equally sub-optimial solutions.

Signed-off-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/auxiliary/util/u_framebuffer.c
src/gallium/include/pipe/p_state.h

index a73a1de2f0b2d12cb6b89d467e7fd7d81e4e7e36..b1f3982fb4ef48f9054a0e44c78ceb1ca05060a9 100644 (file)
@@ -645,6 +645,8 @@ util_dump_framebuffer_state(FILE *stream, const struct pipe_framebuffer_state *s
 
    util_dump_member(stream, uint, state, width);
    util_dump_member(stream, uint, state, height);
+   util_dump_member(stream, uint, state, samples);
+   util_dump_member(stream, uint, state, layers);
    util_dump_member(stream, uint, state, nr_cbufs);
    util_dump_member_array(stream, ptr, state, cbufs);
    util_dump_member(stream, ptr, state, zsbuf);
index 49b391d8162212c25ba8c71202d2180e04e0eac3..f9b804673dc991c01e09ed4ff3474c7d7418ad9c 100644 (file)
@@ -55,6 +55,10 @@ util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
        dst->height != src->height)
       return FALSE;
 
+   if (dst->samples != src->samples ||
+       dst->layers  != src->layers)
+      return FALSE;
+
    if (dst->nr_cbufs != src->nr_cbufs) {
       return FALSE;
    }
@@ -85,6 +89,9 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
    dst->width = src->width;
    dst->height = src->height;
 
+   dst->samples = src->samples;
+   dst->layers  = src->layers;
+
    for (i = 0; i < src->nr_cbufs; i++)
       pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
 
@@ -109,6 +116,7 @@ util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
 
    pipe_surface_reference(&fb->zsbuf, NULL);
 
+   fb->samples = fb->layers = 0;
    fb->width = fb->height = 0;
    fb->nr_cbufs = 0;
 }
@@ -160,6 +168,14 @@ util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb)
 {
        unsigned i, num_layers = 0;
 
+       /**
+        * In the case of ARB_framebuffer_no_attachment
+        * we obtain the number of layers directly from
+        * the framebuffer state.
+        */
+       if (!(fb->nr_cbufs || fb->zsbuf))
+               return fb->layers;
+
        for (i = 0; i < fb->nr_cbufs; i++) {
                if (fb->cbufs[i]) {
                        unsigned num = fb->cbufs[i]->u.tex.last_layer -
@@ -184,6 +200,20 @@ util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb)
 {
    unsigned i;
 
+   /**
+    * In the case of ARB_framebuffer_no_attachment
+    * we obtain the number of samples directly from
+    * the framebuffer state.
+    *
+    * NOTE: fb->samples may wind up as zero due to memset()'s on internal
+    *       driver structures on their initialization and so we take the
+    *       MAX here to ensure we have a valid number of samples. However,
+    *       if samples is legitimately not getting set somewhere
+    *       multi-sampling will evidently break.
+    */
+   if (!(fb->nr_cbufs || fb->zsbuf))
+      return MAX2(fb->samples, 1);
+
    for (i = 0; i < fb->nr_cbufs; i++) {
       if (fb->cbufs[i]) {
          return MAX2(1, fb->cbufs[i]->texture->nr_samples);
index 5ab53728e82c3b1b24b41dca22e47577ae59cc8d..cb806cb6550ab45ccfedd037cfce8c329c841216 100644 (file)
@@ -298,9 +298,17 @@ struct pipe_stencil_ref
 };
 
 
+/**
+ * Note that pipe_surfaces are "texture views for rendering"
+ * and so in the case of ARB_framebuffer_no_attachment there
+ * is no pipe_surface state available such that we may
+ * extract the number of samples and layers.
+ */
 struct pipe_framebuffer_state
 {
    unsigned width, height;
+   unsigned samples; /**< Number of samples in a no-attachment framebuffer */
+   unsigned layers;  /**< Number of layers  in a no-attachment framebuffer */
 
    /** multiple color buffers for multiple render targets */
    unsigned nr_cbufs;