r600g: use the new vertex buffer manager
This commit is contained in:
@@ -2052,10 +2052,10 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
|
||||
|
||||
for (i = 0; i < ve->count; i++) {
|
||||
unsigned vbuffer_index;
|
||||
r600_vertex_data_type(ve->hw_format[i], &format, &num_format, &format_comp);
|
||||
desc = util_format_description(ve->hw_format[i]);
|
||||
r600_vertex_data_type(ve->elements[i].src_format, &format, &num_format, &format_comp);
|
||||
desc = util_format_description(ve->elements[i].src_format);
|
||||
if (desc == NULL) {
|
||||
R600_ERR("unknown format %d\n", ve->hw_format[i]);
|
||||
R600_ERR("unknown format %d\n", ve->elements[i].src_format);
|
||||
r600_bo_reference(rctx->radeon, &ve->fetch_shader, NULL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,9 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
|
||||
if (rctx->states[R600_PIPE_STATE_CLIP]) {
|
||||
util_blitter_save_clip(rctx->blitter, &rctx->clip);
|
||||
}
|
||||
util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffers, rctx->vertex_buffer);
|
||||
util_blitter_save_vertex_buffers(rctx->blitter,
|
||||
rctx->vbuf_mgr->nr_vertex_buffers,
|
||||
rctx->vbuf_mgr->vertex_buffer);
|
||||
|
||||
if (op & (R600_CLEAR_SURFACE | R600_COPY))
|
||||
util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer);
|
||||
@@ -88,13 +90,13 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t
|
||||
if (!texture->dirty_db)
|
||||
return;
|
||||
|
||||
surf_tmpl.format = texture->resource.base.b.format;
|
||||
surf_tmpl.format = texture->resource.b.b.b.format;
|
||||
surf_tmpl.u.tex.level = level;
|
||||
surf_tmpl.u.tex.first_layer = 0;
|
||||
surf_tmpl.u.tex.last_layer = 0;
|
||||
surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL;
|
||||
|
||||
zsurf = ctx->create_surface(ctx, &texture->resource.base.b, &surf_tmpl);
|
||||
zsurf = ctx->create_surface(ctx, &texture->resource.b.b.b, &surf_tmpl);
|
||||
|
||||
surf_tmpl.format = ((struct pipe_resource*)texture->flushed_depth_texture)->format;
|
||||
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
|
||||
@@ -248,8 +250,8 @@ void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture
|
||||
struct pipe_box sbox;
|
||||
|
||||
sbox.x = sbox.y = sbox.z = 0;
|
||||
sbox.width = texture->resource.base.b.width0;
|
||||
sbox.height = texture->resource.base.b.height0;
|
||||
sbox.width = texture->resource.b.b.b.width0;
|
||||
sbox.height = texture->resource.b.b.b.height0;
|
||||
/* XXX that might be wrong */
|
||||
sbox.depth = 1;
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
|
||||
int write = 0;
|
||||
uint8_t *data;
|
||||
|
||||
if (rbuffer->user_buffer)
|
||||
return (uint8_t*)rbuffer->user_buffer + transfer->box.x;
|
||||
if (rbuffer->r.b.user_ptr)
|
||||
return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x;
|
||||
|
||||
if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
|
||||
/* FIXME */
|
||||
@@ -87,7 +87,7 @@ static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
|
||||
{
|
||||
struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
|
||||
|
||||
if (rbuffer->user_buffer)
|
||||
if (rbuffer->r.b.user_ptr)
|
||||
return;
|
||||
|
||||
if (rbuffer->r.bo)
|
||||
@@ -126,20 +126,25 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
|
||||
return NULL;
|
||||
|
||||
rbuffer->magic = R600_BUFFER_MAGIC;
|
||||
rbuffer->user_buffer = NULL;
|
||||
rbuffer->r.base.b = *templ;
|
||||
pipe_reference_init(&rbuffer->r.base.b.reference, 1);
|
||||
rbuffer->r.base.b.screen = screen;
|
||||
rbuffer->r.base.vtbl = &r600_buffer_vtbl;
|
||||
rbuffer->r.size = rbuffer->r.base.b.width0;
|
||||
rbuffer->r.b.b.b = *templ;
|
||||
pipe_reference_init(&rbuffer->r.b.b.b.reference, 1);
|
||||
rbuffer->r.b.b.b.screen = screen;
|
||||
rbuffer->r.b.b.vtbl = &r600_buffer_vtbl;
|
||||
rbuffer->r.b.user_ptr = NULL;
|
||||
rbuffer->r.size = rbuffer->r.b.b.b.width0;
|
||||
rbuffer->r.bo_size = rbuffer->r.size;
|
||||
bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage);
|
||||
|
||||
bo = r600_bo((struct radeon*)screen->winsys,
|
||||
rbuffer->r.b.b.b.width0,
|
||||
alignment, rbuffer->r.b.b.b.bind,
|
||||
rbuffer->r.b.b.b.usage);
|
||||
|
||||
if (bo == NULL) {
|
||||
FREE(rbuffer);
|
||||
return NULL;
|
||||
}
|
||||
rbuffer->r.bo = bo;
|
||||
return &rbuffer->r.base.b;
|
||||
return &rbuffer->r.b.b.b;
|
||||
}
|
||||
|
||||
struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
|
||||
@@ -153,22 +158,22 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
|
||||
return NULL;
|
||||
|
||||
rbuffer->magic = R600_BUFFER_MAGIC;
|
||||
pipe_reference_init(&rbuffer->r.base.b.reference, 1);
|
||||
rbuffer->r.base.vtbl = &r600_buffer_vtbl;
|
||||
rbuffer->r.base.b.screen = screen;
|
||||
rbuffer->r.base.b.target = PIPE_BUFFER;
|
||||
rbuffer->r.base.b.format = PIPE_FORMAT_R8_UNORM;
|
||||
rbuffer->r.base.b.usage = PIPE_USAGE_IMMUTABLE;
|
||||
rbuffer->r.base.b.bind = bind;
|
||||
rbuffer->r.base.b.width0 = bytes;
|
||||
rbuffer->r.base.b.height0 = 1;
|
||||
rbuffer->r.base.b.depth0 = 1;
|
||||
rbuffer->r.base.b.array_size = 1;
|
||||
rbuffer->r.base.b.flags = 0;
|
||||
pipe_reference_init(&rbuffer->r.b.b.b.reference, 1);
|
||||
rbuffer->r.b.b.vtbl = &r600_buffer_vtbl;
|
||||
rbuffer->r.b.b.b.screen = screen;
|
||||
rbuffer->r.b.b.b.target = PIPE_BUFFER;
|
||||
rbuffer->r.b.b.b.format = PIPE_FORMAT_R8_UNORM;
|
||||
rbuffer->r.b.b.b.usage = PIPE_USAGE_IMMUTABLE;
|
||||
rbuffer->r.b.b.b.bind = bind;
|
||||
rbuffer->r.b.b.b.width0 = bytes;
|
||||
rbuffer->r.b.b.b.height0 = 1;
|
||||
rbuffer->r.b.b.b.depth0 = 1;
|
||||
rbuffer->r.b.b.b.array_size = 1;
|
||||
rbuffer->r.b.b.b.flags = 0;
|
||||
rbuffer->r.b.user_ptr = ptr;
|
||||
rbuffer->r.bo = NULL;
|
||||
rbuffer->r.bo_size = 0;
|
||||
rbuffer->user_buffer = ptr;
|
||||
return &rbuffer->r.base.b;
|
||||
return &rbuffer->r.b.b.b;
|
||||
}
|
||||
|
||||
struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
|
||||
@@ -189,12 +194,12 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pipe_reference_init(&rbuffer->base.b.reference, 1);
|
||||
rbuffer->base.b.target = PIPE_BUFFER;
|
||||
rbuffer->base.b.screen = screen;
|
||||
rbuffer->base.vtbl = &r600_buffer_vtbl;
|
||||
pipe_reference_init(&rbuffer->b.b.b.reference, 1);
|
||||
rbuffer->b.b.b.target = PIPE_BUFFER;
|
||||
rbuffer->b.b.b.screen = screen;
|
||||
rbuffer->b.b.vtbl = &r600_buffer_vtbl;
|
||||
rbuffer->bo = bo;
|
||||
return &rbuffer->base.b;
|
||||
return &rbuffer->b.b.b;
|
||||
}
|
||||
|
||||
void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw)
|
||||
@@ -202,59 +207,19 @@ void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl
|
||||
struct r600_resource_buffer *rbuffer = r600_buffer(draw->index_buffer);
|
||||
boolean flushed;
|
||||
|
||||
u_upload_data(rctx->upload_vb, 0,
|
||||
u_upload_data(rctx->upload_ib, 0,
|
||||
draw->info.count * draw->index_size,
|
||||
rbuffer->user_buffer,
|
||||
rbuffer->r.b.user_ptr,
|
||||
&draw->index_buffer_offset,
|
||||
&draw->index_buffer, &flushed);
|
||||
}
|
||||
|
||||
void r600_upload_user_buffers(struct r600_pipe_context *rctx,
|
||||
int min_index, int max_index)
|
||||
{
|
||||
int i, nr = rctx->vertex_elements->count;
|
||||
unsigned count = max_index + 1 - min_index;
|
||||
boolean flushed;
|
||||
boolean uploaded[32] = {0};
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
unsigned index = rctx->vertex_elements->elements[i].vertex_buffer_index;
|
||||
struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[index];
|
||||
struct r600_resource_buffer *userbuf = r600_buffer(vb->buffer);
|
||||
|
||||
if (userbuf && userbuf->user_buffer && !uploaded[index]) {
|
||||
unsigned first, size;
|
||||
|
||||
if (vb->stride) {
|
||||
first = vb->stride * min_index;
|
||||
size = vb->stride * count;
|
||||
} else {
|
||||
first = 0;
|
||||
size = rctx->vertex_elements->hw_format_size[i];
|
||||
}
|
||||
|
||||
u_upload_data(rctx->upload_vb, first, size,
|
||||
(uint8_t*)userbuf->user_buffer + first,
|
||||
&vb->buffer_offset,
|
||||
&rctx->real_vertex_buffer[index],
|
||||
&flushed);
|
||||
|
||||
vb->buffer_offset -= first;
|
||||
|
||||
/* vertex_arrays_dirty = TRUE; */
|
||||
uploaded[index] = TRUE;
|
||||
} else {
|
||||
assert(rctx->real_vertex_buffer[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource_buffer **rbuffer,
|
||||
uint32_t *const_offset)
|
||||
{
|
||||
if ((*rbuffer)->user_buffer) {
|
||||
uint8_t *ptr = (*rbuffer)->user_buffer;
|
||||
unsigned size = (*rbuffer)->r.base.b.width0;
|
||||
if ((*rbuffer)->r.b.user_ptr) {
|
||||
uint8_t *ptr = (*rbuffer)->r.b.user_ptr;
|
||||
unsigned size = (*rbuffer)->r.b.b.b.width0;
|
||||
boolean flushed;
|
||||
|
||||
*rbuffer = NULL;
|
||||
|
||||
@@ -76,8 +76,6 @@ static void r600_destroy_context(struct pipe_context *context)
|
||||
|
||||
rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
|
||||
|
||||
r600_end_vertex_translate(rctx);
|
||||
|
||||
r600_context_fini(&rctx->ctx);
|
||||
|
||||
util_blitter_destroy(rctx->blitter);
|
||||
@@ -86,11 +84,9 @@ static void r600_destroy_context(struct pipe_context *context)
|
||||
free(rctx->states[i]);
|
||||
}
|
||||
|
||||
u_upload_destroy(rctx->upload_vb);
|
||||
u_upload_destroy(rctx->upload_ib);
|
||||
u_upload_destroy(rctx->upload_const);
|
||||
|
||||
if (rctx->tran.translate_cache)
|
||||
translate_cache_destroy(rctx->tran.translate_cache);
|
||||
u_vbuf_mgr_destroy(rctx->vbuf_mgr);
|
||||
|
||||
FREE(rctx->ps_resource);
|
||||
FREE(rctx->vs_resource);
|
||||
@@ -164,10 +160,16 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rctx->upload_vb = u_upload_create(&rctx->context, 1024 * 1024, 16,
|
||||
PIPE_BIND_VERTEX_BUFFER |
|
||||
rctx->vbuf_mgr = u_vbuf_mgr_create(&rctx->context, 1024 * 1024, 16,
|
||||
U_VERTEX_FETCH_BYTE_ALIGNED);
|
||||
if (!rctx->vbuf_mgr) {
|
||||
r600_destroy_context(&rctx->context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rctx->upload_ib = u_upload_create(&rctx->context, 128 * 1024, 16,
|
||||
PIPE_BIND_INDEX_BUFFER);
|
||||
if (rctx->upload_vb == NULL) {
|
||||
if (rctx->upload_ib == NULL) {
|
||||
r600_destroy_context(&rctx->context);
|
||||
return NULL;
|
||||
}
|
||||
@@ -185,12 +187,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rctx->tran.translate_cache = translate_cache_create();
|
||||
if (rctx->tran.translate_cache == NULL) {
|
||||
FREE(rctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rctx->vs_resource = CALLOC(R600_RESOURCE_ARRAY_SIZE, sizeof(struct r600_pipe_state));
|
||||
if (!rctx->vs_resource) {
|
||||
FREE(rctx);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <pipe/p_screen.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <util/u_math.h>
|
||||
#include "translate/translate_cache.h"
|
||||
#include "util/u_vbuf_mgr.h"
|
||||
#include "r600.h"
|
||||
#include "r600_public.h"
|
||||
#include "r600_shader.h"
|
||||
@@ -86,9 +86,7 @@ struct r600_vertex_element
|
||||
{
|
||||
unsigned count;
|
||||
struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS];
|
||||
enum pipe_format hw_format[PIPE_MAX_ATTRIBS];
|
||||
unsigned hw_format_size[PIPE_MAX_ATTRIBS];
|
||||
boolean incompatible_layout;
|
||||
struct u_vbuf_mgr_elements *vmgr_elements;
|
||||
struct r600_bo *fetch_shader;
|
||||
unsigned fs_size;
|
||||
struct r600_pipe_state rstate;
|
||||
@@ -117,18 +115,6 @@ struct r600_textures_info {
|
||||
unsigned n_samplers;
|
||||
};
|
||||
|
||||
/* vertex buffer translation context, used to translate vertex input that
|
||||
* hw doesn't natively support, so far only FLOAT64 is unsupported.
|
||||
*/
|
||||
struct r600_translate_context {
|
||||
/* Translate cache for incompatible vertex offset/stride/format fallback. */
|
||||
struct translate_cache *translate_cache;
|
||||
/* The vertex buffer slot containing the translated buffer. */
|
||||
unsigned vb_slot;
|
||||
void *saved_velems;
|
||||
void *new_velems;
|
||||
};
|
||||
|
||||
#define R600_CONSTANT_ARRAY_SIZE 256
|
||||
#define R600_RESOURCE_ARRAY_SIZE 160
|
||||
|
||||
@@ -144,10 +130,6 @@ struct r600_pipe_context {
|
||||
struct r600_vertex_element *vertex_elements;
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_index_buffer index_buffer;
|
||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_resource *real_vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
unsigned nvertex_buffers;
|
||||
unsigned nreal_vertex_buffers; /* with the translated vertex buffer */
|
||||
unsigned cb_target_mask;
|
||||
/* for saving when using blitter */
|
||||
struct pipe_stencil_ref stencil_ref;
|
||||
@@ -165,11 +147,10 @@ struct r600_pipe_context {
|
||||
/* shader information */
|
||||
unsigned sprite_coord_enable;
|
||||
bool flatshade;
|
||||
struct u_upload_mgr *upload_vb;
|
||||
unsigned any_user_vbs;
|
||||
struct r600_textures_info ps_samplers;
|
||||
unsigned vb_max_index;
|
||||
struct r600_translate_context tran;
|
||||
|
||||
struct u_vbuf_mgr *vbuf_mgr;
|
||||
struct u_upload_mgr *upload_ib;
|
||||
struct u_upload_mgr *upload_const;
|
||||
bool blit;
|
||||
};
|
||||
@@ -210,8 +191,6 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
|
||||
struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
|
||||
struct winsys_handle *whandle);
|
||||
void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw);
|
||||
void r600_upload_user_buffers(struct r600_pipe_context *rctx,
|
||||
int min_index, int max_index);
|
||||
|
||||
/* r600_query.c */
|
||||
void r600_init_query_functions(struct r600_pipe_context *rctx);
|
||||
@@ -250,9 +229,6 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
|
||||
unsigned level, unsigned layer);
|
||||
|
||||
/* r600_translate.c */
|
||||
void r600_begin_vertex_translate(struct r600_pipe_context *rctx,
|
||||
int min_index, int max_index);
|
||||
void r600_end_vertex_translate(struct r600_pipe_context *rctx);
|
||||
void r600_translate_index_buffer(struct r600_pipe_context *r600,
|
||||
struct pipe_resource **index_buffer,
|
||||
unsigned *index_size,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define R600_RESOURCE_H
|
||||
|
||||
#include "util/u_transfer.h"
|
||||
#include "util/u_vbuf_mgr.h"
|
||||
|
||||
/* flag to indicate a resource is to be used as a transfer so should not be tiled */
|
||||
#define R600_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV
|
||||
@@ -43,7 +44,7 @@ struct r600_transfer {
|
||||
* underlying implementations.
|
||||
*/
|
||||
struct r600_resource {
|
||||
struct u_resource base;
|
||||
struct u_vbuf_resource b;
|
||||
struct r600_bo *bo;
|
||||
u32 size;
|
||||
unsigned bo_size;
|
||||
@@ -68,10 +69,10 @@ struct r600_resource_texture {
|
||||
|
||||
#define R600_BUFFER_MAGIC 0xabcd1600
|
||||
|
||||
/* XXX this could be removed */
|
||||
struct r600_resource_buffer {
|
||||
struct r600_resource r;
|
||||
uint32_t magic;
|
||||
void *user_buffer;
|
||||
};
|
||||
|
||||
struct r600_surface {
|
||||
@@ -98,11 +99,6 @@ static INLINE struct r600_resource_buffer *r600_buffer(struct pipe_resource *buf
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static INLINE boolean r600_is_user_buffer(struct pipe_resource *buffer)
|
||||
{
|
||||
return r600_buffer(buffer)->user_buffer ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture, boolean just_create);
|
||||
|
||||
/* r600_texture.c texture transfer functions. */
|
||||
|
||||
@@ -123,6 +123,9 @@ void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
|
||||
|
||||
rctx->vertex_elements = v;
|
||||
if (v) {
|
||||
u_vbuf_mgr_bind_vertex_elements(rctx->vbuf_mgr, state,
|
||||
v->vmgr_elements);
|
||||
|
||||
rctx->states[v->rstate.id] = &v->rstate;
|
||||
r600_context_pipe_state_set(&rctx->ctx, &v->rstate);
|
||||
}
|
||||
@@ -140,6 +143,7 @@ void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
|
||||
rctx->vertex_elements = NULL;
|
||||
|
||||
r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL);
|
||||
u_vbuf_mgr_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
@@ -164,52 +168,19 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
|
||||
const struct pipe_vertex_buffer *buffers)
|
||||
{
|
||||
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
||||
struct pipe_vertex_buffer *vbo;
|
||||
unsigned max_index = ~0;
|
||||
int i;
|
||||
|
||||
/* Zero states. */
|
||||
for (i = 0; i < count; i++) {
|
||||
vbo = (struct pipe_vertex_buffer*)&buffers[i];
|
||||
|
||||
pipe_resource_reference(&rctx->vertex_buffer[i].buffer, vbo->buffer);
|
||||
pipe_resource_reference(&rctx->real_vertex_buffer[i], NULL);
|
||||
|
||||
if (!vbo->buffer) {
|
||||
/* Zero states. */
|
||||
if (!buffers[i].buffer) {
|
||||
if (rctx->family >= CHIP_CEDAR) {
|
||||
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
|
||||
} else {
|
||||
r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (r600_is_user_buffer(vbo->buffer)) {
|
||||
rctx->any_user_vbs = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
pipe_resource_reference(&rctx->real_vertex_buffer[i], vbo->buffer);
|
||||
|
||||
/* The stride of zero means we will be fetching only the first
|
||||
* vertex, so don't care about max_index. */
|
||||
if (!vbo->stride) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Update the maximum index. */
|
||||
{
|
||||
unsigned vbo_max_index =
|
||||
(vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
|
||||
max_index = MIN2(max_index, vbo_max_index);
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < rctx->nreal_vertex_buffers; i++) {
|
||||
pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL);
|
||||
pipe_resource_reference(&rctx->real_vertex_buffer[i], NULL);
|
||||
|
||||
/* Zero states. */
|
||||
for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) {
|
||||
if (rctx->family >= CHIP_CEDAR) {
|
||||
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
|
||||
} else {
|
||||
@@ -217,72 +188,24 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
|
||||
|
||||
rctx->nvertex_buffers = count;
|
||||
rctx->nreal_vertex_buffers = count;
|
||||
rctx->vb_max_index = max_index;
|
||||
u_vbuf_mgr_set_vertex_buffers(rctx->vbuf_mgr, count, buffers);
|
||||
}
|
||||
|
||||
|
||||
#define FORMAT_REPLACE(what, withwhat) \
|
||||
case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
|
||||
|
||||
void *r600_create_vertex_elements(struct pipe_context *ctx,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_element *elements)
|
||||
{
|
||||
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
|
||||
struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
|
||||
enum pipe_format *format;
|
||||
int i;
|
||||
|
||||
assert(count < 32);
|
||||
if (!v)
|
||||
return NULL;
|
||||
|
||||
v->count = count;
|
||||
memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
v->hw_format[i] = v->elements[i].src_format;
|
||||
format = &v->hw_format[i];
|
||||
|
||||
switch (*format) {
|
||||
FORMAT_REPLACE(R64_FLOAT, R32_FLOAT);
|
||||
FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT);
|
||||
FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT);
|
||||
FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT);
|
||||
|
||||
/* r600 doesn't seem to support 32_*SCALED, these formats
|
||||
* aren't in D3D10 either. */
|
||||
FORMAT_REPLACE(R32_UNORM, R32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT);
|
||||
|
||||
FORMAT_REPLACE(R32_USCALED, R32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
|
||||
|
||||
FORMAT_REPLACE(R32_SNORM, R32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT);
|
||||
|
||||
FORMAT_REPLACE(R32_SSCALED, R32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT);
|
||||
FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
|
||||
default:;
|
||||
}
|
||||
v->incompatible_layout =
|
||||
v->incompatible_layout ||
|
||||
v->elements[i].src_format != v->hw_format[i];
|
||||
|
||||
v->hw_format_size[i] = align(util_format_get_blocksize(v->hw_format[i]), 4);
|
||||
}
|
||||
v->vmgr_elements =
|
||||
u_vbuf_mgr_create_vertex_elements(rctx->vbuf_mgr, count,
|
||||
elements, v->elements);
|
||||
|
||||
if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
|
||||
FREE(v);
|
||||
@@ -433,7 +356,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer != &rbuffer->r.base.b)
|
||||
if (buffer != &rbuffer->r.b.b.b)
|
||||
pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL);
|
||||
}
|
||||
|
||||
@@ -449,7 +372,7 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
|
||||
rctx->nvs_resource = rctx->vertex_elements->count;
|
||||
} else {
|
||||
/* bind vertex buffer once */
|
||||
rctx->nvs_resource = rctx->nreal_vertex_buffers;
|
||||
rctx->nvs_resource = rctx->vbuf_mgr->nr_real_vertex_buffers;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < rctx->nvs_resource; i++) {
|
||||
@@ -461,13 +384,13 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
|
||||
/* one resource per vertex elements */
|
||||
unsigned vbuffer_index;
|
||||
vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index;
|
||||
vertex_buffer = &rctx->vertex_buffer[vbuffer_index];
|
||||
rbuffer = (struct r600_resource*)rctx->real_vertex_buffer[vbuffer_index];
|
||||
vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[vbuffer_index];
|
||||
rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[vbuffer_index];
|
||||
offset = rctx->vertex_elements->vbuffer_offset[i];
|
||||
} else {
|
||||
/* bind vertex buffer once */
|
||||
vertex_buffer = &rctx->vertex_buffer[i];
|
||||
rbuffer = (struct r600_resource*)rctx->real_vertex_buffer[i];
|
||||
vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[i];
|
||||
rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[i];
|
||||
offset = 0;
|
||||
}
|
||||
if (vertex_buffer == NULL || rbuffer == NULL)
|
||||
@@ -497,15 +420,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
|
||||
unsigned prim;
|
||||
|
||||
r600_flush_depth_textures(rctx);
|
||||
|
||||
if (rctx->vertex_elements->incompatible_layout) {
|
||||
r600_begin_vertex_translate(rctx, info->min_index, info->max_index);
|
||||
}
|
||||
|
||||
if (rctx->any_user_vbs) {
|
||||
r600_upload_user_buffers(rctx, info->min_index, info->max_index);
|
||||
}
|
||||
|
||||
u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info, NULL, NULL);
|
||||
r600_vertex_buffer_update(rctx);
|
||||
|
||||
draw.info = *info;
|
||||
@@ -523,7 +438,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
|
||||
draw.index_buffer_offset = draw.info.start * draw.index_size;
|
||||
draw.info.start = 0;
|
||||
|
||||
if (r600_is_user_buffer(draw.index_buffer)) {
|
||||
if (u_vbuf_resource(draw.index_buffer)->user_ptr) {
|
||||
r600_upload_index_buffer(rctx, &draw);
|
||||
}
|
||||
} else {
|
||||
@@ -607,8 +522,5 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
|
||||
|
||||
pipe_resource_reference(&draw.index_buffer, NULL);
|
||||
|
||||
/* delete previous translated vertex elements */
|
||||
if (rctx->tran.new_velems) {
|
||||
r600_end_vertex_translate(rctx);
|
||||
}
|
||||
u_vbuf_mgr_draw_end(rctx->vbuf_mgr);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
|
||||
{
|
||||
unsigned offset = rtex->offset[level];
|
||||
|
||||
switch (rtex->resource.base.b.target) {
|
||||
switch (rtex->resource.b.b.b.target) {
|
||||
case PIPE_TEXTURE_3D:
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
return offset + layer * rtex->layer_size[level];
|
||||
@@ -167,7 +167,7 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen,
|
||||
struct r600_resource_texture *rtex,
|
||||
unsigned level)
|
||||
{
|
||||
struct pipe_resource *ptex = &rtex->resource.base.b;
|
||||
struct pipe_resource *ptex = &rtex->resource.b.b.b;
|
||||
unsigned width, stride, tile_width;
|
||||
|
||||
if (rtex->pitch_override)
|
||||
@@ -188,7 +188,7 @@ static unsigned r600_texture_get_nblocksy(struct pipe_screen *screen,
|
||||
struct r600_resource_texture *rtex,
|
||||
unsigned level)
|
||||
{
|
||||
struct pipe_resource *ptex = &rtex->resource.base.b;
|
||||
struct pipe_resource *ptex = &rtex->resource.b.b.b;
|
||||
unsigned height, tile_height;
|
||||
|
||||
height = mip_minify(ptex->height0, level);
|
||||
@@ -211,7 +211,7 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen,
|
||||
struct r600_resource_texture *rtex,
|
||||
unsigned level, unsigned array_mode)
|
||||
{
|
||||
struct pipe_resource *ptex = &rtex->resource.base.b;
|
||||
struct pipe_resource *ptex = &rtex->resource.b.b.b;
|
||||
|
||||
switch (array_mode) {
|
||||
case V_0280A0_ARRAY_LINEAR_GENERAL:
|
||||
@@ -242,7 +242,7 @@ static void r600_setup_miptree(struct pipe_screen *screen,
|
||||
struct r600_resource_texture *rtex,
|
||||
unsigned array_mode)
|
||||
{
|
||||
struct pipe_resource *ptex = &rtex->resource.base.b;
|
||||
struct pipe_resource *ptex = &rtex->resource.b.b.b;
|
||||
struct radeon *radeon = (struct radeon *)screen->winsys;
|
||||
enum chip_class chipc = r600_get_family_class(radeon);
|
||||
unsigned pitch, size, layer_size, i, offset;
|
||||
@@ -372,10 +372,10 @@ r600_texture_create_object(struct pipe_screen *screen,
|
||||
return NULL;
|
||||
|
||||
resource = &rtex->resource;
|
||||
resource->base.b = *base;
|
||||
resource->base.vtbl = &r600_texture_vtbl;
|
||||
pipe_reference_init(&resource->base.b.reference, 1);
|
||||
resource->base.b.screen = screen;
|
||||
resource->b.b.b = *base;
|
||||
resource->b.b.vtbl = &r600_texture_vtbl;
|
||||
pipe_reference_init(&resource->b.b.b.reference, 1);
|
||||
resource->b.b.b.screen = screen;
|
||||
resource->bo = bo;
|
||||
rtex->pitch_override = pitch_in_bytes_override;
|
||||
/* only mark depth textures the HW can hit as depth textures */
|
||||
@@ -389,7 +389,7 @@ r600_texture_create_object(struct pipe_screen *screen,
|
||||
resource->size = rtex->size;
|
||||
|
||||
if (!resource->bo) {
|
||||
struct pipe_resource *ptex = &rtex->resource.base.b;
|
||||
struct pipe_resource *ptex = &rtex->resource.b.b.b;
|
||||
int base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
|
||||
|
||||
resource->bo = r600_bo(radeon, rtex->size, base_align, base->bind, base->usage);
|
||||
|
||||
@@ -23,176 +23,11 @@
|
||||
* Authors: Dave Airlie <airlied@redhat.com>
|
||||
*/
|
||||
|
||||
#include "translate/translate_cache.h"
|
||||
#include "translate/translate.h"
|
||||
#include <pipebuffer/pb_buffer.h>
|
||||
#include <util/u_index_modify.h>
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "r600_pipe.h"
|
||||
|
||||
void r600_begin_vertex_translate(struct r600_pipe_context *rctx,
|
||||
int min_index, int max_index)
|
||||
{
|
||||
struct pipe_context *pipe = &rctx->context;
|
||||
struct translate_key key = {0};
|
||||
struct translate_element *te;
|
||||
unsigned tr_elem_index[PIPE_MAX_ATTRIBS] = {0};
|
||||
struct translate *tr;
|
||||
struct r600_vertex_element *ve = rctx->vertex_elements;
|
||||
boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
|
||||
uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
|
||||
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
|
||||
struct pipe_resource *out_buffer = NULL;
|
||||
unsigned i, num_verts, out_offset;
|
||||
struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
|
||||
boolean flushed;
|
||||
|
||||
/* Initialize the translate key, i.e. the recipe how vertices should be
|
||||
* translated. */
|
||||
for (i = 0; i < ve->count; i++) {
|
||||
enum pipe_format output_format = ve->hw_format[i];
|
||||
unsigned output_format_size = ve->hw_format_size[i];
|
||||
|
||||
/* Check for support. */
|
||||
if (ve->elements[i].src_format == ve->hw_format[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Workaround for translate: output floats instead of halfs. */
|
||||
switch (output_format) {
|
||||
case PIPE_FORMAT_R16_FLOAT:
|
||||
output_format = PIPE_FORMAT_R32_FLOAT;
|
||||
output_format_size = 4;
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16_FLOAT:
|
||||
output_format = PIPE_FORMAT_R32G32_FLOAT;
|
||||
output_format_size = 8;
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16B16_FLOAT:
|
||||
output_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
output_format_size = 12;
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
output_format_size = 16;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
/* Add this vertex element. */
|
||||
te = &key.element[key.nr_elements];
|
||||
/*te->type;
|
||||
te->instance_divisor;*/
|
||||
te->input_buffer = ve->elements[i].vertex_buffer_index;
|
||||
te->input_format = ve->elements[i].src_format;
|
||||
te->input_offset = ve->elements[i].src_offset;
|
||||
te->output_format = output_format;
|
||||
te->output_offset = key.output_stride;
|
||||
|
||||
key.output_stride += output_format_size;
|
||||
vb_translated[ve->elements[i].vertex_buffer_index] = TRUE;
|
||||
tr_elem_index[i] = key.nr_elements;
|
||||
key.nr_elements++;
|
||||
}
|
||||
|
||||
/* Get a translate object. */
|
||||
tr = translate_cache_find(rctx->tran.translate_cache, &key);
|
||||
|
||||
/* Map buffers we want to translate. */
|
||||
for (i = 0; i < rctx->nvertex_buffers; i++) {
|
||||
if (vb_translated[i]) {
|
||||
struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[i];
|
||||
|
||||
vb_map[i] = pipe_buffer_map(pipe, vb->buffer,
|
||||
PIPE_TRANSFER_READ, &vb_transfer[i]);
|
||||
|
||||
tr->set_buffer(tr, i,
|
||||
vb_map[i] + vb->buffer_offset + vb->stride * min_index,
|
||||
vb->stride, ~0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create and map the output buffer. */
|
||||
num_verts = max_index + 1 - min_index;
|
||||
|
||||
u_upload_alloc(rctx->upload_vb,
|
||||
key.output_stride * min_index,
|
||||
key.output_stride * num_verts,
|
||||
&out_offset, &out_buffer, &flushed,
|
||||
(void**)&out_map);
|
||||
|
||||
out_offset -= key.output_stride * min_index;
|
||||
|
||||
/* Translate. */
|
||||
tr->run(tr, 0, num_verts, 0, out_map);
|
||||
|
||||
/* Unmap all buffers. */
|
||||
for (i = 0; i < rctx->nvertex_buffers; i++) {
|
||||
if (vb_translated[i]) {
|
||||
pipe_buffer_unmap(pipe, vb_transfer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the first free slot. */
|
||||
rctx->tran.vb_slot = ~0;
|
||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
||||
if (!rctx->vertex_buffer[i].buffer) {
|
||||
rctx->tran.vb_slot = i;
|
||||
|
||||
if (i >= rctx->nvertex_buffers) {
|
||||
rctx->nreal_vertex_buffers = i+1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rctx->tran.vb_slot != ~0) {
|
||||
/* Setup the new vertex buffer. */
|
||||
pipe_resource_reference(&rctx->real_vertex_buffer[rctx->tran.vb_slot], out_buffer);
|
||||
rctx->vertex_buffer[rctx->tran.vb_slot].buffer_offset = out_offset;
|
||||
rctx->vertex_buffer[rctx->tran.vb_slot].stride = key.output_stride;
|
||||
|
||||
/* Setup new vertex elements. */
|
||||
for (i = 0; i < ve->count; i++) {
|
||||
if (vb_translated[ve->elements[i].vertex_buffer_index]) {
|
||||
te = &key.element[tr_elem_index[i]];
|
||||
new_velems[i].instance_divisor = ve->elements[i].instance_divisor;
|
||||
new_velems[i].src_format = te->output_format;
|
||||
new_velems[i].src_offset = te->output_offset;
|
||||
new_velems[i].vertex_buffer_index = rctx->tran.vb_slot;
|
||||
} else {
|
||||
memcpy(&new_velems[i], &ve->elements[i],
|
||||
sizeof(struct pipe_vertex_element));
|
||||
}
|
||||
}
|
||||
|
||||
rctx->tran.saved_velems = rctx->vertex_elements;
|
||||
rctx->tran.new_velems =
|
||||
pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
|
||||
pipe->bind_vertex_elements_state(pipe, rctx->tran.new_velems);
|
||||
}
|
||||
|
||||
pipe_resource_reference(&out_buffer, NULL);
|
||||
}
|
||||
|
||||
void r600_end_vertex_translate(struct r600_pipe_context *rctx)
|
||||
{
|
||||
struct pipe_context *pipe = &rctx->context;
|
||||
|
||||
if (rctx->tran.new_velems == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Restore vertex elements. */
|
||||
pipe->bind_vertex_elements_state(pipe, rctx->tran.saved_velems);
|
||||
rctx->tran.saved_velems = NULL;
|
||||
pipe->delete_vertex_elements_state(pipe, rctx->tran.new_velems);
|
||||
rctx->tran.new_velems = NULL;
|
||||
|
||||
/* Delete the now-unused VBO. */
|
||||
pipe_resource_reference(&rctx->real_vertex_buffer[rctx->tran.vb_slot], NULL);
|
||||
rctx->nreal_vertex_buffers = rctx->nvertex_buffers;
|
||||
}
|
||||
|
||||
void r600_translate_index_buffer(struct r600_pipe_context *r600,
|
||||
struct pipe_resource **index_buffer,
|
||||
@@ -206,7 +41,7 @@ void r600_translate_index_buffer(struct r600_pipe_context *r600,
|
||||
|
||||
switch (*index_size) {
|
||||
case 1:
|
||||
u_upload_alloc(r600->upload_vb, 0, count * 2,
|
||||
u_upload_alloc(r600->upload_ib, 0, count * 2,
|
||||
&out_offset, &out_buffer, &flushed, &ptr);
|
||||
|
||||
util_shorten_ubyte_elts_to_userptr(
|
||||
|
||||
Reference in New Issue
Block a user