[Mesa-dev] [PATCH 14/21] u_vbuf: make use of the new CAPs to determine what to do

Marek Olšák maraeo at gmail.com
Wed Apr 11 08:38:48 PDT 2012


This adds the ability to initialize u_vbuf_caps before creating u_vbuf itself.
It will be useful for determining if u_vbuf should be used or not.

Also adapt r300g and r600g.
---
 src/gallium/auxiliary/util/u_vbuf.c     |   51 +++++++++++++++++-------------
 src/gallium/auxiliary/util/u_vbuf.h     |   14 ++++-----
 src/gallium/drivers/r300/r300_context.c |   11 ++++--
 src/gallium/drivers/r300/r300_screen.c  |    4 ++
 src/gallium/drivers/r600/r600_pipe.c    |   18 +++++++----
 5 files changed, 58 insertions(+), 40 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 2482c8a..31f670c 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -68,6 +68,7 @@ enum {
 
 struct u_vbuf_priv {
    struct u_vbuf b;
+   struct u_vbuf_caps caps;
    struct pipe_context *pipe;
    struct translate_cache *translate_cache;
    struct cso_cache *cso_cache;
@@ -114,46 +115,56 @@ struct u_vbuf_priv {
                            const struct pipe_draw_info *info);
 };
 
-static void u_vbuf_init_format_caps(struct u_vbuf_priv *mgr)
+void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
 {
-   struct pipe_screen *screen = mgr->pipe->screen;
-
-   mgr->b.caps.format_fixed32 =
+   caps->format_fixed32 =
       screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER);
 
-   mgr->b.caps.format_float16 =
+   caps->format_float16 =
       screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER);
 
-   mgr->b.caps.format_float64 =
+   caps->format_float64 =
       screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER);
 
-   mgr->b.caps.format_norm32 =
+   caps->format_norm32 =
       screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER) &&
       screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER);
 
-   mgr->b.caps.format_scaled32 =
+   caps->format_scaled32 =
       screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER) &&
       screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
                                   0, PIPE_BIND_VERTEX_BUFFER);
+
+   caps->fetch_dword_unaligned =
+      !screen->get_param(screen,
+                        PIPE_CAP_VERTEX_BUFFER_OFFSET_DWORD_ALIGNED_ONLY) &&
+      !screen->get_param(screen,
+                        PIPE_CAP_VERTEX_BUFFER_STRIDE_DWORD_ALIGNED_ONLY) &&
+      !screen->get_param(screen,
+                        PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_DWORD_ALIGNED_ONLY);
+
+   caps->user_vertex_buffers =
+      screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS);
 }
 
 static void u_vbuf_install(struct u_vbuf_priv *mgr);
 
 struct u_vbuf *
 u_vbuf_create(struct pipe_context *pipe,
+              struct u_vbuf_caps *caps,
               unsigned upload_buffer_size,
               unsigned upload_buffer_alignment,
-              unsigned upload_buffer_bind,
-              enum u_fetch_alignment fetch_alignment)
+              unsigned upload_buffer_bind)
 {
    struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv);
 
+   mgr->caps = *caps;
    mgr->pipe = pipe;
    mgr->cso_cache = cso_cache_create();
    mgr->translate_cache = translate_cache_create();
@@ -163,10 +174,6 @@ u_vbuf_create(struct pipe_context *pipe,
                                      upload_buffer_alignment,
                                      upload_buffer_bind);
 
-   mgr->b.caps.fetch_dword_unaligned =
-         fetch_alignment == U_VERTEX_FETCH_BYTE_ALIGNED;
-
-   u_vbuf_init_format_caps(mgr);
    u_vbuf_install(mgr);
    return &mgr->b;
 }
@@ -588,7 +595,7 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
       /* Choose a native format.
        * For now we don't care about the alignment, that's going to
        * be sorted out later. */
-      if (!mgr->b.caps.format_fixed32) {
+      if (!mgr->caps.format_fixed32) {
          switch (format) {
             FORMAT_REPLACE(R32_FIXED,           R32_FLOAT);
             FORMAT_REPLACE(R32G32_FIXED,        R32G32_FLOAT);
@@ -597,7 +604,7 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
             default:;
          }
       }
-      if (!mgr->b.caps.format_float16) {
+      if (!mgr->caps.format_float16) {
          switch (format) {
             FORMAT_REPLACE(R16_FLOAT,           R32_FLOAT);
             FORMAT_REPLACE(R16G16_FLOAT,        R32G32_FLOAT);
@@ -606,7 +613,7 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
             default:;
          }
       }
-      if (!mgr->b.caps.format_float64) {
+      if (!mgr->caps.format_float64) {
          switch (format) {
             FORMAT_REPLACE(R64_FLOAT,           R32_FLOAT);
             FORMAT_REPLACE(R64G64_FLOAT,        R32G32_FLOAT);
@@ -615,7 +622,7 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
             default:;
          }
       }
-      if (!mgr->b.caps.format_norm32) {
+      if (!mgr->caps.format_norm32) {
          switch (format) {
             FORMAT_REPLACE(R32_UNORM,           R32_FLOAT);
             FORMAT_REPLACE(R32G32_UNORM,        R32G32_FLOAT);
@@ -628,7 +635,7 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
             default:;
          }
       }
-      if (!mgr->b.caps.format_scaled32) {
+      if (!mgr->caps.format_scaled32) {
          switch (format) {
             FORMAT_REPLACE(R32_USCALED,         R32_FLOAT);
             FORMAT_REPLACE(R32G32_USCALED,      R32G32_FLOAT);
@@ -649,14 +656,14 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
 
       ve->incompatible_layout_elem[i] =
             ve->ve[i].src_format != ve->native_format[i] ||
-            (!mgr->b.caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0);
+            (!mgr->caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0);
       ve->incompatible_layout =
             ve->incompatible_layout ||
             ve->incompatible_layout_elem[i];
    }
 
    /* Align the formats to the size of DWORD if needed. */
-   if (!mgr->b.caps.fetch_dword_unaligned) {
+   if (!mgr->caps.fetch_dword_unaligned) {
       for (i = 0; i < count; i++) {
          ve->native_format_size[i] = align(ve->native_format_size[i], 4);
       }
@@ -699,7 +706,7 @@ static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe,
    mgr->incompatible_vb_layout = FALSE;
    memset(mgr->incompatible_vb, 0, sizeof(mgr->incompatible_vb));
 
-   if (!mgr->b.caps.fetch_dword_unaligned) {
+   if (!mgr->caps.fetch_dword_unaligned) {
       /* Check if the strides and offsets are aligned to the size of DWORD. */
       for (i = 0; i < count; i++) {
          if (bufs[i].buffer) {
diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h
index a17d64a..1c05629 100644
--- a/src/gallium/auxiliary/util/u_vbuf.h
+++ b/src/gallium/auxiliary/util/u_vbuf.h
@@ -49,6 +49,9 @@ struct u_vbuf_caps {
    /* Whether vertex fetches don't have to be dword-aligned. */
    /* TRUE if hardware supports it. */
    unsigned fetch_dword_unaligned:1;
+
+   /* Whether the driver supports user vertex buffers. */
+   unsigned user_vertex_buffers:1;
 };
 
 /* The manager.
@@ -69,26 +72,21 @@ struct u_vbuf {
     * - u_upload_flush */
    struct u_upload_mgr *uploader;
 
-   struct u_vbuf_caps caps;
-
    /* Vertex elements state as created by u_vbuf.
     * This is used when saving the state into u_blitter, there's no other
     * usage. */
    void *vertex_elements;
 };
 
-enum u_fetch_alignment {
-   U_VERTEX_FETCH_BYTE_ALIGNED,
-   U_VERTEX_FETCH_DWORD_ALIGNED
-};
 
+void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps);
 
 struct u_vbuf *
 u_vbuf_create(struct pipe_context *pipe,
+              struct u_vbuf_caps *caps,
               unsigned upload_buffer_size,
               unsigned upload_buffer_alignment,
-              unsigned upload_buffer_bind,
-              enum u_fetch_alignment fetch_alignment);
+              unsigned upload_buffer_bind);
 
 void u_vbuf_destroy(struct u_vbuf *mgr);
 
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 769d0bf..6a93575 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -428,13 +428,16 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     r300->context.create_video_buffer = vl_video_buffer_create;
 
     if (r300->screen->caps.has_tcl) {
-        r300->vbuf_mgr = u_vbuf_create(&r300->context, 1024 * 1024, 16,
+        struct u_vbuf_caps caps;
+
+        u_vbuf_get_caps(screen, &caps);
+        caps.format_fixed32 = 0;
+
+        r300->vbuf_mgr = u_vbuf_create(&r300->context, &caps, 1024 * 1024, 16,
                                        PIPE_BIND_VERTEX_BUFFER |
-                                       PIPE_BIND_INDEX_BUFFER,
-                                       U_VERTEX_FETCH_DWORD_ALIGNED);
+                                       PIPE_BIND_INDEX_BUFFER);
         if (!r300->vbuf_mgr)
             goto fail;
-        r300->vbuf_mgr->caps.format_fixed32 = 0;
     }
 
     r300->blitter = util_blitter_create(&r300->context);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 5873d9a..b9eb709 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -103,6 +103,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+        case PIPE_CAP_VERTEX_BUFFER_OFFSET_DWORD_ALIGNED_ONLY:
+        case PIPE_CAP_VERTEX_BUFFER_STRIDE_DWORD_ALIGNED_ONLY:
+        case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_DWORD_ALIGNED_ONLY:
             return 1;
 
         case PIPE_CAP_GLSL_FEATURE_LEVEL:
@@ -141,6 +144,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+        case PIPE_CAP_USER_VERTEX_BUFFERS:
             return 0;
 
         /* SWTCL-only features. */
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 7c40e50..9c9fa4d 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -212,6 +212,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 {
 	struct r600_context *rctx = CALLOC_STRUCT(r600_context);
 	struct r600_screen* rscreen = (struct r600_screen *)screen;
+	struct u_vbuf_caps vbuf_caps;
 
 	if (rctx == NULL)
 		return NULL;
@@ -293,14 +294,15 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 	rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
 	r600_emit_atom(rctx, &rctx->start_cs_cmd.atom);
 
-	rctx->vbuf_mgr = u_vbuf_create(&rctx->context, 1024 * 1024, 256,
-					   PIPE_BIND_VERTEX_BUFFER |
-					   PIPE_BIND_INDEX_BUFFER |
-					   PIPE_BIND_CONSTANT_BUFFER,
-					   U_VERTEX_FETCH_DWORD_ALIGNED);
+	u_vbuf_get_caps(screen, &vbuf_caps);
+	vbuf_caps.format_fixed32 = 0;
+	rctx->vbuf_mgr = u_vbuf_create(&rctx->context, &vbuf_caps,
+				       1024 * 1024, 256,
+				       PIPE_BIND_VERTEX_BUFFER |
+				       PIPE_BIND_INDEX_BUFFER |
+				       PIPE_BIND_CONSTANT_BUFFER);
 	if (!rctx->vbuf_mgr)
 		goto fail;
-	rctx->vbuf_mgr->caps.format_fixed32 = 0;
 
 	rctx->blitter = util_blitter_create(&rctx->context);
 	if (rctx->blitter == NULL)
@@ -403,6 +405,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
 	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
 	case PIPE_CAP_TGSI_INSTANCEID:
+	case PIPE_CAP_VERTEX_BUFFER_OFFSET_DWORD_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_BUFFER_STRIDE_DWORD_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_DWORD_ALIGNED_ONLY:
 		return 1;
 
 	case PIPE_CAP_GLSL_FEATURE_LEVEL:
@@ -426,6 +431,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
 	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
 	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+	case PIPE_CAP_USER_VERTEX_BUFFERS:
 		return 0;
 
 	/* Stream output. */
-- 
1.7.5.4



More information about the mesa-dev mailing list