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.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user