r600g: implement invalidation of texture buffer objects
This fixes piglit spec/ARB_texture_buffer_object/data-sync. Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
da9c3ed304
commit
79f28cdb98
|
@ -596,7 +596,8 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
|
|||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
|
||||
texture_buffer_sampler_view(struct r600_context *rctx,
|
||||
struct r600_pipe_sampler_view *view,
|
||||
unsigned width0, unsigned height0)
|
||||
|
||||
{
|
||||
|
@ -644,6 +645,9 @@ texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
|
|||
view->tex_resource_words[4] = 0;
|
||||
view->tex_resource_words[5] = view->tex_resource_words[6] = 0;
|
||||
view->tex_resource_words[7] = S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_BUFFER);
|
||||
|
||||
if (tmp->resource.gpu_address)
|
||||
LIST_ADDTAIL(&view->list, &rctx->b.texture_buffers);
|
||||
return &view->base;
|
||||
}
|
||||
|
||||
|
@ -654,6 +658,7 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
|
|||
unsigned width0, unsigned height0,
|
||||
unsigned force_level)
|
||||
{
|
||||
struct r600_context *rctx = (struct r600_context*)ctx;
|
||||
struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
|
||||
struct r600_pipe_sampler_view *view = CALLOC_STRUCT(r600_pipe_sampler_view);
|
||||
struct r600_texture *tmp = (struct r600_texture*)texture;
|
||||
|
@ -679,7 +684,7 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
|
|||
view->base.context = ctx;
|
||||
|
||||
if (texture->target == PIPE_BUFFER)
|
||||
return texture_buffer_sampler_view(view, width0, height0);
|
||||
return texture_buffer_sampler_view(rctx, view, width0, height0);
|
||||
|
||||
swizzle[0] = state->swizzle_r;
|
||||
swizzle[1] = state->swizzle_g;
|
||||
|
|
|
@ -222,6 +222,7 @@ struct r600_screen {
|
|||
|
||||
struct r600_pipe_sampler_view {
|
||||
struct pipe_sampler_view base;
|
||||
struct list_head list;
|
||||
struct r600_resource *tex_resource;
|
||||
uint32_t tex_resource_words[8];
|
||||
bool skip_mip_address_reloc;
|
||||
|
|
|
@ -354,10 +354,14 @@ static void r600_delete_rs_state(struct pipe_context *ctx, void *state)
|
|||
static void r600_sampler_view_destroy(struct pipe_context *ctx,
|
||||
struct pipe_sampler_view *state)
|
||||
{
|
||||
struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state;
|
||||
struct r600_pipe_sampler_view *view = (struct r600_pipe_sampler_view *)state;
|
||||
|
||||
if (view->tex_resource->gpu_address &&
|
||||
view->tex_resource->b.b.target == PIPE_BUFFER)
|
||||
LIST_DELINIT(&view->list);
|
||||
|
||||
pipe_resource_reference(&state->texture, NULL);
|
||||
FREE(resource);
|
||||
FREE(view);
|
||||
}
|
||||
|
||||
void r600_sampler_states_dirty(struct r600_context *rctx,
|
||||
|
@ -2314,6 +2318,7 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
|
|||
struct r600_context *rctx = (struct r600_context*)ctx;
|
||||
struct r600_resource *rbuffer = r600_resource(buf);
|
||||
unsigned i, shader, mask, alignment = rbuffer->buf->alignment;
|
||||
struct r600_pipe_sampler_view *view;
|
||||
|
||||
/* Reallocate the buffer in the same pipe_resource. */
|
||||
r600_init_resource(&rctx->screen->b, rbuffer, rbuffer->b.b.width0,
|
||||
|
@ -2358,7 +2363,35 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
|
|||
}
|
||||
}
|
||||
|
||||
/* XXX TODO: texture buffer objects */
|
||||
/* Texture buffer objects - update the virtual addresses in descriptors. */
|
||||
LIST_FOR_EACH_ENTRY(view, &rctx->b.texture_buffers, list) {
|
||||
if (view->base.texture == &rbuffer->b.b) {
|
||||
unsigned stride = util_format_get_blocksize(view->base.format);
|
||||
uint64_t offset = (uint64_t)view->base.u.buf.first_element * stride;
|
||||
uint64_t va = rbuffer->gpu_address + offset;
|
||||
|
||||
view->tex_resource_words[0] = va;
|
||||
view->tex_resource_words[2] &= C_038008_BASE_ADDRESS_HI;
|
||||
view->tex_resource_words[2] |= S_038008_BASE_ADDRESS_HI(va >> 32);
|
||||
}
|
||||
}
|
||||
/* Texture buffer objects - make bindings dirty if needed. */
|
||||
for (shader = 0; shader < PIPE_SHADER_TYPES; shader++) {
|
||||
struct r600_samplerview_state *state = &rctx->samplers[shader].views;
|
||||
bool found = false;
|
||||
uint32_t mask = state->enabled_mask;
|
||||
|
||||
while (mask) {
|
||||
unsigned i = u_bit_scan(&mask);
|
||||
if (state->views[i]->base.texture == &rbuffer->b.b) {
|
||||
found = true;
|
||||
state->dirty_mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
r600_sampler_views_dirty(rctx, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void r600_set_occlusion_query_state(struct pipe_context *ctx, bool enable)
|
||||
|
|
|
@ -157,6 +157,8 @@ bool r600_common_context_init(struct r600_common_context *rctx,
|
|||
rctx->b.memory_barrier = r600_memory_barrier;
|
||||
rctx->b.flush = r600_flush_from_st;
|
||||
|
||||
LIST_INITHEAD(&rctx->texture_buffers);
|
||||
|
||||
r600_init_context_texture_functions(rctx);
|
||||
r600_streamout_init(rctx);
|
||||
r600_query_init(rctx);
|
||||
|
|
|
@ -375,6 +375,11 @@ struct r600_common_context {
|
|||
float sample_locations_8x[8][2];
|
||||
float sample_locations_16x[16][2];
|
||||
|
||||
/* The list of all texture buffer objects in this context.
|
||||
* This list is walked when a buffer is invalidated/reallocated and
|
||||
* the GPU addresses are updated. */
|
||||
struct list_head texture_buffers;
|
||||
|
||||
/* Copy one resource to another using async DMA. */
|
||||
void (*dma_copy)(struct pipe_context *ctx,
|
||||
struct pipe_resource *dst,
|
||||
|
|
Loading…
Reference in New Issue