diff options
-rw-r--r-- | src/gallium/drivers/radeon/r600_buffer_common.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_winsys.h | 5 | ||||
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_surface.c | 47 |
5 files changed, 92 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c index f341ecb41a5..0dc6c918331 100644 --- a/src/gallium/drivers/radeon/r600_buffer_common.c +++ b/src/gallium/drivers/radeon/r600_buffer_common.c @@ -443,6 +443,27 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, return &rbuffer->b.b; } +struct pipe_resource *r600_aligned_buffer_create(struct pipe_screen *screen, + unsigned bind, + unsigned usage, + unsigned size, + unsigned alignment) +{ + struct pipe_resource buffer; + + memset(&buffer, 0, sizeof buffer); + buffer.target = PIPE_BUFFER; + buffer.format = PIPE_FORMAT_R8_UNORM; + buffer.bind = bind; + buffer.usage = usage; + buffer.flags = 0; + buffer.width0 = size; + buffer.height0 = 1; + buffer.depth0 = 1; + buffer.array_size = 1; + return r600_buffer_create(screen, &buffer, alignment); +} + struct pipe_resource * r600_buffer_from_user_memory(struct pipe_screen *screen, const struct pipe_resource *templ, diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index b58b500bd76..1eec596b258 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -214,6 +214,7 @@ struct r600_texture { struct r600_fmask_info fmask; struct r600_cmask_info cmask; struct r600_resource *cmask_buffer; + struct r600_resource *dcc_buffer; unsigned cb_color_info; /* fast clear enable bit */ unsigned color_clear_value[2]; @@ -489,6 +490,11 @@ bool r600_init_resource(struct r600_common_screen *rscreen, struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ, unsigned alignment); +struct pipe_resource * r600_aligned_buffer_create(struct pipe_screen *screen, + unsigned bind, + unsigned usage, + unsigned size, + unsigned alignment); struct pipe_resource * r600_buffer_from_user_memory(struct pipe_screen *screen, const struct pipe_resource *templ, diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index fc69f48bb70..fffb9ef4cbe 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -268,6 +268,7 @@ static void r600_texture_destroy(struct pipe_screen *screen, if (rtex->cmask_buffer != &rtex->resource) { pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL); } + pipe_resource_reference((struct pipe_resource**)&rtex->dcc_buffer, NULL); pb_reference(&resource->buf, NULL); FREE(rtex); } @@ -482,6 +483,20 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1); } +static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen, + struct r600_texture *rtex) +{ + rtex->dcc_buffer = (struct r600_resource *) + r600_aligned_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM, + PIPE_USAGE_DEFAULT, rtex->surface.dcc_size, rtex->surface.dcc_alignment); + if (rtex->dcc_buffer == NULL) { + return; + } + + r600_screen_clear_buffer(rscreen, &rtex->dcc_buffer->b.b, 0, rtex->surface.dcc_size, + 0xFFFFFFFF, true); +} + static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen, struct r600_texture *rtex) { @@ -621,6 +636,9 @@ r600_texture_create_object(struct pipe_screen *screen, return NULL; } } + if (rtex->surface.dcc_enabled) { + vi_texture_alloc_dcc_separate(rscreen, rtex); + } } /* Now create the backing buffer. */ diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index 5f13c1ebc26..0178643549e 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -332,6 +332,7 @@ struct radeon_surf_level { uint32_t nblk_z; uint32_t pitch_bytes; uint32_t mode; + uint64_t dcc_offset; }; struct radeon_surf { @@ -367,6 +368,10 @@ struct radeon_surf { uint32_t stencil_tiling_index[RADEON_SURF_MAX_LEVEL]; uint32_t pipe_config; uint32_t num_banks; + + uint64_t dcc_size; + uint64_t dcc_alignment; + bool dcc_enabled; }; struct radeon_bo_list_item { diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c index 358df381011..b442174b7b8 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c @@ -175,7 +175,9 @@ static int compute_level(struct amdgpu_winsys *ws, struct radeon_surf *surf, bool is_stencil, unsigned level, unsigned type, bool compressed, ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn, - ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut) + ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut, + ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn, + ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut) { struct radeon_surf_level *surf_level; ADDR_E_RETURNCODE ret; @@ -248,6 +250,30 @@ static int compute_level(struct amdgpu_winsys *ws, surf->tiling_index[level] = AddrSurfInfoOut->tileIndex; surf->bo_size = surf_level->offset + AddrSurfInfoOut->surfSize; + + if (surf->dcc_enabled) { + AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize; + AddrDccIn->tileMode = AddrSurfInfoOut->tileMode; + AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo; + AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex; + AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex; + + ret = AddrComputeDccInfo(ws->addrlib, + AddrDccIn, + AddrDccOut); + + if (ret == ADDR_OK) { + surf_level->dcc_offset = surf->dcc_size; + surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize; + surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign); + } else { + surf->dcc_enabled = false; + surf_level->dcc_offset = 0; + } + } else { + surf_level->dcc_offset = 0; + } + return 0; } @@ -259,6 +285,8 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, bool compressed; ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0}; + ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0}; + ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0}; ADDR_TILEINFO AddrTileInfoIn = {0}; ADDR_TILEINFO AddrTileInfoOut = {0}; int r; @@ -269,6 +297,8 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); + AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT); + AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT); AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut; type = RADEON_SURF_GET(surf->flags, TYPE); @@ -318,12 +348,16 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, } } else { - AddrSurfInfoIn.bpp = surf->bpe * 8; + AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8; } - AddrSurfInfoIn.numSamples = surf->nsamples; + AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = surf->nsamples; AddrSurfInfoIn.tileIndex = -1; + surf->dcc_enabled = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) && + !(surf->flags & RADEON_SURF_SCANOUT) && + !compressed && AddrDccIn.numSamples <= 1; + /* Set the micro tile type. */ if (surf->flags & RADEON_SURF_SCANOUT) AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE; @@ -339,6 +373,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0; AddrSurfInfoIn.flags.pow2Pad = surf->last_level > 0; AddrSurfInfoIn.flags.degrade4Space = 1; + AddrSurfInfoIn.flags.dccCompatible = surf->dcc_enabled; /* This disables incorrect calculations (hacks) in addrlib. */ AddrSurfInfoIn.flags.noStencil = 1; @@ -375,11 +410,13 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, } surf->bo_size = 0; + surf->dcc_size = 0; + surf->dcc_alignment = 1; /* Calculate texture layout information. */ for (level = 0; level <= surf->last_level; level++) { r = compute_level(ws, surf, false, level, type, compressed, - &AddrSurfInfoIn, &AddrSurfInfoOut); + &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut); if (r) return r; @@ -406,7 +443,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, for (level = 0; level <= surf->last_level; level++) { r = compute_level(ws, surf, true, level, type, compressed, - &AddrSurfInfoIn, &AddrSurfInfoOut); + &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut); if (r) return r; |