diff options
author | Marek Olšák <[email protected]> | 2012-08-26 22:38:35 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-08-30 19:43:56 +0200 |
commit | 78354011f99c4103345f8f32e10b0b4b884ebdaf (patch) | |
tree | 0686495ce07db652b88bed43a4f421e4077d5545 /src/gallium/drivers/r600/r600_texture.c | |
parent | 863e2c85b9c59d717ad786c709638d948ff0f38e (diff) |
r600g: implement color resolve for r600
The blend state is different and the resolve single-sample buffer must have
FMASK and CMASK enabled. I decided to have one CMASK and one FMASK
per context instead of per resource.
There are new FMASK and CMASK allocation helpers and a new buffer_create
helper for that.
Diffstat (limited to 'src/gallium/drivers/r600/r600_texture.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 0b2fdda53f7..6de3d6a8645 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -252,13 +252,15 @@ static const struct u_resource_vtbl r600_texture_vtbl = NULL /* transfer_inline_write */ }; -static void r600_texture_allocate_fmask(struct r600_screen *rscreen, - struct r600_texture *rtex) +/* The number of samples can be specified independently of the texture. */ +void r600_texture_get_fmask_info(struct r600_screen *rscreen, + struct r600_texture *rtex, + unsigned nr_samples, + struct r600_fmask_info *out) { /* FMASK is allocated pretty much like an ordinary texture. * Here we use bpe in the units of bits, not bytes. */ struct radeon_surface fmask = rtex->surface; - unsigned nr_samples = rtex->resource.b.b.nr_samples; switch (nr_samples) { case 2: @@ -297,10 +299,23 @@ static void r600_texture_allocate_fmask(struct r600_screen *rscreen, } assert(fmask.level[0].mode == RADEON_SURF_MODE_2D); + out->bank_height = fmask.bankh; + out->alignment = MAX2(256, fmask.bo_alignment); + out->size = (fmask.bo_size + 7) / 8; +} + +static void r600_texture_allocate_fmask(struct r600_screen *rscreen, + struct r600_texture *rtex) +{ + struct r600_fmask_info fmask; + + r600_texture_get_fmask_info(rscreen, rtex, + rtex->resource.b.b.nr_samples, &fmask); + /* Reserve space for FMASK while converting bits back to bytes. */ - rtex->fmask_bank_height = fmask.bankh; - rtex->fmask_offset = align(rtex->size, MAX2(256, fmask.bo_alignment)); - rtex->fmask_size = (fmask.bo_size + 7) / 8; + rtex->fmask_bank_height = fmask.bank_height; + rtex->fmask_offset = align(rtex->size, fmask.alignment); + rtex->fmask_size = fmask.size; rtex->size = rtex->fmask_offset + rtex->fmask_size; #if 0 printf("FMASK width=%u, height=%i, bits=%u, size=%u\n", @@ -308,8 +323,9 @@ static void r600_texture_allocate_fmask(struct r600_screen *rscreen, #endif } -static void r600_texture_allocate_cmask(struct r600_screen *rscreen, - struct r600_texture *rtex) +void r600_texture_get_cmask_info(struct r600_screen *rscreen, + struct r600_texture *rtex, + struct r600_cmask_info *out) { unsigned cmask_tile_width = 8; unsigned cmask_tile_height = 8; @@ -331,14 +347,25 @@ static void r600_texture_allocate_cmask(struct r600_screen *rscreen, unsigned base_align = num_pipes * pipe_interleave_bytes; unsigned slice_bytes = ((pitch_elements * height * element_bits + 7) / 8) / cmask_tile_elements; - unsigned size = rtex->surface.array_size * align(slice_bytes, base_align); assert(macro_tile_width % 128 == 0); assert(macro_tile_height % 128 == 0); - rtex->cmask_slice_tile_max = ((pitch_elements * height) / (128*128)) - 1; - rtex->cmask_offset = align(rtex->size, MAX2(256, base_align)); - rtex->cmask_size = size; + out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1; + out->alignment = MAX2(256, base_align); + out->size = rtex->surface.array_size * align(slice_bytes, base_align); +} + +static void r600_texture_allocate_cmask(struct r600_screen *rscreen, + struct r600_texture *rtex) +{ + struct r600_cmask_info cmask; + + r600_texture_get_cmask_info(rscreen, rtex, &cmask); + + rtex->cmask_slice_tile_max = cmask.slice_tile_max; + rtex->cmask_offset = align(rtex->size, cmask.alignment); + rtex->cmask_size = cmask.size; rtex->size = rtex->cmask_offset + rtex->cmask_size; #if 0 printf("CMASK: macro tile width = %u, macro tile height = %u, " @@ -479,6 +506,9 @@ static struct pipe_surface *r600_create_surface(struct pipe_context *pipe, static void r600_surface_destroy(struct pipe_context *pipe, struct pipe_surface *surface) { + struct r600_surface *surf = (struct r600_surface*)surface; + pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL); + pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL); pipe_resource_reference(&surface->texture, NULL); FREE(surface); } |