gallium: make user vertex buffers optional

This couldn't be split because it would break bisecting.

Summary:
* r300g,r600g: stop using u_vbuf
* r300g,r600g: also report that the FIXED vertex type is unsupported
* u_vbuf: refactor for use in the state tracker
* cso: wire up u_vbuf with cso_context
* st/mesa: conditionally install u_vbuf
This commit is contained in:
Marek Olšák
2012-04-10 06:00:17 +02:00
parent 79eafc14ca
commit e0773da1e8
16 changed files with 277 additions and 243 deletions

View File

@@ -41,6 +41,7 @@
#include "util/u_inlines.h" #include "util/u_inlines.h"
#include "util/u_math.h" #include "util/u_math.h"
#include "util/u_memory.h" #include "util/u_memory.h"
#include "util/u_vbuf.h"
#include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_parse.h"
#include "cso_cache/cso_context.h" #include "cso_cache/cso_context.h"
@@ -78,6 +79,7 @@ struct sampler_info
struct cso_context { struct cso_context {
struct pipe_context *pipe; struct pipe_context *pipe;
struct cso_cache *cache; struct cso_cache *cache;
struct u_vbuf *vbuf;
boolean has_geometry_shader; boolean has_geometry_shader;
boolean has_streamout; boolean has_streamout;
@@ -268,6 +270,10 @@ out:
return NULL; return NULL;
} }
void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf)
{
ctx->vbuf = vbuf;
}
/** /**
* Prior to context destruction, this function unbinds all state objects. * Prior to context destruction, this function unbinds all state objects.
@@ -780,11 +786,17 @@ enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned count, unsigned count,
const struct pipe_vertex_element *states) const struct pipe_vertex_element *states)
{ {
struct u_vbuf *vbuf = ctx->vbuf;
unsigned key_size, hash_key; unsigned key_size, hash_key;
struct cso_hash_iter iter; struct cso_hash_iter iter;
void *handle; void *handle;
struct cso_velems_state velems_state; struct cso_velems_state velems_state;
if (vbuf) {
u_vbuf_set_vertex_elements(vbuf, count, states);
return PIPE_OK;
}
/* need to include the count into the stored state data too. /* need to include the count into the stored state data too.
Otherwise first few count pipe_vertex_elements could be identical even if count Otherwise first few count pipe_vertex_elements could be identical even if count
is different, and there's no guarantee the hash would be different in that is different, and there's no guarantee the hash would be different in that
@@ -826,12 +838,26 @@ enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
void cso_save_vertex_elements(struct cso_context *ctx) void cso_save_vertex_elements(struct cso_context *ctx)
{ {
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
u_vbuf_save_vertex_elements(vbuf);
return;
}
assert(!ctx->velements_saved); assert(!ctx->velements_saved);
ctx->velements_saved = ctx->velements; ctx->velements_saved = ctx->velements;
} }
void cso_restore_vertex_elements(struct cso_context *ctx) void cso_restore_vertex_elements(struct cso_context *ctx)
{ {
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
u_vbuf_restore_vertex_elements(vbuf);
return;
}
if (ctx->velements != ctx->velements_saved) { if (ctx->velements != ctx->velements_saved) {
ctx->velements = ctx->velements_saved; ctx->velements = ctx->velements_saved;
ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved); ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
@@ -845,6 +871,13 @@ void cso_set_vertex_buffers(struct cso_context *ctx,
unsigned count, unsigned count,
const struct pipe_vertex_buffer *buffers) const struct pipe_vertex_buffer *buffers)
{ {
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
u_vbuf_set_vertex_buffers(vbuf, count, buffers);
return;
}
if (count != ctx->nr_vertex_buffers || if (count != ctx->nr_vertex_buffers ||
memcmp(buffers, ctx->vertex_buffers, memcmp(buffers, ctx->vertex_buffers,
sizeof(struct pipe_vertex_buffer) * count) != 0) { sizeof(struct pipe_vertex_buffer) * count) != 0) {
@@ -856,6 +889,13 @@ void cso_set_vertex_buffers(struct cso_context *ctx,
void cso_save_vertex_buffers(struct cso_context *ctx) void cso_save_vertex_buffers(struct cso_context *ctx)
{ {
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
u_vbuf_save_vertex_buffers(vbuf);
return;
}
util_copy_vertex_buffers(ctx->vertex_buffers_saved, util_copy_vertex_buffers(ctx->vertex_buffers_saved,
&ctx->nr_vertex_buffers_saved, &ctx->nr_vertex_buffers_saved,
ctx->vertex_buffers, ctx->vertex_buffers,
@@ -865,6 +905,12 @@ void cso_save_vertex_buffers(struct cso_context *ctx)
void cso_restore_vertex_buffers(struct cso_context *ctx) void cso_restore_vertex_buffers(struct cso_context *ctx)
{ {
unsigned i; unsigned i;
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
u_vbuf_restore_vertex_buffers(vbuf);
return;
}
util_copy_vertex_buffers(ctx->vertex_buffers, util_copy_vertex_buffers(ctx->vertex_buffers,
&ctx->nr_vertex_buffers, &ctx->nr_vertex_buffers,
@@ -1298,16 +1344,28 @@ void
cso_set_index_buffer(struct cso_context *cso, cso_set_index_buffer(struct cso_context *cso,
const struct pipe_index_buffer *ib) const struct pipe_index_buffer *ib)
{ {
struct pipe_context *pipe = cso->pipe; struct u_vbuf *vbuf = cso->vbuf;
pipe->set_index_buffer(pipe, ib);
if (vbuf) {
u_vbuf_set_index_buffer(vbuf, ib);
} else {
struct pipe_context *pipe = cso->pipe;
pipe->set_index_buffer(pipe, ib);
}
} }
void void
cso_draw_vbo(struct cso_context *cso, cso_draw_vbo(struct cso_context *cso,
const struct pipe_draw_info *info) const struct pipe_draw_info *info)
{ {
struct pipe_context *pipe = cso->pipe; struct u_vbuf *vbuf = cso->vbuf;
pipe->draw_vbo(pipe, info);
if (vbuf) {
u_vbuf_draw_vbo(vbuf, info);
} else {
struct pipe_context *pipe = cso->pipe;
pipe->draw_vbo(pipe, info);
}
} }
void void

View File

@@ -39,9 +39,12 @@ extern "C" {
#endif #endif
struct cso_context; 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 );
void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf);
void cso_release_all( struct cso_context *ctx ); void cso_release_all( struct cso_context *ctx );
void cso_destroy_context( struct cso_context *cso ); void cso_destroy_context( struct cso_context *cso );

View File

@@ -66,12 +66,22 @@ enum {
VB_NUM = 3 VB_NUM = 3
}; };
struct u_vbuf_priv { struct u_vbuf {
struct u_vbuf b;
struct u_vbuf_caps caps; struct u_vbuf_caps caps;
struct pipe_context *pipe; struct pipe_context *pipe;
struct translate_cache *translate_cache; struct translate_cache *translate_cache;
struct cso_cache *cso_cache; struct cso_cache *cso_cache;
struct u_upload_mgr *uploader;
/* This is what was set in set_vertex_buffers.
* May contain user buffers. */
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_buffers;
/* Saved vertex buffers. */
struct pipe_vertex_buffer vertex_buffer_saved[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_buffers_saved;
/* Vertex buffers for the driver. /* Vertex buffers for the driver.
* There are no user buffers. */ * There are no user buffers. */
@@ -82,14 +92,14 @@ struct u_vbuf_priv {
/* The index buffer. */ /* The index buffer. */
struct pipe_index_buffer index_buffer; struct pipe_index_buffer index_buffer;
/* and its associated helper structure for this module. */ /* Vertex elements. */
struct u_vbuf_elements *ve; struct u_vbuf_elements *ve, *ve_saved;
/* Vertex elements used for the translate fallback. */ /* Vertex elements used for the translate fallback. */
struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS];
/* If non-NULL, this is a vertex element state used for the translate /* If non-NULL, this is a vertex element state used for the translate
* fallback and therefore used for rendering too. */ * fallback and therefore used for rendering too. */
void *fallback_ve; boolean using_translate;
/* The vertex buffer slot index where translated vertices have been /* The vertex buffer slot index where translated vertices have been
* stored in. */ * stored in. */
unsigned fallback_vbs[VB_NUM]; unsigned fallback_vbs[VB_NUM];
@@ -100,21 +110,14 @@ struct u_vbuf_priv {
boolean incompatible_vb_layout; boolean incompatible_vb_layout;
/* Per-buffer flags. */ /* Per-buffer flags. */
boolean incompatible_vb[PIPE_MAX_ATTRIBS]; boolean incompatible_vb[PIPE_MAX_ATTRIBS];
void (*driver_set_index_buffer)(struct pipe_context *pipe,
const struct pipe_index_buffer *);
void (*driver_set_vertex_buffers)(struct pipe_context *,
unsigned num_buffers,
const struct pipe_vertex_buffer *);
void *(*driver_create_vertex_elements_state)(struct pipe_context *,
unsigned num_elements,
const struct pipe_vertex_element *);
void (*driver_bind_vertex_elements_state)(struct pipe_context *, void *);
void (*driver_delete_vertex_elements_state)(struct pipe_context *, void *);
void (*driver_draw_vbo)(struct pipe_context *pipe,
const struct pipe_draw_info *info);
}; };
static void *
u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
const struct pipe_vertex_element *attribs);
static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso);
void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps) void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
{ {
caps->format_fixed32 = caps->format_fixed32 =
@@ -153,16 +156,11 @@ void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
screen->get_param(screen, PIPE_CAP_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 * struct u_vbuf *
u_vbuf_create(struct pipe_context *pipe, u_vbuf_create(struct pipe_context *pipe,
struct u_vbuf_caps *caps, struct u_vbuf_caps *caps)
unsigned upload_buffer_size,
unsigned upload_buffer_alignment,
unsigned upload_buffer_bind)
{ {
struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv); struct u_vbuf *mgr = CALLOC_STRUCT(u_vbuf);
mgr->caps = *caps; mgr->caps = *caps;
mgr->pipe = pipe; mgr->pipe = pipe;
@@ -170,23 +168,22 @@ u_vbuf_create(struct pipe_context *pipe,
mgr->translate_cache = translate_cache_create(); mgr->translate_cache = translate_cache_create();
memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs)); memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
mgr->b.uploader = u_upload_create(pipe, upload_buffer_size, mgr->uploader = u_upload_create(pipe, 1024 * 1024, 4,
upload_buffer_alignment, PIPE_BIND_VERTEX_BUFFER);
upload_buffer_bind);
u_vbuf_install(mgr); return mgr;
return &mgr->b;
} }
/* XXX I had to fork this off of cso_context. */ /* u_vbuf uses its own caching for vertex elements, because it needs to keep
static void * * its own preprocessed state per vertex element CSO. */
u_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr, static struct u_vbuf_elements *
unsigned count, u_vbuf_set_vertex_elements_internal(struct u_vbuf *mgr, unsigned count,
const struct pipe_vertex_element *states) const struct pipe_vertex_element *states)
{ {
struct pipe_context *pipe = mgr->pipe;
unsigned key_size, hash_key; unsigned key_size, hash_key;
struct cso_hash_iter iter; struct cso_hash_iter iter;
void *handle; struct u_vbuf_elements *ve;
struct cso_velems_state velems_state; struct cso_velems_state velems_state;
/* need to include the count into the stored state data too. */ /* need to include the count into the stored state data too. */
@@ -201,50 +198,50 @@ u_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr,
if (cso_hash_iter_is_null(iter)) { if (cso_hash_iter_is_null(iter)) {
struct cso_velements *cso = MALLOC_STRUCT(cso_velements); struct cso_velements *cso = MALLOC_STRUCT(cso_velements);
memcpy(&cso->state, &velems_state, key_size); memcpy(&cso->state, &velems_state, key_size);
cso->data = cso->data = u_vbuf_create_vertex_elements(mgr, count, states);
mgr->driver_create_vertex_elements_state(mgr->pipe, count, cso->delete_state = (cso_state_callback)u_vbuf_delete_vertex_elements;
&cso->state.velems[0]); cso->context = (void*)mgr;
cso->delete_state =
(cso_state_callback)mgr->driver_delete_vertex_elements_state;
cso->context = mgr->pipe;
iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso); iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso);
handle = cso->data; ve = cso->data;
} else { } else {
handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data; ve = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
} }
mgr->driver_bind_vertex_elements_state(mgr->pipe, handle); assert(ve);
return handle; pipe->bind_vertex_elements_state(pipe, ve->driver_cso);
return ve;
} }
void u_vbuf_destroy(struct u_vbuf *mgrb) void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count,
const struct pipe_vertex_element *states)
{
mgr->ve = u_vbuf_set_vertex_elements_internal(mgr, count, states);
}
void u_vbuf_destroy(struct u_vbuf *mgr)
{ {
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb;
unsigned i; unsigned i;
assert(mgr->pipe->draw); for (i = 0; i < mgr->nr_vertex_buffers; i++) {
mgr->pipe->draw = NULL; pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
for (i = 0; i < mgr->b.nr_vertex_buffers; i++) {
pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL);
} }
for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
} }
translate_cache_destroy(mgr->translate_cache); translate_cache_destroy(mgr->translate_cache);
u_upload_destroy(mgr->b.uploader); u_upload_destroy(mgr->uploader);
cso_cache_delete(mgr->cso_cache); cso_cache_delete(mgr->cso_cache);
FREE(mgr); FREE(mgr);
} }
static void static void
u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
unsigned vb_mask, unsigned out_vb, unsigned vb_mask, unsigned out_vb,
int start_vertex, unsigned num_vertices, int start_vertex, unsigned num_vertices,
int start_index, unsigned num_indices, int min_index, int start_index, unsigned num_indices, int min_index,
bool unroll_indices) boolean unroll_indices)
{ {
struct translate *tr; struct translate *tr;
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
@@ -256,9 +253,9 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
tr = translate_cache_find(mgr->translate_cache, key); tr = translate_cache_find(mgr->translate_cache, key);
/* Map buffers we want to translate. */ /* Map buffers we want to translate. */
for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { for (i = 0; i < mgr->nr_vertex_buffers; i++) {
if (vb_mask & (1 << i)) { if (vb_mask & (1 << i)) {
struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i]; struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[i];
unsigned offset = vb->buffer_offset + vb->stride * start_vertex; unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
uint8_t *map; uint8_t *map;
@@ -303,7 +300,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
} }
/* Create and map the output buffer. */ /* Create and map the output buffer. */
u_upload_alloc(mgr->b.uploader, 0, u_upload_alloc(mgr->uploader, 0,
key->output_stride * num_indices, key->output_stride * num_indices,
&out_offset, &out_buffer, &out_offset, &out_buffer,
(void**)&out_map); (void**)&out_map);
@@ -325,7 +322,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
} }
} else { } else {
/* Create and map the output buffer. */ /* Create and map the output buffer. */
u_upload_alloc(mgr->b.uploader, u_upload_alloc(mgr->uploader,
key->output_stride * start_vertex, key->output_stride * start_vertex,
key->output_stride * num_vertices, key->output_stride * num_vertices,
&out_offset, &out_buffer, &out_offset, &out_buffer,
@@ -337,7 +334,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
} }
/* Unmap all buffers. */ /* Unmap all buffers. */
for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { for (i = 0; i < mgr->nr_vertex_buffers; i++) {
if (vb_transfer[i]) { if (vb_transfer[i]) {
pipe_buffer_unmap(mgr->pipe, vb_transfer[i]); pipe_buffer_unmap(mgr->pipe, vb_transfer[i]);
} }
@@ -354,7 +351,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
} }
static boolean static boolean
u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr, u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
unsigned mask[VB_NUM]) unsigned mask[VB_NUM])
{ {
unsigned i, type; unsigned i, type;
@@ -392,7 +389,7 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr,
} }
if (i == PIPE_MAX_ATTRIBS) { if (i == PIPE_MAX_ATTRIBS) {
/* fail, reset the number to its original value */ /* fail, reset the number to its original value */
mgr->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
return FALSE; return FALSE;
} }
} }
@@ -403,11 +400,11 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr,
} }
static boolean static boolean
u_vbuf_translate_begin(struct u_vbuf_priv *mgr, u_vbuf_translate_begin(struct u_vbuf *mgr,
int start_vertex, unsigned num_vertices, int start_vertex, unsigned num_vertices,
int start_instance, unsigned num_instances, int start_instance, unsigned num_instances,
int start_index, unsigned num_indices, int min_index, int start_index, unsigned num_indices, int min_index,
bool unroll_indices) boolean unroll_indices)
{ {
unsigned mask[VB_NUM] = {0}; unsigned mask[VB_NUM] = {0};
struct translate_key key[VB_NUM]; struct translate_key key[VB_NUM];
@@ -434,7 +431,7 @@ u_vbuf_translate_begin(struct u_vbuf_priv *mgr,
for (i = 0; i < mgr->ve->count; i++) { for (i = 0; i < mgr->ve->count; i++) {
unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index; unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index;
if (!mgr->b.vertex_buffer[vb_index].stride) { if (!mgr->vertex_buffer[vb_index].stride) {
if (!mgr->ve->incompatible_layout_elem[i] && if (!mgr->ve->incompatible_layout_elem[i] &&
!mgr->incompatible_vb[vb_index]) { !mgr->incompatible_vb[vb_index]) {
continue; continue;
@@ -543,18 +540,19 @@ u_vbuf_translate_begin(struct u_vbuf_priv *mgr,
} }
} }
mgr->fallback_ve = u_vbuf_cache_set_vertex_elements(mgr, mgr->ve->count, u_vbuf_set_vertex_elements_internal(mgr, mgr->ve->count,
mgr->fallback_velems); mgr->fallback_velems);
mgr->using_translate = TRUE;
return TRUE; return TRUE;
} }
static void u_vbuf_translate_end(struct u_vbuf_priv *mgr) static void u_vbuf_translate_end(struct u_vbuf *mgr)
{ {
unsigned i; unsigned i;
/* Restore vertex elements. */ /* Restore vertex elements. */
mgr->driver_bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso); mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso);
mgr->fallback_ve = NULL; mgr->using_translate = FALSE;
/* Unreference the now-unused VBOs. */ /* Unreference the now-unused VBOs. */
for (i = 0; i < VB_NUM; i++) { for (i = 0; i < VB_NUM; i++) {
@@ -564,18 +562,17 @@ static void u_vbuf_translate_end(struct u_vbuf_priv *mgr)
mgr->fallback_vbs[i] = ~0; mgr->fallback_vbs[i] = ~0;
} }
} }
mgr->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
} }
#define FORMAT_REPLACE(what, withwhat) \ #define FORMAT_REPLACE(what, withwhat) \
case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
static void * static void *
u_vbuf_create_vertex_elements(struct pipe_context *pipe, u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
unsigned count,
const struct pipe_vertex_element *attribs) const struct pipe_vertex_element *attribs)
{ {
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; struct pipe_context *pipe = mgr->pipe;
unsigned i; unsigned i;
struct pipe_vertex_element native_attribs[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element native_attribs[PIPE_MAX_ATTRIBS];
struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements);
@@ -670,36 +667,22 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe,
} }
ve->driver_cso = ve->driver_cso =
mgr->driver_create_vertex_elements_state(pipe, count, native_attribs); pipe->create_vertex_elements_state(pipe, count, native_attribs);
return ve; return ve;
} }
static void u_vbuf_bind_vertex_elements(struct pipe_context *pipe, static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso)
void *cso)
{ {
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; struct pipe_context *pipe = mgr->pipe;
struct u_vbuf_elements *ve = cso; struct u_vbuf_elements *ve = cso;
mgr->ve = ve; pipe->delete_vertex_elements_state(pipe, ve->driver_cso);
mgr->b.vertex_elements = ve;
mgr->driver_bind_vertex_elements_state(pipe, ve ? ve->driver_cso : NULL);
}
static void u_vbuf_delete_vertex_elements(struct pipe_context *pipe,
void *cso)
{
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
struct u_vbuf_elements *ve = cso;
mgr->driver_delete_vertex_elements_state(pipe, ve->driver_cso);
FREE(ve); FREE(ve);
} }
static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe, void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
unsigned count, const struct pipe_vertex_buffer *bufs)
const struct pipe_vertex_buffer *bufs)
{ {
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
unsigned i; unsigned i;
mgr->any_user_vbs = FALSE; mgr->any_user_vbs = FALSE;
@@ -722,13 +705,13 @@ static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
const struct pipe_vertex_buffer *vb = &bufs[i]; const struct pipe_vertex_buffer *vb = &bufs[i];
pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer); pipe_resource_reference(&mgr->vertex_buffer[i].buffer, vb->buffer);
mgr->real_vertex_buffer[i].buffer_offset = mgr->real_vertex_buffer[i].buffer_offset =
mgr->b.vertex_buffer[i].buffer_offset = vb->buffer_offset; mgr->vertex_buffer[i].buffer_offset = vb->buffer_offset;
mgr->real_vertex_buffer[i].stride = mgr->real_vertex_buffer[i].stride =
mgr->b.vertex_buffer[i].stride = vb->stride; mgr->vertex_buffer[i].stride = vb->stride;
if (!vb->buffer || if (!vb->buffer ||
mgr->incompatible_vb[i]) { mgr->incompatible_vb[i]) {
@@ -745,22 +728,22 @@ static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe,
pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, vb->buffer); pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, vb->buffer);
} }
for (i = count; i < mgr->b.nr_vertex_buffers; i++) { for (i = count; i < mgr->nr_vertex_buffers; i++) {
pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
} }
for (i = count; i < mgr->nr_real_vertex_buffers; i++) { for (i = count; i < mgr->nr_real_vertex_buffers; i++) {
pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
} }
mgr->b.nr_vertex_buffers = count; mgr->nr_vertex_buffers = count;
mgr->nr_real_vertex_buffers = count; mgr->nr_real_vertex_buffers = count;
mgr->vertex_buffers_dirty = TRUE; mgr->vertex_buffers_dirty = TRUE;
} }
static void u_vbuf_set_index_buffer(struct pipe_context *pipe, void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
const struct pipe_index_buffer *ib) const struct pipe_index_buffer *ib)
{ {
struct u_vbuf_priv *mgr = pipe->draw; struct pipe_context *pipe = mgr->pipe;
if (ib && ib->buffer) { if (ib && ib->buffer) {
assert(ib->offset % ib->index_size == 0); assert(ib->offset % ib->index_size == 0);
@@ -771,19 +754,19 @@ static void u_vbuf_set_index_buffer(struct pipe_context *pipe,
pipe_resource_reference(&mgr->index_buffer.buffer, NULL); pipe_resource_reference(&mgr->index_buffer.buffer, NULL);
} }
mgr->driver_set_index_buffer(pipe, ib); pipe->set_index_buffer(pipe, ib);
} }
static void static void
u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, u_vbuf_upload_buffers(struct u_vbuf *mgr,
int start_vertex, unsigned num_vertices, int start_vertex, unsigned num_vertices,
int start_instance, unsigned num_instances) int start_instance, unsigned num_instances)
{ {
unsigned i; unsigned i;
unsigned nr_velems = mgr->ve->count; unsigned nr_velems = mgr->ve->count;
unsigned nr_vbufs = mgr->b.nr_vertex_buffers; unsigned nr_vbufs = mgr->nr_vertex_buffers;
struct pipe_vertex_element *velems = struct pipe_vertex_element *velems =
mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve;
unsigned start_offset[PIPE_MAX_ATTRIBS]; unsigned start_offset[PIPE_MAX_ATTRIBS];
unsigned end_offset[PIPE_MAX_ATTRIBS] = {0}; unsigned end_offset[PIPE_MAX_ATTRIBS] = {0};
@@ -791,7 +774,7 @@ u_vbuf_upload_buffers(struct u_vbuf_priv *mgr,
for (i = 0; i < nr_velems; i++) { for (i = 0; i < nr_velems; i++) {
struct pipe_vertex_element *velem = &velems[i]; struct pipe_vertex_element *velem = &velems[i];
unsigned index = velem->vertex_buffer_index; unsigned index = velem->vertex_buffer_index;
struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index]; struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[index];
unsigned instance_div, first, size; unsigned instance_div, first, size;
/* Skip the buffers generated by translate. */ /* Skip the buffers generated by translate. */
@@ -850,16 +833,16 @@ u_vbuf_upload_buffers(struct u_vbuf_priv *mgr,
assert(start < end); assert(start < end);
real_vb = &mgr->real_vertex_buffer[i]; real_vb = &mgr->real_vertex_buffer[i];
ptr = mgr->b.vertex_buffer[i].buffer->user_ptr; ptr = mgr->vertex_buffer[i].buffer->user_ptr;
u_upload_data(mgr->b.uploader, start, end - start, ptr + start, u_upload_data(mgr->uploader, start, end - start, ptr + start,
&real_vb->buffer_offset, &real_vb->buffer); &real_vb->buffer_offset, &real_vb->buffer);
real_vb->buffer_offset -= start; real_vb->buffer_offset -= start;
} }
} }
static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) static boolean u_vbuf_need_minmax_index(struct u_vbuf *mgr)
{ {
unsigned i, nr = mgr->ve->count; unsigned i, nr = mgr->ve->count;
@@ -873,7 +856,7 @@ static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr)
} }
index = mgr->ve->ve[i].vertex_buffer_index; index = mgr->ve->ve[i].vertex_buffer_index;
vb = &mgr->b.vertex_buffer[index]; vb = &mgr->vertex_buffer[index];
/* Constant attribs don't need min/max_index. */ /* Constant attribs don't need min/max_index. */
if (!vb->stride) { if (!vb->stride) {
@@ -891,7 +874,7 @@ static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr)
return FALSE; return FALSE;
} }
static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf_priv *mgr) static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr)
{ {
unsigned i, nr = mgr->ve->count; unsigned i, nr = mgr->ve->count;
@@ -905,7 +888,7 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf_priv *mgr)
} }
index = mgr->ve->ve[i].vertex_buffer_index; index = mgr->ve->ve[i].vertex_buffer_index;
vb = &mgr->b.vertex_buffer[index]; vb = &mgr->vertex_buffer[index];
/* Constant attribs are not per-vertex data. */ /* Constant attribs are not per-vertex data. */
if (!vb->stride) { if (!vb->stride) {
@@ -1023,13 +1006,12 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
} }
} }
static void u_vbuf_draw_vbo(struct pipe_context *pipe, void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
const struct pipe_draw_info *info)
{ {
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; struct pipe_context *pipe = mgr->pipe;
int start_vertex, min_index; int start_vertex, min_index;
unsigned num_vertices; unsigned num_vertices;
bool unroll_indices = false; boolean unroll_indices = FALSE;
/* Normal draw. No fallback and no user buffers. */ /* Normal draw. No fallback and no user buffers. */
if (!mgr->incompatible_vb_layout && if (!mgr->incompatible_vb_layout &&
@@ -1037,27 +1019,27 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
!mgr->any_user_vbs) { !mgr->any_user_vbs) {
/* Set vertex buffers if needed. */ /* Set vertex buffers if needed. */
if (mgr->vertex_buffers_dirty) { if (mgr->vertex_buffers_dirty) {
mgr->driver_set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers, pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
mgr->real_vertex_buffer); mgr->real_vertex_buffer);
mgr->vertex_buffers_dirty = FALSE; mgr->vertex_buffers_dirty = FALSE;
} }
mgr->driver_draw_vbo(pipe, info); pipe->draw_vbo(pipe, info);
return; return;
} }
if (info->indexed) { if (info->indexed) {
int max_index; int max_index;
bool index_bounds_valid = false; boolean index_bounds_valid = FALSE;
if (info->max_index != ~0) { if (info->max_index != ~0) {
min_index = info->min_index; min_index = info->min_index;
max_index = info->max_index; max_index = info->max_index;
index_bounds_valid = true; index_bounds_valid = TRUE;
} else if (u_vbuf_need_minmax_index(mgr)) { } else if (u_vbuf_need_minmax_index(mgr)) {
u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info, u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info,
&min_index, &max_index); &min_index, &max_index);
index_bounds_valid = true; index_bounds_valid = TRUE;
} }
/* If the index bounds are valid, it means some upload or translation /* If the index bounds are valid, it means some upload or translation
@@ -1077,7 +1059,7 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
num_vertices-info->count > 32 && num_vertices-info->count > 32 &&
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) { !u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
/*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/ /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/
unroll_indices = true; unroll_indices = TRUE;
} }
} else { } else {
/* Nothing to do for per-vertex attribs. */ /* Nothing to do for per-vertex attribs. */
@@ -1117,9 +1099,9 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
} }
unsigned i; unsigned i;
for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { for (i = 0; i < mgr->nr_vertex_buffers; i++) {
printf("input %i: ", i); printf("input %i: ", i);
util_dump_vertex_buffer(stdout, mgr->b.vertex_buffer+i); util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i);
printf("\n"); printf("\n");
} }
for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
@@ -1129,8 +1111,9 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
} }
*/ */
mgr->driver_set_vertex_buffers(mgr->pipe, mgr->nr_real_vertex_buffers, u_upload_unmap(mgr->uploader);
mgr->real_vertex_buffer); pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
mgr->real_vertex_buffer);
if (unlikely(unroll_indices)) { if (unlikely(unroll_indices)) {
struct pipe_draw_info new_info = *info; struct pipe_draw_info new_info = *info;
@@ -1140,36 +1123,51 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
new_info.max_index = info->count - 1; new_info.max_index = info->count - 1;
new_info.start = 0; new_info.start = 0;
mgr->driver_draw_vbo(pipe, &new_info); pipe->draw_vbo(pipe, &new_info);
} else { } else {
mgr->driver_draw_vbo(pipe, info); pipe->draw_vbo(pipe, info);
} }
if (mgr->fallback_ve) { if (mgr->using_translate) {
u_vbuf_translate_end(mgr); u_vbuf_translate_end(mgr);
} }
mgr->vertex_buffers_dirty = TRUE; mgr->vertex_buffers_dirty = TRUE;
} }
static void u_vbuf_install(struct u_vbuf_priv *mgr) void u_vbuf_save_vertex_elements(struct u_vbuf *mgr)
{ {
struct pipe_context *pipe = mgr->pipe; assert(!mgr->ve_saved);
assert(!pipe->draw); mgr->ve_saved = mgr->ve;
}
pipe->draw = mgr;
mgr->driver_set_index_buffer = pipe->set_index_buffer; void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr)
mgr->driver_set_vertex_buffers = pipe->set_vertex_buffers; {
mgr->driver_create_vertex_elements_state = if (mgr->ve != mgr->ve_saved) {
pipe->create_vertex_elements_state; struct pipe_context *pipe = mgr->pipe;
mgr->driver_bind_vertex_elements_state = pipe->bind_vertex_elements_state;
mgr->driver_delete_vertex_elements_state = mgr->ve = mgr->ve_saved;
pipe->delete_vertex_elements_state; pipe->bind_vertex_elements_state(pipe,
mgr->driver_draw_vbo = pipe->draw_vbo; mgr->ve ? mgr->ve->driver_cso : NULL);
}
pipe->set_index_buffer = u_vbuf_set_index_buffer; mgr->ve_saved = NULL;
pipe->set_vertex_buffers = u_vbuf_set_vertex_buffers; }
pipe->create_vertex_elements_state = u_vbuf_create_vertex_elements;
pipe->bind_vertex_elements_state = u_vbuf_bind_vertex_elements; void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr)
pipe->delete_vertex_elements_state = u_vbuf_delete_vertex_elements; {
pipe->draw_vbo = u_vbuf_draw_vbo; util_copy_vertex_buffers(mgr->vertex_buffer_saved,
&mgr->nr_vertex_buffers_saved,
mgr->vertex_buffer,
mgr->nr_vertex_buffers);
}
void u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr)
{
unsigned i;
u_vbuf_set_vertex_buffers(mgr, mgr->nr_vertex_buffers_saved,
mgr->vertex_buffer_saved);
for (i = 0; i < mgr->nr_vertex_buffers_saved; i++) {
pipe_resource_reference(&mgr->vertex_buffer_saved[i].buffer, NULL);
}
mgr->nr_vertex_buffers_saved = 0;
} }

View File

@@ -25,8 +25,8 @@
* *
**************************************************************************/ **************************************************************************/
#ifndef U_VBUF_MGR_H #ifndef U_VBUF_H
#define U_VBUF_MGR_H #define U_VBUF_H
/* This module builds upon u_upload_mgr and translate_cache and takes care of /* This module builds upon u_upload_mgr and translate_cache and takes care of
* user buffer uploads and vertex format fallbacks. It's designed * user buffer uploads and vertex format fallbacks. It's designed
@@ -36,6 +36,9 @@
#include "pipe/p_context.h" #include "pipe/p_context.h"
#include "pipe/p_state.h" #include "pipe/p_state.h"
struct cso_context;
struct u_vbuf;
/* Hardware vertex fetcher limitations can be described by this structure. */ /* Hardware vertex fetcher limitations can be described by this structure. */
struct u_vbuf_caps { struct u_vbuf_caps {
/* Vertex format CAPs. */ /* Vertex format CAPs. */
@@ -54,41 +57,28 @@ struct u_vbuf_caps {
unsigned user_vertex_buffers:1; unsigned user_vertex_buffers:1;
}; };
/* The manager.
* This structure should also be used to access vertex buffers
* from a driver. */
struct u_vbuf {
/* This is what was set in set_vertex_buffers.
* May contain user buffers. */
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_buffers;
/* This uploader can optionally be used by the driver.
*
* Allowed functions:
* - u_upload_alloc
* - u_upload_data
* - u_upload_buffer
* - u_upload_flush */
struct u_upload_mgr *uploader;
/* 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;
};
void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps); void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps);
struct u_vbuf * struct u_vbuf *
u_vbuf_create(struct pipe_context *pipe, u_vbuf_create(struct pipe_context *pipe,
struct u_vbuf_caps *caps, struct u_vbuf_caps *caps);
unsigned upload_buffer_size,
unsigned upload_buffer_alignment,
unsigned upload_buffer_bind);
void u_vbuf_destroy(struct u_vbuf *mgr); 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);
void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
const struct pipe_vertex_buffer *bufs);
void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
const struct pipe_index_buffer *ib);
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info);
/* Save/restore functionality. */
void u_vbuf_save_vertex_elements(struct u_vbuf *mgr);
void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr);
void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr);
void u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr);
#endif #endif

View File

@@ -62,15 +62,9 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o
util_blitter_save_fragment_shader(r300->blitter, r300->fs.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs.state);
util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
util_blitter_save_viewport(r300->blitter, &r300->viewport); util_blitter_save_viewport(r300->blitter, &r300->viewport);
if (r300->vbuf_mgr) { util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers,
util_blitter_save_vertex_buffers(r300->blitter, r300->vbuf_mgr->nr_vertex_buffers, r300->vertex_buffer);
r300->vbuf_mgr->vertex_buffer); util_blitter_save_vertex_elements(r300->blitter, r300->velems);
util_blitter_save_vertex_elements(r300->blitter, r300->vbuf_mgr->vertex_elements);
} else {
util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers,
r300->vertex_buffer);
util_blitter_save_vertex_elements(r300->blitter, r300->velems);
}
if (op & R300_SAVE_FRAMEBUFFER) { if (op & R300_SAVE_FRAMEBUFFER) {
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);

View File

@@ -100,9 +100,6 @@ static void r300_destroy_context(struct pipe_context* context)
if (r300->draw) if (r300->draw)
draw_destroy(r300->draw); draw_destroy(r300->draw);
if (r300->vbuf_mgr)
u_vbuf_destroy(r300->vbuf_mgr);
u_upload_destroy(r300->uploader); u_upload_destroy(r300->uploader);
/* XXX: This function assumes r300->query_list was initialized */ /* XXX: This function assumes r300->query_list was initialized */
@@ -429,20 +426,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.create_video_decoder = vl_create_decoder; r300->context.create_video_decoder = vl_create_decoder;
r300->context.create_video_buffer = vl_video_buffer_create; r300->context.create_video_buffer = vl_video_buffer_create;
if (r300->screen->caps.has_tcl) { r300->uploader = u_upload_create(&r300->context, 256 * 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);
if (!r300->vbuf_mgr)
goto fail;
}
r300->uploader = u_upload_create(&r300->context, 256 * 1024, 16,
PIPE_BIND_INDEX_BUFFER); PIPE_BIND_INDEX_BUFFER);
r300->blitter = util_blitter_create(&r300->context); r300->blitter = util_blitter_create(&r300->context);

View File

@@ -30,7 +30,6 @@
#include "pipe/p_context.h" #include "pipe/p_context.h"
#include "util/u_inlines.h" #include "util/u_inlines.h"
#include "util/u_transfer.h" #include "util/u_transfer.h"
#include "util/u_vbuf.h"
#include "r300_defines.h" #include "r300_defines.h"
#include "r300_screen.h" #include "r300_screen.h"
@@ -576,7 +575,6 @@ struct r300_context {
void *dsa_decompress_zmask; void *dsa_decompress_zmask;
struct u_vbuf *vbuf_mgr;
struct pipe_index_buffer index_buffer; struct pipe_index_buffer index_buffer;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_buffers; unsigned nr_vertex_buffers;

View File

@@ -361,10 +361,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_R16G16_FLOAT ||
format == PIPE_FORMAT_R16G16B16_FLOAT || format == PIPE_FORMAT_R16G16B16_FLOAT ||
format == PIPE_FORMAT_R16G16B16A16_FLOAT; format == PIPE_FORMAT_R16G16B16A16_FLOAT;
boolean is_fixed = format == PIPE_FORMAT_R32_FIXED ||
format == PIPE_FORMAT_R32G32_FIXED ||
format == PIPE_FORMAT_R32G32B32_FIXED ||
format == PIPE_FORMAT_R32G32B32A32_FIXED;
if (!util_format_is_supported(format, usage)) if (!util_format_is_supported(format, usage))
return FALSE; return FALSE;
@@ -428,8 +424,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
if (usage & PIPE_BIND_VERTEX_BUFFER && if (usage & PIPE_BIND_VERTEX_BUFFER &&
/* Half float is supported on >= R400. */ /* Half float is supported on >= R400. */
(is_r400 || is_r500 || !is_half_float) && (is_r400 || is_r500 || !is_half_float) &&
/* We have a fallback for FIXED. */ r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) {
(is_fixed || r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT)) {
retval |= PIPE_BIND_VERTEX_BUFFER; retval |= PIPE_BIND_VERTEX_BUFFER;
} }

View File

@@ -29,7 +29,6 @@
#include "../../winsys/radeon/drm/radeon_winsys.h" #include "../../winsys/radeon/drm/radeon_winsys.h"
#include "util/u_double_list.h" #include "util/u_double_list.h"
#include "util/u_transfer.h" #include "util/u_transfer.h"
#include "util/u_vbuf.h"
#define R600_ERR(fmt, args...) \ #define R600_ERR(fmt, args...) \
fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args) fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args)

View File

@@ -55,13 +55,13 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]); util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]);
util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
util_blitter_save_vertex_elements(rctx->blitter, rctx->vbuf_mgr->vertex_elements); util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
if (rctx->states[R600_PIPE_STATE_VIEWPORT]) { if (rctx->states[R600_PIPE_STATE_VIEWPORT]) {
util_blitter_save_viewport(rctx->blitter, &rctx->viewport); util_blitter_save_viewport(rctx->blitter, &rctx->viewport);
} }
util_blitter_save_vertex_buffers(rctx->blitter, util_blitter_save_vertex_buffers(rctx->blitter,
rctx->vbuf_mgr->nr_vertex_buffers, rctx->nr_vertex_buffers,
rctx->vbuf_mgr->vertex_buffer); rctx->vertex_buffer);
util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets, util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
(struct pipe_stream_output_target**)rctx->so_targets); (struct pipe_stream_output_target**)rctx->so_targets);

View File

@@ -106,8 +106,8 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
/* We changed the buffer, now we need to bind it where the old one was bound. */ /* We changed the buffer, now we need to bind it where the old one was bound. */
/* Vertex buffers. */ /* Vertex buffers. */
for (i = 0; i < rctx->vbuf_mgr->nr_vertex_buffers; i++) { for (i = 0; i < rctx->nr_vertex_buffers; i++) {
if (rctx->vbuf_mgr->vertex_buffer[i].buffer == &rbuffer->b.b) { if (rctx->vertex_buffer[i].buffer == &rbuffer->b.b) {
r600_inval_vertex_cache(rctx); r600_inval_vertex_cache(rctx);
r600_atom_dirty(rctx, &rctx->vertex_buffer_state); r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
} }

View File

@@ -101,7 +101,8 @@ static INLINE bool r600_is_vertex_format_supported(enum pipe_format format)
/* No fixed, no double. */ /* No fixed, no double. */
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
(desc->channel[i].size == 64 && (desc->channel[i].size == 64 &&
desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)) desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) ||
desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
return false; return false;
/* No scaled/norm formats with 32 bits per channel. */ /* No scaled/norm formats with 32 bits per channel. */

View File

@@ -192,9 +192,6 @@ static void r600_destroy_context(struct pipe_context *context)
free(rctx->states[i]); free(rctx->states[i]);
} }
if (rctx->vbuf_mgr) {
u_vbuf_destroy(rctx->vbuf_mgr);
}
if (rctx->uploader) { if (rctx->uploader) {
u_upload_destroy(rctx->uploader); u_upload_destroy(rctx->uploader);
} }
@@ -216,7 +213,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
{ {
struct r600_context *rctx = CALLOC_STRUCT(r600_context); struct r600_context *rctx = CALLOC_STRUCT(r600_context);
struct r600_screen* rscreen = (struct r600_screen *)screen; struct r600_screen* rscreen = (struct r600_screen *)screen;
struct u_vbuf_caps vbuf_caps;
if (rctx == NULL) if (rctx == NULL)
return NULL; return NULL;
@@ -298,16 +294,6 @@ 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); rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
r600_emit_atom(rctx, &rctx->start_cs_cmd.atom); r600_emit_atom(rctx, &rctx->start_cs_cmd.atom);
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->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256, rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256,
PIPE_BIND_INDEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
PIPE_BIND_CONSTANT_BUFFER); PIPE_BIND_CONSTANT_BUFFER);

View File

@@ -284,7 +284,6 @@ struct r600_context {
struct r600_textures_info vs_samplers; struct r600_textures_info vs_samplers;
struct r600_textures_info ps_samplers; struct r600_textures_info ps_samplers;
struct u_vbuf *vbuf_mgr;
struct u_upload_mgr *uploader; struct u_upload_mgr *uploader;
struct util_slab_mempool pool_transfers; struct util_slab_mempool pool_transfers;
boolean have_depth_texture, have_depth_fb; boolean have_depth_texture, have_depth_fb;

View File

@@ -65,6 +65,7 @@
#include "util/u_inlines.h" #include "util/u_inlines.h"
#include "util/u_upload_mgr.h" #include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h" #include "cso_cache/cso_context.h"
#include "util/u_vbuf.h"
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE) DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)
@@ -111,6 +112,27 @@ st_get_msaa(void)
} }
static void st_init_vbuf(struct st_context *st)
{
struct u_vbuf_caps caps;
u_vbuf_get_caps(st->pipe->screen, &caps);
/* Create u_vbuf if there is anything unsupported. */
if (!caps.fetch_dword_unaligned ||
!caps.format_fixed32 ||
!caps.format_float16 ||
!caps.format_float64 ||
!caps.format_norm32 ||
!caps.format_scaled32 ||
!caps.user_vertex_buffers) {
/* XXX user vertex buffers are always uploaded regardless of the CAP. */
st->vbuf = u_vbuf_create(st->pipe, &caps);
cso_install_vbuf(st->cso_context, st->vbuf);
}
}
static struct st_context * static struct st_context *
st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
{ {
@@ -134,6 +156,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
st->cso_context = cso_create_context(pipe); st->cso_context = cso_create_context(pipe);
st_init_vbuf(st);
st_init_atoms( st ); st_init_atoms( st );
st_init_bitmap(st); st_init_bitmap(st);
st_init_clear(st); st_init_clear(st);
@@ -277,6 +300,9 @@ void st_destroy_context( struct st_context *st )
st_destroy_context_priv(st); st_destroy_context_priv(st);
if (st->vbuf)
u_vbuf_destroy(st->vbuf);
cso_destroy_context(cso); cso_destroy_context(cso);
pipe->destroy( pipe ); pipe->destroy( pipe );

View File

@@ -41,6 +41,7 @@ struct gen_mipmap_state;
struct st_context; struct st_context;
struct st_fragment_program; struct st_fragment_program;
struct u_upload_mgr; struct u_upload_mgr;
struct u_vbuf;
#define ST_NEW_MESA (1 << 0) /* Mesa state has changed */ #define ST_NEW_MESA (1 << 0) /* Mesa state has changed */
@@ -73,6 +74,8 @@ struct st_context
struct pipe_context *pipe; struct pipe_context *pipe;
struct u_upload_mgr *uploader; struct u_upload_mgr *uploader;
struct u_vbuf *vbuf;
struct draw_context *draw; /**< For selection/feedback/rastpos only */ struct draw_context *draw; /**< For selection/feedback/rastpos only */
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */ struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */