From 7fe3631a7a0ad7602b4e947ac87ef86875c8bb3f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 10 Apr 2012 05:14:26 +0200 Subject: [PATCH] u_vbuf: make use of the new CAPs to determine what to do 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 2482c8ab7fa..f0601bda72d 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_4BYTE_ALIGNED_ONLY) && + !screen->get_param(screen, + PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY) && + !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); } 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 a17d64ae7ad..1c0562903f2 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 74d5e8ed36c..fd464f32afd 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, 4, + 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, 4, 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 d12fa4e8249..8c12865e9ce 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_4BYTE_ALIGNED_ONLY: + case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: + case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_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 bfe413c1786..c4c27ab526b 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) @@ -402,6 +404,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_4BYTE_ALIGNED_ONLY: + case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: + case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: return 1; case PIPE_CAP_GLSL_FEATURE_LEVEL: @@ -425,6 +430,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. */ -- 2.30.2