[Mesa-dev] [PATCH 1/2] gallium: let state trackers tell u_vbuf whether user VBOs are possible

Marek Olšák maraeo at gmail.com
Sat Feb 11 16:31:27 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

This can affect whether u_vbuf will be enabled or not.
---
 src/gallium/auxiliary/cso_cache/cso_context.c | 9 +++++----
 src/gallium/auxiliary/cso_cache/cso_context.h | 3 ++-
 src/gallium/auxiliary/util/u_tests.c          | 8 ++++----
 src/gallium/auxiliary/util/u_vbuf.c           | 5 +++--
 src/gallium/auxiliary/util/u_vbuf.h           | 5 ++++-
 src/gallium/state_trackers/nine/device9.c     | 4 ++--
 src/gallium/state_trackers/xa/xa_context.c    | 2 +-
 src/gallium/tests/trivial/quad-tex.c          | 2 +-
 src/gallium/tests/trivial/tri.c               | 2 +-
 src/mesa/state_tracker/st_context.c           | 2 +-
 10 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 469ab9c..0f12304 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -270,50 +270,51 @@ sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
       while (to_restore--) {
          struct cso_sampler *sampler = samplers_to_restore[to_restore];
 
          cso_hash_insert(hash, sampler->hash_key, sampler);
       }
 
       FREE(samplers_to_restore);
    }
 }
 
-static void cso_init_vbuf(struct cso_context *cso)
+static void cso_init_vbuf(struct cso_context *cso, unsigned flags)
 {
    struct u_vbuf_caps caps;
 
    /* Install u_vbuf if there is anything unsupported. */
-   if (u_vbuf_get_caps(cso->pipe->screen, &caps)) {
+   if (u_vbuf_get_caps(cso->pipe->screen, &caps, flags)) {
       cso->vbuf = u_vbuf_create(cso->pipe, &caps,
                                 cso->aux_vertex_buffer_index);
    }
 }
 
-struct cso_context *cso_create_context( struct pipe_context *pipe )
+struct cso_context *
+cso_create_context(struct pipe_context *pipe, unsigned u_vbuf_flags)
 {
    struct cso_context *ctx = CALLOC_STRUCT(cso_context);
    if (!ctx)
       return NULL;
 
    ctx->cache = cso_cache_create();
    if (ctx->cache == NULL)
       goto out;
    cso_cache_set_sanitize_callback(ctx->cache,
                                    sanitize_hash,
                                    ctx);
 
    ctx->pipe = pipe;
    ctx->sample_mask = ~0;
 
    ctx->aux_vertex_buffer_index = 0; /* 0 for now */
 
-   cso_init_vbuf(ctx);
+   cso_init_vbuf(ctx, u_vbuf_flags);
 
    /* Enable for testing: */
    if (0) cso_set_maximum_cache_size( ctx->cache, 4 );
 
    if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
       ctx->has_geometry_shader = TRUE;
    }
    if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 29e5e33..2a65354 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -34,21 +34,22 @@
 #include "pipe/p_defines.h"
 
 
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
 struct cso_context;
 struct u_vbuf;
 
-struct cso_context *cso_create_context( struct pipe_context *pipe );
+struct cso_context *cso_create_context(struct pipe_context *pipe,
+                                       unsigned u_vbuf_flags);
 void cso_destroy_context( struct cso_context *cso );
 
 
 enum pipe_error cso_set_blend( struct cso_context *cso,
                                const struct pipe_blend_state *blend );
 
 
 enum pipe_error cso_set_depth_stencil_alpha( struct cso_context *cso,
                                              const struct pipe_depth_stencil_alpha_state *dsa );
 
diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c
index c33c1f6..687e511 100644
--- a/src/gallium/auxiliary/util/u_tests.c
+++ b/src/gallium/auxiliary/util/u_tests.c
@@ -297,21 +297,21 @@ tgsi_vs_window_space_position(struct pipe_context *ctx)
    void *fs, *vs;
    bool pass = true;
    static const float red[] = {1, 0, 0, 1};
 
    if (!ctx->screen->get_param(ctx->screen,
                                PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION)) {
       util_report_result(SKIP);
       return;
    }
 
-   cso = cso_create_context(ctx);
+   cso = cso_create_context(ctx, 0);
    cb = util_create_texture2d(ctx->screen, 256, 256,
                               PIPE_FORMAT_R8G8B8A8_UNORM);
    util_set_common_states_and_clear(cso, ctx, cb);
 
    /* Fragment shader. */
    fs = util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC,
                                        TGSI_INTERPOLATE_LINEAR, TRUE);
    cso_set_fragment_shader_handle(cso, fs);
 
    /* Vertex shader. */
@@ -357,21 +357,21 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target)
                               expected_buf : expected_tex;
    unsigned num_expected = tgsi_tex_target == TGSI_TEXTURE_BUFFER ? 1 : 2;
 
    if (tgsi_tex_target == TGSI_TEXTURE_BUFFER &&
        !ctx->screen->get_param(ctx->screen, PIPE_CAP_TEXTURE_BUFFER_OBJECTS)) {
       util_report_result_helper(SKIP, "%s: %s", __func__,
                                 tgsi_texture_names[tgsi_tex_target]);
       return;
    }
 
-   cso = cso_create_context(ctx);
+   cso = cso_create_context(ctx, 0);
    cb = util_create_texture2d(ctx->screen, 256, 256,
                               PIPE_FORMAT_R8G8B8A8_UNORM);
    util_set_common_states_and_clear(cso, ctx, cb);
 
    ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, NULL);
 
    /* Fragment shader. */
    fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target,
                                       TGSI_INTERPOLATE_LINEAR,
                                       TGSI_RETURN_TYPE_FLOAT,
@@ -399,21 +399,21 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target)
 
 static void
 null_constant_buffer(struct pipe_context *ctx)
 {
    struct cso_context *cso;
    struct pipe_resource *cb;
    void *fs, *vs;
    bool pass = true;
    static const float zero[] = {0, 0, 0, 0};
 
-   cso = cso_create_context(ctx);
+   cso = cso_create_context(ctx, 0);
    cb = util_create_texture2d(ctx->screen, 256, 256,
                               PIPE_FORMAT_R8G8B8A8_UNORM);
    util_set_common_states_and_clear(cso, ctx, cb);
 
    ctx->set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, NULL);
 
    /* Fragment shader. */
    {
       static const char *text = /* I don't like ureg... */
             "FRAG\n"
@@ -455,21 +455,21 @@ null_constant_buffer(struct pipe_context *ctx)
 static void
 null_fragment_shader(struct pipe_context *ctx)
 {
    struct cso_context *cso;
    struct pipe_resource *cb;
    void *vs;
    struct pipe_rasterizer_state rs = {0};
    struct pipe_query *query;
    union pipe_query_result qresult;
 
-   cso = cso_create_context(ctx);
+   cso = cso_create_context(ctx, 0);
    cb = util_create_texture2d(ctx->screen, 256, 256,
                               PIPE_FORMAT_R8G8B8A8_UNORM);
    util_set_common_states_and_clear(cso, ctx, cb);
 
    /* No rasterization. */
    rs.rasterizer_discard = 1;
    cso_set_rasterizer(cso, &rs);
 
    vs = util_set_passthrough_vertex_shader(cso, ctx, false);
 
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 532e7c0..5f7cbff 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -249,21 +249,22 @@ static const struct {
    { PIPE_FORMAT_R8_USCALED,           PIPE_FORMAT_R32_FLOAT },
    { PIPE_FORMAT_R8G8_USCALED,         PIPE_FORMAT_R32G32_FLOAT },
    { PIPE_FORMAT_R8G8B8_USCALED,       PIPE_FORMAT_R32G32B32_FLOAT },
    { PIPE_FORMAT_R8G8B8A8_USCALED,     PIPE_FORMAT_R32G32B32A32_FLOAT },
    { PIPE_FORMAT_R8_SSCALED,           PIPE_FORMAT_R32_FLOAT },
    { PIPE_FORMAT_R8G8_SSCALED,         PIPE_FORMAT_R32G32_FLOAT },
    { PIPE_FORMAT_R8G8B8_SSCALED,       PIPE_FORMAT_R32G32B32_FLOAT },
    { PIPE_FORMAT_R8G8B8A8_SSCALED,     PIPE_FORMAT_R32G32B32A32_FLOAT },
 };
 
-boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
+boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps,
+                        unsigned flags)
 {
    unsigned i;
    boolean fallback = FALSE;
 
    /* I'd rather have a bitfield of which formats are supported and a static
     * table of the translations indexed by format, but since we don't have C99
     * we can't easily make a sparsely-populated table indexed by format.  So,
     * we construct the sparse table here.
     */
    for (i = 0; i < PIPE_FORMAT_COUNT; i++)
@@ -287,21 +288,21 @@ boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
                         PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY);
    caps->velem_src_offset_unaligned =
       !screen->get_param(screen,
                          PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY);
    caps->user_vertex_buffers =
       screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS);
 
    if (!caps->buffer_offset_unaligned ||
        !caps->buffer_stride_unaligned ||
        !caps->velem_src_offset_unaligned ||
-       !caps->user_vertex_buffers) {
+       (!(flags & U_VBUF_FLAG_NO_USER_VBOS) && !caps->user_vertex_buffers)) {
       fallback = TRUE;
    }
 
    return fallback;
 }
 
 struct u_vbuf *
 u_vbuf_create(struct pipe_context *pipe,
               struct u_vbuf_caps *caps, unsigned aux_vertex_buffer_index)
 {
diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h
index 9e8b135..ddfa844 100644
--- a/src/gallium/auxiliary/util/u_vbuf.h
+++ b/src/gallium/auxiliary/util/u_vbuf.h
@@ -33,36 +33,39 @@
  * There is a more detailed description at the beginning of the .c file.
  */
 
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "pipe/p_format.h"
 
 struct cso_context;
 struct u_vbuf;
 
+#define U_VBUF_FLAG_NO_USER_VBOS (1 << 0)
+
 /* Hardware vertex fetcher limitations can be described by this structure. */
 struct u_vbuf_caps {
    enum pipe_format format_translation[PIPE_FORMAT_COUNT];
 
    /* Whether vertex fetches don't have to be 4-byte-aligned. */
    /* TRUE if hardware supports it. */
    unsigned buffer_offset_unaligned:1;
    unsigned buffer_stride_unaligned:1;
    unsigned velem_src_offset_unaligned:1;
 
    /* Whether the driver supports user vertex buffers. */
    unsigned user_vertex_buffers:1;
 };
 
 
-boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps);
+boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps,
+                        unsigned flags);
 
 struct u_vbuf *
 u_vbuf_create(struct pipe_context *pipe,
               struct u_vbuf_caps *caps, unsigned aux_vertex_buffer_index);
 
 void u_vbuf_destroy(struct u_vbuf *mgr);
 
 /* State and draw functions. */
 void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count,
                                 const struct pipe_vertex_element *states);
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 92bc72c..b9b7a63 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -192,23 +192,23 @@ NineDevice9_ctor( struct NineDevice9 *This,
     /* When may_swvp, SetConstant* limits are different */
     if (This->may_swvp)
         This->caps.MaxVertexShaderConst = NINE_MAX_CONST_F_SWVP;
 
     This->context.pipe = This->screen->context_create(This->screen, NULL, 0);
     This->pipe_secondary = This->screen->context_create(This->screen, NULL, 0);
     if (!This->context.pipe || !This->pipe_secondary) { return E_OUTOFMEMORY; } /* guess */
     This->pipe_sw = This->screen_sw->context_create(This->screen_sw, NULL, 0);
     if (!This->pipe_sw) { return E_OUTOFMEMORY; }
 
-    This->context.cso = cso_create_context(This->context.pipe);
+    This->context.cso = cso_create_context(This->context.pipe, 0);
     if (!This->context.cso) { return E_OUTOFMEMORY; } /* also a guess */
-    This->cso_sw = cso_create_context(This->pipe_sw);
+    This->cso_sw = cso_create_context(This->pipe_sw, 0);
     if (!This->cso_sw) { return E_OUTOFMEMORY; }
 
     /* Create first, it messes up our state. */
     This->hud = hud_create(This->context.pipe, This->context.cso); /* NULL result is fine */
 
     /* Available memory counter. Updated only for allocations with this device
      * instance. This is the Win 7 behavior.
      * Win XP shares this counter across multiple devices. */
     This->available_texture_mem = This->screen->get_param(This->screen, PIPE_CAP_VIDEO_MEMORY);
     if (This->available_texture_mem < 4096)
diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c
index 715b48d..1f47170 100644
--- a/src/gallium/state_trackers/xa/xa_context.c
+++ b/src/gallium/state_trackers/xa/xa_context.c
@@ -50,21 +50,21 @@ xa_context_default(struct xa_tracker *xa)
     return xa->default_ctx;
 }
 
 XA_EXPORT struct xa_context *
 xa_context_create(struct xa_tracker *xa)
 {
     struct xa_context *ctx = calloc(1, sizeof(*ctx));
 
     ctx->xa = xa;
     ctx->pipe = xa->screen->context_create(xa->screen, NULL, 0);
-    ctx->cso = cso_create_context(ctx->pipe);
+    ctx->cso = cso_create_context(ctx->pipe, 0);
     ctx->shaders = xa_shaders_create(ctx);
     renderer_init_state(ctx);
 
     return ctx;
 }
 
 XA_EXPORT void
 xa_context_destroy(struct xa_context *r)
 {
     struct pipe_resource **vsbuf = &r->vs_const_buffer;
diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c
index c72c5fe..6e9957a 100644
--- a/src/gallium/tests/trivial/quad-tex.c
+++ b/src/gallium/tests/trivial/quad-tex.c
@@ -94,21 +94,21 @@ static void init_prog(struct program *p)
 	/* find a hardware device */
 	ret = pipe_loader_probe(&p->dev, 1);
 	assert(ret);
 
 	/* init a pipe screen */
 	p->screen = pipe_loader_create_screen(p->dev);
 	assert(p->screen);
 
 	/* create the pipe driver context and cso context */
 	p->pipe = p->screen->context_create(p->screen, NULL, 0);
-	p->cso = cso_create_context(p->pipe);
+	p->cso = cso_create_context(p->pipe, 0);
 
 	/* set clear color */
 	p->clear_color.f[0] = 0.3;
 	p->clear_color.f[1] = 0.1;
 	p->clear_color.f[2] = 0.3;
 	p->clear_color.f[3] = 1.0;
 
 	/* vertex buffer */
 	{
 		float vertices[4][2][4] = {
diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c
index 914f5e7..a203169 100644
--- a/src/gallium/tests/trivial/tri.c
+++ b/src/gallium/tests/trivial/tri.c
@@ -89,21 +89,21 @@ static void init_prog(struct program *p)
 	/* find a hardware device */
 	ret = pipe_loader_probe(&p->dev, 1);
 	assert(ret);
 
 	/* init a pipe screen */
 	p->screen = pipe_loader_create_screen(p->dev);
 	assert(p->screen);
 
 	/* create the pipe driver context and cso context */
 	p->pipe = p->screen->context_create(p->screen, NULL, 0);
-	p->cso = cso_create_context(p->pipe);
+	p->cso = cso_create_context(p->pipe, 0);
 
 	/* set clear color */
 	p->clear_color.f[0] = 0.3;
 	p->clear_color.f[1] = 0.1;
 	p->clear_color.f[2] = 0.3;
 	p->clear_color.f[3] = 1.0;
 
 	/* vertex buffer */
 	{
 		float vertices[4][2][4] = {
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 5523734..1229340 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -355,21 +355,21 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
       st->indexbuf_uploader = u_upload_create(pipe, 128 * 1024,
                                               PIPE_BIND_INDEX_BUFFER,
                                               PIPE_USAGE_STREAM);
    }
 
    if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS))
       st->constbuf_uploader = u_upload_create(pipe, 128 * 1024,
                                               PIPE_BIND_CONSTANT_BUFFER,
                                               PIPE_USAGE_STREAM);
 
-   st->cso_context = cso_create_context(pipe);
+   st->cso_context = cso_create_context(pipe, 0);
 
    st_init_atoms( st );
    st_init_clear(st);
    st_init_draw( st );
    st_init_pbo_helpers(st);
 
    /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */
    if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
       st->internal_target = PIPE_TEXTURE_2D;
    else
-- 
2.7.4



More information about the mesa-dev mailing list