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;
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();
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;
}
/* 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);
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);
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);
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);
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);
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);
}
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) {
/* 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.
* - 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);
{
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;
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)
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:
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. */