diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-05-10 20:36:03 +0200 |
---|---|---|
committer | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-05-18 11:48:51 +0200 |
commit | 8aabed64c37c70b0914e5628f0168264ed7e21c7 (patch) | |
tree | e8d495e77696a700dec93e15d8014ce6555270a4 | |
parent | db77cd879b7996fcf423090b776f6f96708818c3 (diff) |
ac/radeonsi: move the bulk of gfx9_surface_init to ac_surface
We can now merge the two *_surface_init functions.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
-rw-r--r-- | src/amd/common/ac_surface.c | 380 | ||||
-rw-r--r-- | src/amd/common/ac_surface.h | 4 | ||||
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_surface.c | 425 |
3 files changed, 394 insertions, 415 deletions
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index cf741049db..8b6d3b10a2 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -630,3 +630,383 @@ int gfx6_compute_surface(ADDR_HANDLE addrlib, surf->is_linear = surf->u.legacy.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED; return 0; } + +/* This is only called when expecting a tiled layout. */ +static int +gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib, + ADDR2_COMPUTE_SURFACE_INFO_INPUT *in, + bool is_fmask, AddrSwizzleMode *swizzle_mode) +{ + ADDR_E_RETURNCODE ret; + ADDR2_GET_PREFERRED_SURF_SETTING_INPUT sin = {0}; + ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT sout = {0}; + + sin.size = sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT); + sout.size = sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT); + + sin.flags = in->flags; + sin.resourceType = in->resourceType; + sin.format = in->format; + sin.resourceLoction = ADDR_RSRC_LOC_INVIS; + /* TODO: We could allow some of these: */ + sin.forbiddenBlock.micro = 1; /* don't allow the 256B swizzle modes */ + sin.forbiddenBlock.var = 1; /* don't allow the variable-sized swizzle modes */ + sin.forbiddenBlock.linear = 1; /* don't allow linear swizzle modes */ + sin.bpp = in->bpp; + sin.width = in->width; + sin.height = in->height; + sin.numSlices = in->numSlices; + sin.numMipLevels = in->numMipLevels; + sin.numSamples = in->numSamples; + sin.numFrags = in->numFrags; + + if (is_fmask) { + sin.flags.color = 0; + sin.flags.fmask = 1; + } + + ret = Addr2GetPreferredSurfaceSetting(addrlib, &sin, &sout); + if (ret != ADDR_OK) + return ret; + + *swizzle_mode = sout.swizzleMode; + return 0; +} + +static int gfx9_compute_miptree(ADDR_HANDLE addrlib, + struct radeon_surf *surf, bool compressed, + ADDR2_COMPUTE_SURFACE_INFO_INPUT *in) +{ + ADDR2_MIP_INFO mip_info[RADEON_SURF_MAX_LEVELS] = {}; + ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0}; + ADDR_E_RETURNCODE ret; + + out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT); + out.pMipInfo = mip_info; + + ret = Addr2ComputeSurfaceInfo(addrlib, in, &out); + if (ret != ADDR_OK) + return ret; + + if (in->flags.stencil) { + surf->u.gfx9.stencil.swizzle_mode = in->swizzleMode; + surf->u.gfx9.stencil.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 : + out.mipChainPitch - 1; + surf->surf_alignment = MAX2(surf->surf_alignment, out.baseAlign); + surf->u.gfx9.stencil_offset = align(surf->surf_size, out.baseAlign); + surf->surf_size = surf->u.gfx9.stencil_offset + out.surfSize; + return 0; + } + + surf->u.gfx9.surf.swizzle_mode = in->swizzleMode; + surf->u.gfx9.surf.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 : + out.mipChainPitch - 1; + + /* CMASK fast clear uses these even if FMASK isn't allocated. + * FMASK only supports the Z swizzle modes, whose numbers are multiples of 4. + */ + surf->u.gfx9.fmask.swizzle_mode = surf->u.gfx9.surf.swizzle_mode & ~0x3; + surf->u.gfx9.fmask.epitch = surf->u.gfx9.surf.epitch; + + surf->u.gfx9.surf_slice_size = out.sliceSize; + surf->u.gfx9.surf_pitch = out.pitch; + surf->u.gfx9.surf_height = out.height; + surf->surf_size = out.surfSize; + surf->surf_alignment = out.baseAlign; + + if (in->swizzleMode == ADDR_SW_LINEAR) { + for (unsigned i = 0; i < in->numMipLevels; i++) + surf->u.gfx9.offset[i] = mip_info[i].offset; + } + + if (in->flags.depth) { + assert(in->swizzleMode != ADDR_SW_LINEAR); + + /* HTILE */ + ADDR2_COMPUTE_HTILE_INFO_INPUT hin = {0}; + ADDR2_COMPUTE_HTILE_INFO_OUTPUT hout = {0}; + + hin.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); + hout.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); + + hin.hTileFlags.pipeAligned = 1; + hin.hTileFlags.rbAligned = 1; + hin.depthFlags = in->flags; + hin.swizzleMode = in->swizzleMode; + hin.unalignedWidth = in->width; + hin.unalignedHeight = in->height; + hin.numSlices = in->numSlices; + hin.numMipLevels = in->numMipLevels; + + ret = Addr2ComputeHtileInfo(addrlib, &hin, &hout); + if (ret != ADDR_OK) + return ret; + + surf->u.gfx9.htile.rb_aligned = hin.hTileFlags.rbAligned; + surf->u.gfx9.htile.pipe_aligned = hin.hTileFlags.pipeAligned; + surf->htile_size = hout.htileBytes; + surf->htile_alignment = hout.baseAlign; + } else { + /* DCC */ + if (!(surf->flags & RADEON_SURF_DISABLE_DCC) && + !(surf->flags & RADEON_SURF_SCANOUT) && + !compressed && + in->swizzleMode != ADDR_SW_LINEAR && + /* TODO: We could support DCC with MSAA. */ + in->numSamples == 1) { + ADDR2_COMPUTE_DCCINFO_INPUT din = {0}; + ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0}; + + din.size = sizeof(ADDR2_COMPUTE_DCCINFO_INPUT); + dout.size = sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT); + + din.dccKeyFlags.pipeAligned = 1; + din.dccKeyFlags.rbAligned = 1; + din.colorFlags = in->flags; + din.resourceType = in->resourceType; + din.swizzleMode = in->swizzleMode; + din.bpp = in->bpp; + din.unalignedWidth = in->width; + din.unalignedHeight = in->height; + din.numSlices = in->numSlices; + din.numFrags = in->numFrags; + din.numMipLevels = in->numMipLevels; + din.dataSurfaceSize = out.surfSize; + + ret = Addr2ComputeDccInfo(addrlib, &din, &dout); + if (ret != ADDR_OK) + return ret; + + surf->u.gfx9.dcc.rb_aligned = din.dccKeyFlags.rbAligned; + surf->u.gfx9.dcc.pipe_aligned = din.dccKeyFlags.pipeAligned; + surf->u.gfx9.dcc_pitch_max = dout.pitch - 1; + surf->dcc_size = dout.dccRamSize; + surf->dcc_alignment = dout.dccRamBaseAlign; + } + + /* FMASK */ + if (in->numSamples > 1) { + ADDR2_COMPUTE_FMASK_INFO_INPUT fin = {0}; + ADDR2_COMPUTE_FMASK_INFO_OUTPUT fout = {0}; + + fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT); + fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT); + + ret = gfx9_get_preferred_swizzle_mode(addrlib, in, true, &fin.swizzleMode); + if (ret != ADDR_OK) + return ret; + + fin.unalignedWidth = in->width; + fin.unalignedHeight = in->height; + fin.numSlices = in->numSlices; + fin.numSamples = in->numSamples; + fin.numFrags = in->numFrags; + + ret = Addr2ComputeFmaskInfo(addrlib, &fin, &fout); + if (ret != ADDR_OK) + return ret; + + surf->u.gfx9.fmask.swizzle_mode = fin.swizzleMode; + surf->u.gfx9.fmask.epitch = fout.pitch - 1; + surf->u.gfx9.fmask_size = fout.fmaskBytes; + surf->u.gfx9.fmask_alignment = fout.baseAlign; + } + + /* CMASK */ + if (in->swizzleMode != ADDR_SW_LINEAR) { + ADDR2_COMPUTE_CMASK_INFO_INPUT cin = {0}; + ADDR2_COMPUTE_CMASK_INFO_OUTPUT cout = {0}; + + cin.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT); + cout.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT); + + cin.cMaskFlags.pipeAligned = 1; + cin.cMaskFlags.rbAligned = 1; + cin.colorFlags = in->flags; + cin.resourceType = in->resourceType; + cin.unalignedWidth = in->width; + cin.unalignedHeight = in->height; + cin.numSlices = in->numSlices; + + if (in->numSamples > 1) + cin.swizzleMode = surf->u.gfx9.fmask.swizzle_mode; + else + cin.swizzleMode = in->swizzleMode; + + ret = Addr2ComputeCmaskInfo(addrlib, &cin, &cout); + if (ret != ADDR_OK) + return ret; + + surf->u.gfx9.cmask.rb_aligned = cin.cMaskFlags.rbAligned; + surf->u.gfx9.cmask.pipe_aligned = cin.cMaskFlags.pipeAligned; + surf->u.gfx9.cmask_size = cout.cmaskBytes; + surf->u.gfx9.cmask_alignment = cout.baseAlign; + } + } + + return 0; +} + +int gfx9_compute_surface(ADDR_HANDLE addrlib, + const struct ac_surf_config *config, + enum radeon_surf_mode mode, + struct radeon_surf *surf) +{ + bool compressed; + ADDR2_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; + int r; + + assert(!(surf->flags & RADEON_SURF_FMASK)); + + AddrSurfInfoIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT); + + compressed = surf->blk_w == 4 && surf->blk_h == 4; + + /* The format must be set correctly for the allocation of compressed + * textures to work. In other cases, setting the bpp is sufficient. */ + if (compressed) { + switch (surf->bpe) { + case 8: + AddrSurfInfoIn.format = ADDR_FMT_BC1; + break; + case 16: + AddrSurfInfoIn.format = ADDR_FMT_BC3; + break; + default: + assert(0); + } + } else { + AddrSurfInfoIn.bpp = surf->bpe * 8; + } + + AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER); + AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0; + AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0; + AddrSurfInfoIn.flags.texture = 1; + AddrSurfInfoIn.flags.opt4space = 1; + + AddrSurfInfoIn.numMipLevels = config->info.levels; + AddrSurfInfoIn.numSamples = config->info.samples ? config->info.samples : 1; + AddrSurfInfoIn.numFrags = AddrSurfInfoIn.numSamples; + + /* GFX9 doesn't support 1D depth textures, so allocate all 1D textures + * as 2D to avoid having shader variants for 1D vs 2D, so all shaders + * must sample 1D textures as 2D. */ + if (config->is_3d) + AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_3D; + else + AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_2D; + + AddrSurfInfoIn.width = config->info.width; + AddrSurfInfoIn.height = config->info.height; + + if (config->is_3d) + AddrSurfInfoIn.numSlices = config->info.depth; + else if (config->is_cube) + AddrSurfInfoIn.numSlices = 6; + else + AddrSurfInfoIn.numSlices = config->info.array_size; + + switch (mode) { + case RADEON_SURF_MODE_LINEAR_ALIGNED: + assert(config->info.samples <= 1); + assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); + AddrSurfInfoIn.swizzleMode = ADDR_SW_LINEAR; + break; + + case RADEON_SURF_MODE_1D: + case RADEON_SURF_MODE_2D: + r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, false, + &AddrSurfInfoIn.swizzleMode); + if (r) + return r; + break; + + default: + assert(0); + } + + surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType; + + surf->surf_size = 0; + surf->dcc_size = 0; + surf->htile_size = 0; + surf->u.gfx9.surf_offset = 0; + surf->u.gfx9.stencil_offset = 0; + surf->u.gfx9.fmask_size = 0; + surf->u.gfx9.cmask_size = 0; + + /* Calculate texture layout information. */ + r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn); + if (r) + return r; + + /* Calculate texture layout information for stencil. */ + if (surf->flags & RADEON_SURF_SBUFFER) { + AddrSurfInfoIn.bpp = 8; + AddrSurfInfoIn.flags.depth = 0; + AddrSurfInfoIn.flags.stencil = 1; + + r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn); + if (r) + return r; + } + + surf->is_linear = surf->u.gfx9.surf.swizzle_mode == ADDR_SW_LINEAR; + surf->num_dcc_levels = surf->dcc_size ? config->info.levels : 0; + + switch (surf->u.gfx9.surf.swizzle_mode) { + /* S = standard. */ + case ADDR_SW_256B_S: + case ADDR_SW_4KB_S: + case ADDR_SW_64KB_S: + case ADDR_SW_VAR_S: + case ADDR_SW_64KB_S_T: + case ADDR_SW_4KB_S_X: + case ADDR_SW_64KB_S_X: + case ADDR_SW_VAR_S_X: + surf->micro_tile_mode = RADEON_MICRO_MODE_THIN; + break; + + /* D = display. */ + case ADDR_SW_LINEAR: + case ADDR_SW_256B_D: + case ADDR_SW_4KB_D: + case ADDR_SW_64KB_D: + case ADDR_SW_VAR_D: + case ADDR_SW_64KB_D_T: + case ADDR_SW_4KB_D_X: + case ADDR_SW_64KB_D_X: + case ADDR_SW_VAR_D_X: + surf->micro_tile_mode = RADEON_MICRO_MODE_DISPLAY; + break; + + /* R = rotated. */ + case ADDR_SW_256B_R: + case ADDR_SW_4KB_R: + case ADDR_SW_64KB_R: + case ADDR_SW_VAR_R: + case ADDR_SW_64KB_R_T: + case ADDR_SW_4KB_R_X: + case ADDR_SW_64KB_R_X: + case ADDR_SW_VAR_R_X: + surf->micro_tile_mode = RADEON_MICRO_MODE_ROTATED; + break; + + /* Z = depth. */ + case ADDR_SW_4KB_Z: + case ADDR_SW_64KB_Z: + case ADDR_SW_VAR_Z: + case ADDR_SW_64KB_Z_T: + case ADDR_SW_4KB_Z_X: + case ADDR_SW_64KB_Z_X: + case ADDR_SW_VAR_Z_X: + surf->micro_tile_mode = RADEON_MICRO_MODE_DEPTH; + break; + + default: + assert(0); + } + + return 0; +} diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h index 5e4cb81630..9a9697b77d 100644 --- a/src/amd/common/ac_surface.h +++ b/src/amd/common/ac_surface.h @@ -208,5 +208,9 @@ int gfx6_compute_surface(ADDR_HANDLE addrlib, const struct ac_surf_config *config, enum radeon_surf_mode mode, struct radeon_surf *surf); +int gfx9_compute_surface(ADDR_HANDLE addrlib, + const struct ac_surf_config *config, + enum radeon_surf_mode mode, + struct radeon_surf *surf); #endif /* AC_SURFACE_H */ diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c index fc062a6427..76596e8daf 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c @@ -80,11 +80,11 @@ static int amdgpu_surface_sanity(const struct pipe_resource *tex) return 0; } -static int gfx6_surface_init(struct radeon_winsys *rws, - const struct pipe_resource *tex, - unsigned flags, unsigned bpe, - enum radeon_surf_mode mode, - struct radeon_surf *surf) +static int amdgpu_surface_init(struct radeon_winsys *rws, + const struct pipe_resource *tex, + unsigned flags, unsigned bpe, + enum radeon_surf_mode mode, + struct radeon_surf *surf) { struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; int r; @@ -113,418 +113,13 @@ static int gfx6_surface_init(struct radeon_winsys *rws, config.pipe_interleave_bytes = ws->info.pipe_interleave_bytes; config.amdinfo = &ws->amdinfo; - return gfx6_compute_surface(ws->addrlib, &config, mode, surf); -} - -/* This is only called when expecting a tiled layout. */ -static int -gfx9_get_preferred_swizzle_mode(struct amdgpu_winsys *ws, - ADDR2_COMPUTE_SURFACE_INFO_INPUT *in, - bool is_fmask, AddrSwizzleMode *swizzle_mode) -{ - ADDR_E_RETURNCODE ret; - ADDR2_GET_PREFERRED_SURF_SETTING_INPUT sin = {0}; - ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT sout = {0}; - - sin.size = sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT); - sout.size = sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT); - - sin.flags = in->flags; - sin.resourceType = in->resourceType; - sin.format = in->format; - sin.resourceLoction = ADDR_RSRC_LOC_INVIS; - /* TODO: We could allow some of these: */ - sin.forbiddenBlock.micro = 1; /* don't allow the 256B swizzle modes */ - sin.forbiddenBlock.var = 1; /* don't allow the variable-sized swizzle modes */ - sin.forbiddenBlock.linear = 1; /* don't allow linear swizzle modes */ - sin.bpp = in->bpp; - sin.width = in->width; - sin.height = in->height; - sin.numSlices = in->numSlices; - sin.numMipLevels = in->numMipLevels; - sin.numSamples = in->numSamples; - sin.numFrags = in->numFrags; - - if (is_fmask) { - sin.flags.color = 0; - sin.flags.fmask = 1; - } - - ret = Addr2GetPreferredSurfaceSetting(ws->addrlib, &sin, &sout); - if (ret != ADDR_OK) - return ret; - - *swizzle_mode = sout.swizzleMode; - return 0; -} - -static int gfx9_compute_miptree(struct amdgpu_winsys *ws, - struct radeon_surf *surf, bool compressed, - ADDR2_COMPUTE_SURFACE_INFO_INPUT *in) -{ - ADDR2_MIP_INFO mip_info[RADEON_SURF_MAX_LEVELS] = {}; - ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0}; - ADDR_E_RETURNCODE ret; - - out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT); - out.pMipInfo = mip_info; - - ret = Addr2ComputeSurfaceInfo(ws->addrlib, in, &out); - if (ret != ADDR_OK) - return ret; - - if (in->flags.stencil) { - surf->u.gfx9.stencil.swizzle_mode = in->swizzleMode; - surf->u.gfx9.stencil.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 : - out.mipChainPitch - 1; - surf->surf_alignment = MAX2(surf->surf_alignment, out.baseAlign); - surf->u.gfx9.stencil_offset = align(surf->surf_size, out.baseAlign); - surf->surf_size = surf->u.gfx9.stencil_offset + out.surfSize; - return 0; - } - - surf->u.gfx9.surf.swizzle_mode = in->swizzleMode; - surf->u.gfx9.surf.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 : - out.mipChainPitch - 1; - - /* CMASK fast clear uses these even if FMASK isn't allocated. - * FMASK only supports the Z swizzle modes, whose numbers are multiples of 4. - */ - surf->u.gfx9.fmask.swizzle_mode = surf->u.gfx9.surf.swizzle_mode & ~0x3; - surf->u.gfx9.fmask.epitch = surf->u.gfx9.surf.epitch; - - surf->u.gfx9.surf_slice_size = out.sliceSize; - surf->u.gfx9.surf_pitch = out.pitch; - surf->u.gfx9.surf_height = out.height; - surf->surf_size = out.surfSize; - surf->surf_alignment = out.baseAlign; - - if (in->swizzleMode == ADDR_SW_LINEAR) { - for (unsigned i = 0; i < in->numMipLevels; i++) - surf->u.gfx9.offset[i] = mip_info[i].offset; - } - - if (in->flags.depth) { - assert(in->swizzleMode != ADDR_SW_LINEAR); - - /* HTILE */ - ADDR2_COMPUTE_HTILE_INFO_INPUT hin = {0}; - ADDR2_COMPUTE_HTILE_INFO_OUTPUT hout = {0}; - - hin.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT); - hout.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT); - - hin.hTileFlags.pipeAligned = 1; - hin.hTileFlags.rbAligned = 1; - hin.depthFlags = in->flags; - hin.swizzleMode = in->swizzleMode; - hin.unalignedWidth = in->width; - hin.unalignedHeight = in->height; - hin.numSlices = in->numSlices; - hin.numMipLevels = in->numMipLevels; - - ret = Addr2ComputeHtileInfo(ws->addrlib, &hin, &hout); - if (ret != ADDR_OK) - return ret; - - surf->u.gfx9.htile.rb_aligned = hin.hTileFlags.rbAligned; - surf->u.gfx9.htile.pipe_aligned = hin.hTileFlags.pipeAligned; - surf->htile_size = hout.htileBytes; - surf->htile_alignment = hout.baseAlign; - } else { - /* DCC */ - if (!(surf->flags & RADEON_SURF_DISABLE_DCC) && - !(surf->flags & RADEON_SURF_SCANOUT) && - !compressed && - in->swizzleMode != ADDR_SW_LINEAR && - /* TODO: We could support DCC with MSAA. */ - in->numSamples == 1) { - ADDR2_COMPUTE_DCCINFO_INPUT din = {0}; - ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0}; - - din.size = sizeof(ADDR2_COMPUTE_DCCINFO_INPUT); - dout.size = sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT); - - din.dccKeyFlags.pipeAligned = 1; - din.dccKeyFlags.rbAligned = 1; - din.colorFlags = in->flags; - din.resourceType = in->resourceType; - din.swizzleMode = in->swizzleMode; - din.bpp = in->bpp; - din.unalignedWidth = in->width; - din.unalignedHeight = in->height; - din.numSlices = in->numSlices; - din.numFrags = in->numFrags; - din.numMipLevels = in->numMipLevels; - din.dataSurfaceSize = out.surfSize; - - ret = Addr2ComputeDccInfo(ws->addrlib, &din, &dout); - if (ret != ADDR_OK) - return ret; - - surf->u.gfx9.dcc.rb_aligned = din.dccKeyFlags.rbAligned; - surf->u.gfx9.dcc.pipe_aligned = din.dccKeyFlags.pipeAligned; - surf->u.gfx9.dcc_pitch_max = dout.pitch - 1; - surf->dcc_size = dout.dccRamSize; - surf->dcc_alignment = dout.dccRamBaseAlign; - } - - /* FMASK */ - if (in->numSamples > 1) { - ADDR2_COMPUTE_FMASK_INFO_INPUT fin = {0}; - ADDR2_COMPUTE_FMASK_INFO_OUTPUT fout = {0}; - - fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT); - fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT); - - ret = gfx9_get_preferred_swizzle_mode(ws, in, true, &fin.swizzleMode); - if (ret != ADDR_OK) - return ret; - - fin.unalignedWidth = in->width; - fin.unalignedHeight = in->height; - fin.numSlices = in->numSlices; - fin.numSamples = in->numSamples; - fin.numFrags = in->numFrags; - - ret = Addr2ComputeFmaskInfo(ws->addrlib, &fin, &fout); - if (ret != ADDR_OK) - return ret; - - surf->u.gfx9.fmask.swizzle_mode = fin.swizzleMode; - surf->u.gfx9.fmask.epitch = fout.pitch - 1; - surf->u.gfx9.fmask_size = fout.fmaskBytes; - surf->u.gfx9.fmask_alignment = fout.baseAlign; - } - - /* CMASK */ - if (in->swizzleMode != ADDR_SW_LINEAR) { - ADDR2_COMPUTE_CMASK_INFO_INPUT cin = {0}; - ADDR2_COMPUTE_CMASK_INFO_OUTPUT cout = {0}; - - cin.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT); - cout.size = sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT); - - cin.cMaskFlags.pipeAligned = 1; - cin.cMaskFlags.rbAligned = 1; - cin.colorFlags = in->flags; - cin.resourceType = in->resourceType; - cin.unalignedWidth = in->width; - cin.unalignedHeight = in->height; - cin.numSlices = in->numSlices; - - if (in->numSamples > 1) - cin.swizzleMode = surf->u.gfx9.fmask.swizzle_mode; - else - cin.swizzleMode = in->swizzleMode; - - ret = Addr2ComputeCmaskInfo(ws->addrlib, &cin, &cout); - if (ret != ADDR_OK) - return ret; - - surf->u.gfx9.cmask.rb_aligned = cin.cMaskFlags.rbAligned; - surf->u.gfx9.cmask.pipe_aligned = cin.cMaskFlags.pipeAligned; - surf->u.gfx9.cmask_size = cout.cmaskBytes; - surf->u.gfx9.cmask_alignment = cout.baseAlign; - } - } - - return 0; -} - -static int gfx9_surface_init(struct radeon_winsys *rws, - const struct pipe_resource *tex, - unsigned flags, unsigned bpe, - enum radeon_surf_mode mode, - struct radeon_surf *surf) -{ - struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; - bool compressed; - ADDR2_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; - int r; - - assert(!(flags & RADEON_SURF_FMASK)); - - r = amdgpu_surface_sanity(tex); - if (r) - return r; - - AddrSurfInfoIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT); - - surf->blk_w = util_format_get_blockwidth(tex->format); - surf->blk_h = util_format_get_blockheight(tex->format); - surf->bpe = bpe; - surf->flags = flags; - - compressed = surf->blk_w == 4 && surf->blk_h == 4; - - /* The format must be set correctly for the allocation of compressed - * textures to work. In other cases, setting the bpp is sufficient. */ - if (compressed) { - switch (bpe) { - case 8: - AddrSurfInfoIn.format = ADDR_FMT_BC1; - break; - case 16: - AddrSurfInfoIn.format = ADDR_FMT_BC3; - break; - default: - assert(0); - } - } else { - AddrSurfInfoIn.bpp = bpe * 8; - } - - AddrSurfInfoIn.flags.color = !(flags & RADEON_SURF_Z_OR_SBUFFER); - AddrSurfInfoIn.flags.depth = (flags & RADEON_SURF_ZBUFFER) != 0; - AddrSurfInfoIn.flags.display = (flags & RADEON_SURF_SCANOUT) != 0; - AddrSurfInfoIn.flags.texture = 1; - AddrSurfInfoIn.flags.opt4space = 1; - - AddrSurfInfoIn.numMipLevels = tex->last_level + 1; - AddrSurfInfoIn.numSamples = tex->nr_samples ? tex->nr_samples : 1; - AddrSurfInfoIn.numFrags = AddrSurfInfoIn.numSamples; - - switch (tex->target) { - /* GFX9 doesn't support 1D depth textures, so allocate all 1D textures - * as 2D to avoid having shader variants for 1D vs 2D, so all shaders - * must sample 1D textures as 2D. */ - case PIPE_TEXTURE_1D: - case PIPE_TEXTURE_1D_ARRAY: - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_2D_ARRAY: - case PIPE_TEXTURE_RECT: - case PIPE_TEXTURE_CUBE: - case PIPE_TEXTURE_CUBE_ARRAY: - case PIPE_TEXTURE_3D: - if (tex->target == PIPE_TEXTURE_3D) - AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_3D; - else - AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_2D; - - AddrSurfInfoIn.width = tex->width0; - AddrSurfInfoIn.height = tex->height0; - - if (tex->target == PIPE_TEXTURE_3D) - AddrSurfInfoIn.numSlices = tex->depth0; - else if (tex->target == PIPE_TEXTURE_CUBE) - AddrSurfInfoIn.numSlices = 6; - else - AddrSurfInfoIn.numSlices = tex->array_size; - - switch (mode) { - case RADEON_SURF_MODE_LINEAR_ALIGNED: - assert(tex->nr_samples <= 1); - assert(!(flags & RADEON_SURF_Z_OR_SBUFFER)); - AddrSurfInfoIn.swizzleMode = ADDR_SW_LINEAR; - break; - - case RADEON_SURF_MODE_1D: - case RADEON_SURF_MODE_2D: - r = gfx9_get_preferred_swizzle_mode(ws, &AddrSurfInfoIn, false, - &AddrSurfInfoIn.swizzleMode); - if (r) - return r; - break; - - default: - assert(0); - } - break; - - default: - assert(0); - } - - surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType; - - surf->surf_size = 0; - surf->dcc_size = 0; - surf->htile_size = 0; - surf->u.gfx9.surf_offset = 0; - surf->u.gfx9.stencil_offset = 0; - surf->u.gfx9.fmask_size = 0; - surf->u.gfx9.cmask_size = 0; - - /* Calculate texture layout information. */ - r = gfx9_compute_miptree(ws, surf, compressed, &AddrSurfInfoIn); - if (r) - return r; - - /* Calculate texture layout information for stencil. */ - if (flags & RADEON_SURF_SBUFFER) { - AddrSurfInfoIn.bpp = 8; - AddrSurfInfoIn.flags.depth = 0; - AddrSurfInfoIn.flags.stencil = 1; - - r = gfx9_compute_miptree(ws, surf, compressed, &AddrSurfInfoIn); - if (r) - return r; - } - - surf->is_linear = surf->u.gfx9.surf.swizzle_mode == ADDR_SW_LINEAR; - surf->num_dcc_levels = surf->dcc_size ? tex->last_level + 1 : 0; - - switch (surf->u.gfx9.surf.swizzle_mode) { - /* S = standard. */ - case ADDR_SW_256B_S: - case ADDR_SW_4KB_S: - case ADDR_SW_64KB_S: - case ADDR_SW_VAR_S: - case ADDR_SW_64KB_S_T: - case ADDR_SW_4KB_S_X: - case ADDR_SW_64KB_S_X: - case ADDR_SW_VAR_S_X: - surf->micro_tile_mode = RADEON_MICRO_MODE_THIN; - break; - - /* D = display. */ - case ADDR_SW_LINEAR: - case ADDR_SW_256B_D: - case ADDR_SW_4KB_D: - case ADDR_SW_64KB_D: - case ADDR_SW_VAR_D: - case ADDR_SW_64KB_D_T: - case ADDR_SW_4KB_D_X: - case ADDR_SW_64KB_D_X: - case ADDR_SW_VAR_D_X: - surf->micro_tile_mode = RADEON_MICRO_MODE_DISPLAY; - break; - - /* R = rotated. */ - case ADDR_SW_256B_R: - case ADDR_SW_4KB_R: - case ADDR_SW_64KB_R: - case ADDR_SW_VAR_R: - case ADDR_SW_64KB_R_T: - case ADDR_SW_4KB_R_X: - case ADDR_SW_64KB_R_X: - case ADDR_SW_VAR_R_X: - surf->micro_tile_mode = RADEON_MICRO_MODE_ROTATED; - break; - - /* Z = depth. */ - case ADDR_SW_4KB_Z: - case ADDR_SW_64KB_Z: - case ADDR_SW_VAR_Z: - case ADDR_SW_64KB_Z_T: - case ADDR_SW_4KB_Z_X: - case ADDR_SW_64KB_Z_X: - case ADDR_SW_VAR_Z_X: - surf->micro_tile_mode = RADEON_MICRO_MODE_DEPTH; - break; - - default: - assert(0); - } - - return 0; + if (ws->info.chip_class >= GFX9) + return gfx9_compute_surface(ws->addrlib, &config, mode, surf); + else + return gfx6_compute_surface(ws->addrlib, &config, mode, surf); } void amdgpu_surface_init_functions(struct amdgpu_winsys *ws) { - if (ws->info.chip_class >= GFX9) - ws->base.surface_init = gfx9_surface_init; - else - ws->base.surface_init = gfx6_surface_init; + ws->base.surface_init = amdgpu_surface_init; } |