mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
r600g: initialize CMASK and HTILE with the GPU using streamout
This fixes a crash when a resource cannot be mapped to the CPU's address space because it's too big. This puts a global pipe_context in r600_screen, which is guarded by a mutex, so that we can use pipe_context when there isn't one around. Hopefully our multi-context support is solid. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> NOTE: This is a candidate for the 9.1 branch.
This commit is contained in:
parent
1ba46bbb4c
commit
b692076420
4 changed files with 80 additions and 7 deletions
|
|
@ -522,6 +522,37 @@ void r600_copy_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsig
|
|||
}
|
||||
}
|
||||
|
||||
static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst,
|
||||
unsigned offset, unsigned size, unsigned char value)
|
||||
{
|
||||
struct r600_context *rctx = (struct r600_context*)ctx;
|
||||
|
||||
if (rctx->screen->has_streamout && offset % 4 == 0 && size % 4 == 0) {
|
||||
union pipe_color_union clear_value;
|
||||
uint32_t v = value;
|
||||
|
||||
clear_value.ui[0] = v | (v << 8) | (v << 16) | (v << 24);
|
||||
|
||||
r600_blitter_begin(ctx, R600_DISABLE_RENDER_COND);
|
||||
util_blitter_clear_buffer(rctx->blitter, dst, offset, size,
|
||||
1, &clear_value);
|
||||
r600_blitter_end(ctx);
|
||||
} else {
|
||||
char *map = r600_buffer_mmap_sync_with_rings(rctx, r600_resource(dst),
|
||||
PIPE_TRANSFER_WRITE);
|
||||
memset(map + offset, value, size);
|
||||
}
|
||||
}
|
||||
|
||||
void r600_screen_clear_buffer(struct r600_screen *rscreen, struct pipe_resource *dst,
|
||||
unsigned offset, unsigned size, unsigned char value)
|
||||
{
|
||||
pipe_mutex_lock(rscreen->aux_context_lock);
|
||||
r600_clear_buffer(rscreen->aux_context, dst, offset, size, value);
|
||||
rscreen->aux_context->flush(rscreen->aux_context, NULL, 0);
|
||||
pipe_mutex_unlock(rscreen->aux_context_lock);
|
||||
}
|
||||
|
||||
static bool util_format_is_subsampled_2x1_32bpp(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
|
|
|
|||
|
|
@ -940,6 +940,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
|
|||
if (rscreen == NULL)
|
||||
return;
|
||||
|
||||
pipe_mutex_destroy(rscreen->aux_context_lock);
|
||||
rscreen->aux_context->destroy(rscreen->aux_context);
|
||||
|
||||
if (rscreen->global_pool) {
|
||||
compute_memory_pool_delete(rscreen->global_pool);
|
||||
}
|
||||
|
|
@ -1319,5 +1322,41 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Create the auxiliary context. */
|
||||
pipe_mutex_init(rscreen->aux_context_lock);
|
||||
rscreen->aux_context = rscreen->screen.context_create(&rscreen->screen, NULL);
|
||||
|
||||
#if 0 /* This is for testing whether aux_context and buffer clearing work correctly. */
|
||||
struct pipe_resource templ = {};
|
||||
|
||||
templ.width0 = 4;
|
||||
templ.height0 = 2048;
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
templ.target = PIPE_TEXTURE_2D;
|
||||
templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
|
||||
templ.usage = PIPE_USAGE_STATIC;
|
||||
|
||||
struct r600_resource *res = r600_resource(rscreen->screen.resource_create(&rscreen->screen, &templ));
|
||||
unsigned char *map = ws->buffer_map(res->cs_buf, NULL, PIPE_TRANSFER_WRITE);
|
||||
|
||||
memset(map, 0, 256);
|
||||
|
||||
r600_screen_clear_buffer(rscreen, &res->b.b, 4, 4, 0xCC);
|
||||
r600_screen_clear_buffer(rscreen, &res->b.b, 8, 4, 0xDD);
|
||||
r600_screen_clear_buffer(rscreen, &res->b.b, 12, 4, 0xEE);
|
||||
r600_screen_clear_buffer(rscreen, &res->b.b, 20, 4, 0xFF);
|
||||
r600_screen_clear_buffer(rscreen, &res->b.b, 32, 20, 0x87);
|
||||
|
||||
ws->buffer_wait(res->buf, RADEON_USAGE_WRITE);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
printf("%02X", map[i]);
|
||||
if (i % 16 == 15)
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return &rscreen->screen;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,6 +290,11 @@ struct r600_screen {
|
|||
unsigned cs_count;
|
||||
#endif
|
||||
r600g_dma_blit_t dma_blit;
|
||||
|
||||
/* Auxiliary context. Mainly used to initialize resources.
|
||||
* It must be locked prior to using and flushed before unlocking. */
|
||||
struct pipe_context *aux_context;
|
||||
pipe_mutex aux_context_lock;
|
||||
};
|
||||
|
||||
struct r600_pipe_sampler_view {
|
||||
|
|
@ -721,6 +726,8 @@ void evergreen_update_db_shader_control(struct r600_context * rctx);
|
|||
/* r600_blit.c */
|
||||
void r600_copy_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dstx,
|
||||
struct pipe_resource *src, const struct pipe_box *src_box);
|
||||
void r600_screen_clear_buffer(struct r600_screen *rscreen, struct pipe_resource *dst,
|
||||
unsigned offset, unsigned size, unsigned char value);
|
||||
void r600_init_blit_functions(struct r600_context *rctx);
|
||||
void r600_blit_decompress_depth(struct pipe_context *ctx,
|
||||
struct r600_texture *texture,
|
||||
|
|
|
|||
|
|
@ -480,10 +480,7 @@ r600_texture_create_object(struct pipe_screen *screen,
|
|||
*/
|
||||
R600_ERR("r600: failed to create bo for htile buffers\n");
|
||||
} else {
|
||||
void *ptr;
|
||||
ptr = rscreen->ws->buffer_map(rtex->htile->cs_buf, NULL, PIPE_TRANSFER_WRITE);
|
||||
memset(ptr, 0x0, htile_size);
|
||||
rscreen->ws->buffer_unmap(rtex->htile->cs_buf);
|
||||
r600_screen_clear_buffer(rscreen, &rtex->htile->b.b, 0, htile_size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -505,9 +502,8 @@ r600_texture_create_object(struct pipe_screen *screen,
|
|||
|
||||
if (rtex->cmask_size) {
|
||||
/* Initialize the cmask to 0xCC (= compressed state). */
|
||||
char *ptr = rscreen->ws->buffer_map(resource->cs_buf, NULL, PIPE_TRANSFER_WRITE);
|
||||
memset(ptr + rtex->cmask_offset, 0xCC, rtex->cmask_size);
|
||||
rscreen->ws->buffer_unmap(resource->cs_buf);
|
||||
r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
|
||||
rtex->cmask_offset, rtex->cmask_size, 0xCC);
|
||||
}
|
||||
|
||||
if (rscreen->debug_flags & DBG_VM) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue