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:
@@ -41,6 +41,7 @@
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_vbuf.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
#include "cso_cache/cso_context.h"
|
||||
@@ -78,6 +79,7 @@ struct sampler_info
|
||||
struct cso_context {
|
||||
struct pipe_context *pipe;
|
||||
struct cso_cache *cache;
|
||||
struct u_vbuf *vbuf;
|
||||
|
||||
boolean has_geometry_shader;
|
||||
boolean has_streamout;
|
||||
@@ -268,6 +270,10 @@ out:
|
||||
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.
|
||||
@@ -780,11 +786,17 @@ enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_element *states)
|
||||
{
|
||||
struct u_vbuf *vbuf = ctx->vbuf;
|
||||
unsigned key_size, hash_key;
|
||||
struct cso_hash_iter iter;
|
||||
void *handle;
|
||||
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.
|
||||
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
|
||||
@@ -826,12 +838,26 @@ enum pipe_error cso_set_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);
|
||||
ctx->velements_saved = ctx->velements;
|
||||
}
|
||||
|
||||
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) {
|
||||
ctx->velements = 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,
|
||||
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 ||
|
||||
memcmp(buffers, ctx->vertex_buffers,
|
||||
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)
|
||||
{
|
||||
struct u_vbuf *vbuf = ctx->vbuf;
|
||||
|
||||
if (vbuf) {
|
||||
u_vbuf_save_vertex_buffers(vbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
util_copy_vertex_buffers(ctx->vertex_buffers_saved,
|
||||
&ctx->nr_vertex_buffers_saved,
|
||||
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)
|
||||
{
|
||||
unsigned i;
|
||||
struct u_vbuf *vbuf = ctx->vbuf;
|
||||
|
||||
if (vbuf) {
|
||||
u_vbuf_restore_vertex_buffers(vbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
util_copy_vertex_buffers(ctx->vertex_buffers,
|
||||
&ctx->nr_vertex_buffers,
|
||||
@@ -1298,16 +1344,28 @@ void
|
||||
cso_set_index_buffer(struct cso_context *cso,
|
||||
const struct pipe_index_buffer *ib)
|
||||
{
|
||||
struct pipe_context *pipe = cso->pipe;
|
||||
pipe->set_index_buffer(pipe, ib);
|
||||
struct u_vbuf *vbuf = cso->vbuf;
|
||||
|
||||
if (vbuf) {
|
||||
u_vbuf_set_index_buffer(vbuf, ib);
|
||||
} else {
|
||||
struct pipe_context *pipe = cso->pipe;
|
||||
pipe->set_index_buffer(pipe, ib);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cso_draw_vbo(struct cso_context *cso,
|
||||
const struct pipe_draw_info *info)
|
||||
{
|
||||
struct pipe_context *pipe = cso->pipe;
|
||||
pipe->draw_vbo(pipe, info);
|
||||
struct u_vbuf *vbuf = cso->vbuf;
|
||||
|
||||
if (vbuf) {
|
||||
u_vbuf_draw_vbo(vbuf, info);
|
||||
} else {
|
||||
struct pipe_context *pipe = cso->pipe;
|
||||
pipe->draw_vbo(pipe, info);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -39,9 +39,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct cso_context;
|
||||
struct u_vbuf;
|
||||
|
||||
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_destroy_context( struct cso_context *cso );
|
||||
|
@@ -66,12 +66,22 @@ enum {
|
||||
VB_NUM = 3
|
||||
};
|
||||
|
||||
struct u_vbuf_priv {
|
||||
struct u_vbuf b;
|
||||
struct u_vbuf {
|
||||
struct u_vbuf_caps caps;
|
||||
|
||||
struct pipe_context *pipe;
|
||||
struct translate_cache *translate_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.
|
||||
* There are no user buffers. */
|
||||
@@ -82,14 +92,14 @@ struct u_vbuf_priv {
|
||||
/* The index buffer. */
|
||||
struct pipe_index_buffer index_buffer;
|
||||
|
||||
/* and its associated helper structure for this module. */
|
||||
struct u_vbuf_elements *ve;
|
||||
/* Vertex elements. */
|
||||
struct u_vbuf_elements *ve, *ve_saved;
|
||||
|
||||
/* Vertex elements used for the translate fallback. */
|
||||
struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS];
|
||||
/* If non-NULL, this is a vertex element state used for the translate
|
||||
* fallback and therefore used for rendering too. */
|
||||
void *fallback_ve;
|
||||
boolean using_translate;
|
||||
/* The vertex buffer slot index where translated vertices have been
|
||||
* stored in. */
|
||||
unsigned fallback_vbs[VB_NUM];
|
||||
@@ -100,21 +110,14 @@ struct u_vbuf_priv {
|
||||
boolean incompatible_vb_layout;
|
||||
/* Per-buffer flags. */
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
struct u_vbuf_caps *caps)
|
||||
{
|
||||
struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv);
|
||||
struct u_vbuf *mgr = CALLOC_STRUCT(u_vbuf);
|
||||
|
||||
mgr->caps = *caps;
|
||||
mgr->pipe = pipe;
|
||||
@@ -170,23 +168,22 @@ u_vbuf_create(struct pipe_context *pipe,
|
||||
mgr->translate_cache = translate_cache_create();
|
||||
memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
|
||||
|
||||
mgr->b.uploader = u_upload_create(pipe, upload_buffer_size,
|
||||
upload_buffer_alignment,
|
||||
upload_buffer_bind);
|
||||
mgr->uploader = u_upload_create(pipe, 1024 * 1024, 4,
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
u_vbuf_install(mgr);
|
||||
return &mgr->b;
|
||||
return mgr;
|
||||
}
|
||||
|
||||
/* XXX I had to fork this off of cso_context. */
|
||||
static void *
|
||||
u_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_element *states)
|
||||
/* u_vbuf uses its own caching for vertex elements, because it needs to keep
|
||||
* its own preprocessed state per vertex element CSO. */
|
||||
static struct u_vbuf_elements *
|
||||
u_vbuf_set_vertex_elements_internal(struct u_vbuf *mgr, unsigned count,
|
||||
const struct pipe_vertex_element *states)
|
||||
{
|
||||
struct pipe_context *pipe = mgr->pipe;
|
||||
unsigned key_size, hash_key;
|
||||
struct cso_hash_iter iter;
|
||||
void *handle;
|
||||
struct u_vbuf_elements *ve;
|
||||
struct cso_velems_state velems_state;
|
||||
|
||||
/* 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)) {
|
||||
struct cso_velements *cso = MALLOC_STRUCT(cso_velements);
|
||||
memcpy(&cso->state, &velems_state, key_size);
|
||||
cso->data =
|
||||
mgr->driver_create_vertex_elements_state(mgr->pipe, count,
|
||||
&cso->state.velems[0]);
|
||||
cso->delete_state =
|
||||
(cso_state_callback)mgr->driver_delete_vertex_elements_state;
|
||||
cso->context = mgr->pipe;
|
||||
cso->data = u_vbuf_create_vertex_elements(mgr, count, states);
|
||||
cso->delete_state = (cso_state_callback)u_vbuf_delete_vertex_elements;
|
||||
cso->context = (void*)mgr;
|
||||
|
||||
iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso);
|
||||
handle = cso->data;
|
||||
ve = cso->data;
|
||||
} 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);
|
||||
return handle;
|
||||
assert(ve);
|
||||
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;
|
||||
|
||||
assert(mgr->pipe->draw);
|
||||
mgr->pipe->draw = 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_vertex_buffers; i++) {
|
||||
pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
|
||||
}
|
||||
for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
|
||||
pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
|
||||
}
|
||||
|
||||
translate_cache_destroy(mgr->translate_cache);
|
||||
u_upload_destroy(mgr->b.uploader);
|
||||
u_upload_destroy(mgr->uploader);
|
||||
cso_cache_delete(mgr->cso_cache);
|
||||
FREE(mgr);
|
||||
}
|
||||
|
||||
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,
|
||||
int start_vertex, unsigned num_vertices,
|
||||
int start_index, unsigned num_indices, int min_index,
|
||||
bool unroll_indices)
|
||||
boolean unroll_indices)
|
||||
{
|
||||
struct translate *tr;
|
||||
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);
|
||||
|
||||
/* 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)) {
|
||||
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;
|
||||
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. */
|
||||
u_upload_alloc(mgr->b.uploader, 0,
|
||||
u_upload_alloc(mgr->uploader, 0,
|
||||
key->output_stride * num_indices,
|
||||
&out_offset, &out_buffer,
|
||||
(void**)&out_map);
|
||||
@@ -325,7 +322,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
|
||||
}
|
||||
} else {
|
||||
/* 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 * num_vertices,
|
||||
&out_offset, &out_buffer,
|
||||
@@ -337,7 +334,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key,
|
||||
}
|
||||
|
||||
/* 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]) {
|
||||
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
|
||||
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 i, type;
|
||||
@@ -392,7 +389,7 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr,
|
||||
}
|
||||
if (i == PIPE_MAX_ATTRIBS) {
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
@@ -403,11 +400,11 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr,
|
||||
}
|
||||
|
||||
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_instance, unsigned num_instances,
|
||||
int start_index, unsigned num_indices, int min_index,
|
||||
bool unroll_indices)
|
||||
boolean unroll_indices)
|
||||
{
|
||||
unsigned mask[VB_NUM] = {0};
|
||||
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++) {
|
||||
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] &&
|
||||
!mgr->incompatible_vb[vb_index]) {
|
||||
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,
|
||||
mgr->fallback_velems);
|
||||
u_vbuf_set_vertex_elements_internal(mgr, mgr->ve->count,
|
||||
mgr->fallback_velems);
|
||||
mgr->using_translate = 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;
|
||||
|
||||
/* Restore vertex elements. */
|
||||
mgr->driver_bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso);
|
||||
mgr->fallback_ve = NULL;
|
||||
mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso);
|
||||
mgr->using_translate = FALSE;
|
||||
|
||||
/* Unreference the now-unused VBOs. */
|
||||
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->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers;
|
||||
mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
|
||||
}
|
||||
|
||||
#define FORMAT_REPLACE(what, withwhat) \
|
||||
case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
|
||||
|
||||
static void *
|
||||
u_vbuf_create_vertex_elements(struct pipe_context *pipe,
|
||||
unsigned count,
|
||||
u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
|
||||
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;
|
||||
struct pipe_vertex_element native_attribs[PIPE_MAX_ATTRIBS];
|
||||
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 =
|
||||
mgr->driver_create_vertex_elements_state(pipe, count, native_attribs);
|
||||
pipe->create_vertex_elements_state(pipe, count, native_attribs);
|
||||
return ve;
|
||||
}
|
||||
|
||||
static void u_vbuf_bind_vertex_elements(struct pipe_context *pipe,
|
||||
void *cso)
|
||||
static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, 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;
|
||||
|
||||
mgr->ve = ve;
|
||||
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);
|
||||
pipe->delete_vertex_elements_state(pipe, ve->driver_cso);
|
||||
FREE(ve);
|
||||
}
|
||||
|
||||
static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_buffer *bufs)
|
||||
void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
|
||||
const struct pipe_vertex_buffer *bufs)
|
||||
{
|
||||
struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
|
||||
unsigned i;
|
||||
|
||||
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++) {
|
||||
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->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->b.vertex_buffer[i].stride = vb->stride;
|
||||
mgr->vertex_buffer[i].stride = vb->stride;
|
||||
|
||||
if (!vb->buffer ||
|
||||
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);
|
||||
}
|
||||
|
||||
for (i = count; i < mgr->b.nr_vertex_buffers; i++) {
|
||||
pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL);
|
||||
for (i = count; i < mgr->nr_vertex_buffers; i++) {
|
||||
pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
|
||||
}
|
||||
for (i = count; i < mgr->nr_real_vertex_buffers; i++) {
|
||||
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->vertex_buffers_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void u_vbuf_set_index_buffer(struct pipe_context *pipe,
|
||||
const struct pipe_index_buffer *ib)
|
||||
void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
|
||||
const struct pipe_index_buffer *ib)
|
||||
{
|
||||
struct u_vbuf_priv *mgr = pipe->draw;
|
||||
struct pipe_context *pipe = mgr->pipe;
|
||||
|
||||
if (ib && ib->buffer) {
|
||||
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);
|
||||
}
|
||||
|
||||
mgr->driver_set_index_buffer(pipe, ib);
|
||||
pipe->set_index_buffer(pipe, ib);
|
||||
}
|
||||
|
||||
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_instance, unsigned num_instances)
|
||||
{
|
||||
unsigned i;
|
||||
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 =
|
||||
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 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++) {
|
||||
struct pipe_vertex_element *velem = &velems[i];
|
||||
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;
|
||||
|
||||
/* Skip the buffers generated by translate. */
|
||||
@@ -850,16 +833,16 @@ u_vbuf_upload_buffers(struct u_vbuf_priv *mgr,
|
||||
assert(start < end);
|
||||
|
||||
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 -= 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;
|
||||
|
||||
@@ -873,7 +856,7 @@ static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr)
|
||||
}
|
||||
|
||||
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. */
|
||||
if (!vb->stride) {
|
||||
@@ -891,7 +874,7 @@ static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr)
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
vb = &mgr->b.vertex_buffer[index];
|
||||
vb = &mgr->vertex_buffer[index];
|
||||
|
||||
/* Constant attribs are not per-vertex data. */
|
||||
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,
|
||||
const struct pipe_draw_info *info)
|
||||
void u_vbuf_draw_vbo(struct u_vbuf *mgr, 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;
|
||||
unsigned num_vertices;
|
||||
bool unroll_indices = false;
|
||||
boolean unroll_indices = FALSE;
|
||||
|
||||
/* Normal draw. No fallback and no user buffers. */
|
||||
if (!mgr->incompatible_vb_layout &&
|
||||
@@ -1037,27 +1019,27 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
|
||||
!mgr->any_user_vbs) {
|
||||
/* Set vertex buffers if needed. */
|
||||
if (mgr->vertex_buffers_dirty) {
|
||||
mgr->driver_set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
|
||||
mgr->real_vertex_buffer);
|
||||
pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
|
||||
mgr->real_vertex_buffer);
|
||||
mgr->vertex_buffers_dirty = FALSE;
|
||||
}
|
||||
|
||||
mgr->driver_draw_vbo(pipe, info);
|
||||
pipe->draw_vbo(pipe, info);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->indexed) {
|
||||
int max_index;
|
||||
bool index_bounds_valid = false;
|
||||
boolean index_bounds_valid = FALSE;
|
||||
|
||||
if (info->max_index != ~0) {
|
||||
min_index = info->min_index;
|
||||
max_index = info->max_index;
|
||||
index_bounds_valid = true;
|
||||
index_bounds_valid = TRUE;
|
||||
} else if (u_vbuf_need_minmax_index(mgr)) {
|
||||
u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info,
|
||||
&min_index, &max_index);
|
||||
index_bounds_valid = true;
|
||||
index_bounds_valid = TRUE;
|
||||
}
|
||||
|
||||
/* 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 &&
|
||||
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
|
||||
/*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/
|
||||
unroll_indices = true;
|
||||
unroll_indices = TRUE;
|
||||
}
|
||||
} else {
|
||||
/* Nothing to do for per-vertex attribs. */
|
||||
@@ -1117,9 +1099,9 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe,
|
||||
}
|
||||
|
||||
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);
|
||||
util_dump_vertex_buffer(stdout, mgr->b.vertex_buffer+i);
|
||||
util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i);
|
||||
printf("\n");
|
||||
}
|
||||
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,
|
||||
mgr->real_vertex_buffer);
|
||||
u_upload_unmap(mgr->uploader);
|
||||
pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
|
||||
mgr->real_vertex_buffer);
|
||||
|
||||
if (unlikely(unroll_indices)) {
|
||||
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.start = 0;
|
||||
|
||||
mgr->driver_draw_vbo(pipe, &new_info);
|
||||
pipe->draw_vbo(pipe, &new_info);
|
||||
} 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);
|
||||
}
|
||||
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(!pipe->draw);
|
||||
|
||||
pipe->draw = mgr;
|
||||
mgr->driver_set_index_buffer = pipe->set_index_buffer;
|
||||
mgr->driver_set_vertex_buffers = pipe->set_vertex_buffers;
|
||||
mgr->driver_create_vertex_elements_state =
|
||||
pipe->create_vertex_elements_state;
|
||||
mgr->driver_bind_vertex_elements_state = pipe->bind_vertex_elements_state;
|
||||
mgr->driver_delete_vertex_elements_state =
|
||||
pipe->delete_vertex_elements_state;
|
||||
mgr->driver_draw_vbo = pipe->draw_vbo;
|
||||
|
||||
pipe->set_index_buffer = u_vbuf_set_index_buffer;
|
||||
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;
|
||||
pipe->delete_vertex_elements_state = u_vbuf_delete_vertex_elements;
|
||||
pipe->draw_vbo = u_vbuf_draw_vbo;
|
||||
assert(!mgr->ve_saved);
|
||||
mgr->ve_saved = mgr->ve;
|
||||
}
|
||||
|
||||
void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr)
|
||||
{
|
||||
if (mgr->ve != mgr->ve_saved) {
|
||||
struct pipe_context *pipe = mgr->pipe;
|
||||
|
||||
mgr->ve = mgr->ve_saved;
|
||||
pipe->bind_vertex_elements_state(pipe,
|
||||
mgr->ve ? mgr->ve->driver_cso : NULL);
|
||||
}
|
||||
mgr->ve_saved = NULL;
|
||||
}
|
||||
|
||||
void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@@ -25,8 +25,8 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef U_VBUF_MGR_H
|
||||
#define U_VBUF_MGR_H
|
||||
#ifndef U_VBUF_H
|
||||
#define U_VBUF_H
|
||||
|
||||
/* This module builds upon u_upload_mgr and translate_cache and takes care of
|
||||
* user buffer uploads and vertex format fallbacks. It's designed
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct cso_context;
|
||||
struct u_vbuf;
|
||||
|
||||
/* Hardware vertex fetcher limitations can be described by this structure. */
|
||||
struct u_vbuf_caps {
|
||||
/* Vertex format CAPs. */
|
||||
@@ -54,41 +57,28 @@ struct u_vbuf_caps {
|
||||
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);
|
||||
|
||||
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);
|
||||
struct u_vbuf_caps *caps);
|
||||
|
||||
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
|
||||
|
@@ -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_vertex_shader(r300->blitter, r300->vs_state.state);
|
||||
util_blitter_save_viewport(r300->blitter, &r300->viewport);
|
||||
if (r300->vbuf_mgr) {
|
||||
util_blitter_save_vertex_buffers(r300->blitter, r300->vbuf_mgr->nr_vertex_buffers,
|
||||
r300->vbuf_mgr->vertex_buffer);
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
|
||||
|
@@ -100,9 +100,6 @@ static void r300_destroy_context(struct pipe_context* context)
|
||||
if (r300->draw)
|
||||
draw_destroy(r300->draw);
|
||||
|
||||
if (r300->vbuf_mgr)
|
||||
u_vbuf_destroy(r300->vbuf_mgr);
|
||||
|
||||
u_upload_destroy(r300->uploader);
|
||||
|
||||
/* 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_buffer = vl_video_buffer_create;
|
||||
|
||||
if (r300->screen->caps.has_tcl) {
|
||||
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,
|
||||
r300->uploader = u_upload_create(&r300->context, 256 * 1024, 4,
|
||||
PIPE_BIND_INDEX_BUFFER);
|
||||
|
||||
r300->blitter = util_blitter_create(&r300->context);
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_transfer.h"
|
||||
#include "util/u_vbuf.h"
|
||||
|
||||
#include "r300_defines.h"
|
||||
#include "r300_screen.h"
|
||||
@@ -576,7 +575,6 @@ struct r300_context {
|
||||
|
||||
void *dsa_decompress_zmask;
|
||||
|
||||
struct u_vbuf *vbuf_mgr;
|
||||
struct pipe_index_buffer index_buffer;
|
||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
unsigned nr_vertex_buffers;
|
||||
|
@@ -361,10 +361,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
||||
format == PIPE_FORMAT_R16G16_FLOAT ||
|
||||
format == PIPE_FORMAT_R16G16B16_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))
|
||||
return FALSE;
|
||||
@@ -428,8 +424,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
|
||||
if (usage & PIPE_BIND_VERTEX_BUFFER &&
|
||||
/* Half float is supported on >= R400. */
|
||||
(is_r400 || is_r500 || !is_half_float) &&
|
||||
/* We have a fallback for FIXED. */
|
||||
(is_fixed || r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT)) {
|
||||
r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) {
|
||||
retval |= PIPE_BIND_VERTEX_BUFFER;
|
||||
}
|
||||
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include "../../winsys/radeon/drm/radeon_winsys.h"
|
||||
#include "util/u_double_list.h"
|
||||
#include "util/u_transfer.h"
|
||||
#include "util/u_vbuf.h"
|
||||
|
||||
#define R600_ERR(fmt, args...) \
|
||||
fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args)
|
||||
|
@@ -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_fragment_shader(rctx->blitter, rctx->ps_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]) {
|
||||
util_blitter_save_viewport(rctx->blitter, &rctx->viewport);
|
||||
}
|
||||
util_blitter_save_vertex_buffers(rctx->blitter,
|
||||
rctx->vbuf_mgr->nr_vertex_buffers,
|
||||
rctx->vbuf_mgr->vertex_buffer);
|
||||
rctx->nr_vertex_buffers,
|
||||
rctx->vertex_buffer);
|
||||
util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
|
||||
(struct pipe_stream_output_target**)rctx->so_targets);
|
||||
|
||||
|
@@ -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. */
|
||||
/* Vertex buffers. */
|
||||
for (i = 0; i < rctx->vbuf_mgr->nr_vertex_buffers; i++) {
|
||||
if (rctx->vbuf_mgr->vertex_buffer[i].buffer == &rbuffer->b.b) {
|
||||
for (i = 0; i < rctx->nr_vertex_buffers; i++) {
|
||||
if (rctx->vertex_buffer[i].buffer == &rbuffer->b.b) {
|
||||
r600_inval_vertex_cache(rctx);
|
||||
r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
|
||||
}
|
||||
|
@@ -101,7 +101,8 @@ static INLINE bool r600_is_vertex_format_supported(enum pipe_format format)
|
||||
/* No fixed, no double. */
|
||||
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
|
||||
(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;
|
||||
|
||||
/* No scaled/norm formats with 32 bits per channel. */
|
||||
|
@@ -192,9 +192,6 @@ static void r600_destroy_context(struct pipe_context *context)
|
||||
free(rctx->states[i]);
|
||||
}
|
||||
|
||||
if (rctx->vbuf_mgr) {
|
||||
u_vbuf_destroy(rctx->vbuf_mgr);
|
||||
}
|
||||
if (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_screen* rscreen = (struct r600_screen *)screen;
|
||||
struct u_vbuf_caps vbuf_caps;
|
||||
|
||||
if (rctx == 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);
|
||||
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,
|
||||
PIPE_BIND_INDEX_BUFFER |
|
||||
PIPE_BIND_CONSTANT_BUFFER);
|
||||
|
@@ -284,7 +284,6 @@ struct r600_context {
|
||||
struct r600_textures_info vs_samplers;
|
||||
struct r600_textures_info ps_samplers;
|
||||
|
||||
struct u_vbuf *vbuf_mgr;
|
||||
struct u_upload_mgr *uploader;
|
||||
struct util_slab_mempool pool_transfers;
|
||||
boolean have_depth_texture, have_depth_fb;
|
||||
|
@@ -65,6 +65,7 @@
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "cso_cache/cso_context.h"
|
||||
#include "util/u_vbuf.h"
|
||||
|
||||
|
||||
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 *
|
||||
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->cso_context = cso_create_context(pipe);
|
||||
|
||||
st_init_vbuf(st);
|
||||
st_init_atoms( st );
|
||||
st_init_bitmap(st);
|
||||
st_init_clear(st);
|
||||
@@ -277,6 +300,9 @@ void st_destroy_context( struct st_context *st )
|
||||
|
||||
st_destroy_context_priv(st);
|
||||
|
||||
if (st->vbuf)
|
||||
u_vbuf_destroy(st->vbuf);
|
||||
|
||||
cso_destroy_context(cso);
|
||||
|
||||
pipe->destroy( pipe );
|
||||
|
@@ -41,6 +41,7 @@ struct gen_mipmap_state;
|
||||
struct st_context;
|
||||
struct st_fragment_program;
|
||||
struct u_upload_mgr;
|
||||
struct u_vbuf;
|
||||
|
||||
|
||||
#define ST_NEW_MESA (1 << 0) /* Mesa state has changed */
|
||||
@@ -73,6 +74,8 @@ struct st_context
|
||||
struct pipe_context *pipe;
|
||||
|
||||
struct u_upload_mgr *uploader;
|
||||
struct u_vbuf *vbuf;
|
||||
|
||||
struct draw_context *draw; /**< For selection/feedback/rastpos only */
|
||||
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
|
||||
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */
|
||||
|
Reference in New Issue
Block a user