diff options
author | Satyajit Sahu <satyajit.sahu@amd.com> | 2017-11-10 13:57:29 +0530 |
---|---|---|
committer | Nicolai Hähnle <nhaehnle@gmail.com> | 2017-11-28 16:32:26 +0100 |
commit | 16d69de8bea61e61e19e58b42b29cc8633cfa5d5 (patch) | |
tree | 2eceb872fd6d20cdc6fc303896e74bf9637d49c3 | |
parent | ca2938a5c681e42a344f7237430726aa17ff1126 (diff) |
Tiled to linear and removal of addrlib dependency
Tiled to linear conversion added in bo_map. Also writing back to
tiled data in bo_unmap.
addrlib dependency removed and mesa apis (radeonsi_dri.so) called
directly.
Change-Id: Icb6e5d425c995d3bc4e3b4b8c1e9a7de7947b7b8
Signed-off-by: Satyajit Sahu <satyajit.sahu@amd.com>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | amdgpu.c | 466 |
2 files changed, 250 insertions, 218 deletions
@@ -14,7 +14,7 @@ CFLAGS += -std=c99 -Wall -Wsign-compare -Wpointer-arith -Wcast-qual \ ifdef DRV_AMDGPU CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amdgpu) - LDLIBS += -lamdgpuaddr + LDLIBS += -ldrm_amdgpu -ldl endif ifdef DRV_EXYNOS CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_exynos) @@ -6,6 +6,7 @@ #ifdef DRV_AMDGPU #include <amdgpu.h> #include <amdgpu_drm.h> +#include <dlfcn.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -13,34 +14,60 @@ #include <sys/mman.h> #include <xf86drm.h> -#include "addrinterface.h" #include "drv_priv.h" #include "helpers.h" #include "util.h" - -#ifndef CIASICIDGFXENGINE_SOUTHERNISLAND -#define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A -#endif +#include "ac_surface.h" +#include "ac_gpu_info.h" // clang-format off -#define mmCC_RB_BACKEND_DISABLE 0x263d -#define mmGB_TILE_MODE0 0x2644 -#define mmGB_MACROTILE_MODE0 0x2664 -#define mmGB_ADDR_CONFIG 0x263e -#define mmMC_ARB_RAMCFG 0x9d8 - -enum { - FAMILY_UNKNOWN, - FAMILY_SI, - FAMILY_CI, - FAMILY_KV, - FAMILY_VI, - FAMILY_CZ, - FAMILY_PI, - FAMILY_LAST, +#define DRI_PATH "/usr/lib64/dri/radeonsi_dri.so" + +typedef void* (*addr_create)(const struct radeon_info*, + const struct amdgpu_gpu_info*, + uint64_t*); + +typedef int (*addr_destroy)(void*); + +typedef int (*compute_surface)(void*, + const struct radeon_info*, + const struct ac_surf_config*, + enum radeon_surf_mode, + struct radeon_surf*); + +typedef bool (*query_gpu_info)(int, amdgpu_device_handle, + struct radeon_info*, struct amdgpu_gpu_info*); + +typedef int (*read_write_tiled)(void*, struct ac_surf_config*, + struct radeon_surf*, void*, + uint8_t*, int); + +struct dri_functors { + void *handle; + addr_create fptr_create; + addr_destroy fptr_destroy; + compute_surface fptr_compute_surface; + query_gpu_info fptr_query_gpu_info; + read_write_tiled fptr_read_write_tiled; +}; + +struct drv_priv_ptr { + struct dri_functors *dri_handle; + void *addrlib_handle; + enum radeon_surf_mode surf_mode; + struct radeon_info info; + struct ac_surf_config surf_config; + struct radeon_surf *surf_info; + uint64_t base_align; +}; + +struct bo_priv_ptr { + void *untiled_buf_ptr; + uint32_t ref_count; + int prot; }; -// clang-format on +// clang-format on const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; @@ -71,204 +98,73 @@ static int amdgpu_set_metadata(int fd, uint32_t handle, struct amdgpu_bo_metadat return drmCommandWriteRead(fd, DRM_AMDGPU_GEM_METADATA, &args, sizeof(args)); } -static int amdgpu_read_mm_regs(int fd, unsigned dword_offset, unsigned count, uint32_t instance, - uint32_t flags, uint32_t *values) +static int amdgpu_addrlib_compute(struct drv_priv_ptr *drv_priv, uint32_t width, uint32_t height, + uint32_t format, uint64_t use_flags, uint32_t *tiling_flags) { - struct drm_amdgpu_info request; - - memset(&request, 0, sizeof(request)); - request.return_pointer = (uintptr_t)values; - request.return_size = count * sizeof(uint32_t); - request.query = AMDGPU_INFO_READ_MMR_REG; - request.read_mmr_reg.dword_offset = dword_offset; - request.read_mmr_reg.count = count; - request.read_mmr_reg.instance = instance; - request.read_mmr_reg.flags = flags; - - return drmCommandWrite(fd, DRM_AMDGPU_INFO, &request, sizeof(struct drm_amdgpu_info)); -} + struct radeon_surf *surf_info = drv_priv->surf_info; + memset(surf_info, 0, sizeof(struct radeon_surf)); + struct ac_surf_config surf_config; -static int amdgpu_query_gpu(int fd, struct amdgpu_gpu_info *gpu_info) -{ - int ret; - uint32_t instance; + drv_priv->surf_mode = RADEON_SURF_MODE_2D; - if (!gpu_info) - return -EINVAL; + surf_config.info.width = width; + surf_config.info.height = height; + surf_config.info.depth = 1; + surf_config.info.samples = 1; + surf_config.info.levels = 1; + surf_config.info.array_size = 1; + surf_config.is_3d = 0; + surf_config.is_cube = 0; - instance = AMDGPU_INFO_MMR_SH_INDEX_MASK << AMDGPU_INFO_MMR_SH_INDEX_SHIFT; + surf_info->bpe = drv_stride_from_format(format, 1, 0); - ret = amdgpu_read_mm_regs(fd, mmCC_RB_BACKEND_DISABLE, 1, instance, 0, - &gpu_info->backend_disable[0]); - if (ret) - return ret; - /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */ - gpu_info->backend_disable[0] = (gpu_info->backend_disable[0] >> 16) & 0xff; - - ret = amdgpu_read_mm_regs(fd, mmGB_TILE_MODE0, 32, 0xffffffff, 0, gpu_info->gb_tile_mode); - if (ret) - return ret; - - ret = amdgpu_read_mm_regs(fd, mmGB_MACROTILE_MODE0, 16, 0xffffffff, 0, - gpu_info->gb_macro_tile_mode); - if (ret) - return ret; - - ret = amdgpu_read_mm_regs(fd, mmGB_ADDR_CONFIG, 1, 0xffffffff, 0, &gpu_info->gb_addr_cfg); - if (ret) - return ret; - - ret = amdgpu_read_mm_regs(fd, mmMC_ARB_RAMCFG, 1, 0xffffffff, 0, &gpu_info->mc_arb_ramcfg); - if (ret) - return ret; - - return 0; -} - -static void *ADDR_API alloc_sys_mem(const ADDR_ALLOCSYSMEM_INPUT *in) -{ - return malloc(in->sizeInBytes); -} - -static ADDR_E_RETURNCODE ADDR_API free_sys_mem(const ADDR_FREESYSMEM_INPUT *in) -{ - free(in->pVirtAddr); - return ADDR_OK; -} - -static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags, uint32_t *tiling_flags, - ADDR_COMPUTE_SURFACE_INFO_OUTPUT *addr_out) -{ - ADDR_COMPUTE_SURFACE_INFO_INPUT addr_surf_info_in = { 0 }; - ADDR_TILEINFO addr_tile_info = { 0 }; - ADDR_TILEINFO addr_tile_info_out = { 0 }; - uint32_t bits_per_pixel; - - addr_surf_info_in.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); - - /* Set the requested tiling mode. */ - addr_surf_info_in.tileMode = ADDR_TM_2D_TILED_THIN1; if (use_flags & - (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) - addr_surf_info_in.tileMode = ADDR_TM_LINEAR_ALIGNED; - else if (width <= 16 || height <= 16) - addr_surf_info_in.tileMode = ADDR_TM_1D_TILED_THIN1; - - bits_per_pixel = drv_stride_from_format(format, 1, 0) * 8; - /* Bits per pixel should be calculated from format*/ - addr_surf_info_in.bpp = bits_per_pixel; - addr_surf_info_in.numSamples = 1; - addr_surf_info_in.width = width; - addr_surf_info_in.height = height; - addr_surf_info_in.numSlices = 1; - addr_surf_info_in.pTileInfo = &addr_tile_info; - addr_surf_info_in.tileIndex = -1; - - /* This disables incorrect calculations (hacks) in addrlib. */ - addr_surf_info_in.flags.noStencil = 1; - - /* Set the micro tile type. */ - if (use_flags & BO_USE_SCANOUT) - addr_surf_info_in.tileType = ADDR_DISPLAYABLE; - else - addr_surf_info_in.tileType = ADDR_NON_DISPLAYABLE; - - addr_out->size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); - addr_out->pTileInfo = &addr_tile_info_out; - - if (AddrComputeSurfaceInfo(addrlib, &addr_surf_info_in, addr_out) != ADDR_OK) - return -EINVAL; - - ADDR_CONVERT_TILEINFOTOHW_INPUT s_in = { 0 }; - ADDR_CONVERT_TILEINFOTOHW_OUTPUT s_out = { 0 }; - ADDR_TILEINFO s_tile_hw_info_out = { 0 }; + (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) { + drv_priv->surf_mode = RADEON_SURF_MODE_LINEAR_ALIGNED; + } else if (width <= 16 || height <= 16) { + drv_priv->surf_mode = RADEON_SURF_MODE_1D; + } - s_in.size = sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT); - /* Convert from real value to HW value */ - s_in.reverse = 0; - s_in.pTileInfo = &addr_tile_info_out; - s_in.tileIndex = -1; + if (use_flags & BO_USE_SCANOUT) + surf_info->flags |= RADEON_SURF_SCANOUT; - s_out.size = sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT); - s_out.pTileInfo = &s_tile_hw_info_out; + drv_priv->dri_handle->fptr_compute_surface(drv_priv->addrlib_handle, &drv_priv->info, + &surf_config, drv_priv->surf_mode, surf_info); + drv_priv->surf_mode = surf_info->u.legacy.level[0].mode; - if (AddrConvertTileInfoToHW(addrlib, &s_in, &s_out) != ADDR_OK) - return -EINVAL; + drv_priv->surf_config = surf_config; + *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1 << (drv_priv->surf_mode - 1)); + *tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, surf_info->micro_tile_mode); - if (addr_out->tileMode >= ADDR_TM_2D_TILED_THIN1) - /* 2D_TILED_THIN1 */ - *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 4); - else if (addr_out->tileMode >= ADDR_TM_1D_TILED_THIN1) - /* 1D_TILED_THIN1 */ - *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 2); - else - /* LINEAR_ALIGNED */ - *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); - - *tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, drv_log_base2(addr_tile_info_out.bankWidth)); - *tiling_flags |= - AMDGPU_TILING_SET(BANK_HEIGHT, drv_log_base2(addr_tile_info_out.bankHeight)); - *tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, s_tile_hw_info_out.tileSplitBytes); - *tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, - drv_log_base2(addr_tile_info_out.macroAspectRatio)); - *tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, s_tile_hw_info_out.pipeConfig); - *tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, s_tile_hw_info_out.banks); + *tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, drv_log_base2(surf_info->u.legacy.bankw)); + *tiling_flags |= AMDGPU_TILING_SET(BANK_HEIGHT, drv_log_base2(surf_info->u.legacy.bankh)); + *tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, drv_log_base2(surf_info->u.legacy.tile_split >> 6)); + *tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, drv_log_base2(surf_info->u.legacy.mtilea)); + *tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, surf_info->u.legacy.pipe_config); + *tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, drv_log_base2(surf_info->u.legacy.num_banks >> 1)); return 0; } -static void *amdgpu_addrlib_init(int fd) +static void *amdgpu_addrlib_init(int fd, struct dri_functors* dri_handle, struct radeon_info* info, uint64_t *base_align) { int ret; - ADDR_CREATE_INPUT addr_create_input = { 0 }; - ADDR_CREATE_OUTPUT addr_create_output = { 0 }; - ADDR_REGISTER_VALUE reg_value = { 0 }; - ADDR_CREATE_FLAGS create_flags = { { 0 } }; - ADDR_E_RETURNCODE addr_ret; - - addr_create_input.size = sizeof(ADDR_CREATE_INPUT); - addr_create_output.size = sizeof(ADDR_CREATE_OUTPUT); - struct amdgpu_gpu_info gpu_info = { 0 }; + amdgpu_device_handle dev; + uint32_t drm_major, drm_minor; + void *addr_handle = NULL; - ret = amdgpu_query_gpu(fd, &gpu_info); - + ret = amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev); if (ret) { - fprintf(stderr, "[%s]failed with error =%d\n", __func__, ret); return NULL; } - - reg_value.noOfBanks = gpu_info.mc_arb_ramcfg & 0x3; - reg_value.gbAddrConfig = gpu_info.gb_addr_cfg; - reg_value.noOfRanks = (gpu_info.mc_arb_ramcfg & 0x4) >> 2; - - reg_value.backendDisables = gpu_info.backend_disable[0]; - reg_value.pTileConfig = gpu_info.gb_tile_mode; - reg_value.noOfEntries = sizeof(gpu_info.gb_tile_mode) / sizeof(gpu_info.gb_tile_mode[0]); - reg_value.pMacroTileConfig = gpu_info.gb_macro_tile_mode; - reg_value.noOfMacroEntries = - sizeof(gpu_info.gb_macro_tile_mode) / sizeof(gpu_info.gb_macro_tile_mode[0]); - create_flags.value = 0; - create_flags.useTileIndex = 1; - - addr_create_input.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND; - - addr_create_input.chipFamily = FAMILY_CZ; - addr_create_input.createFlags = create_flags; - addr_create_input.callbacks.allocSysMem = alloc_sys_mem; - addr_create_input.callbacks.freeSysMem = free_sys_mem; - addr_create_input.callbacks.debugPrint = 0; - addr_create_input.regValue = reg_value; - - addr_ret = AddrCreate(&addr_create_input, &addr_create_output); - - if (addr_ret != ADDR_OK) { - fprintf(stderr, "[%s]failed error =%d\n", __func__, addr_ret); + if (!dri_handle->fptr_query_gpu_info(fd, dev, info, &gpu_info)) { return NULL; } - return addr_create_output.hLib; + amdgpu_device_deinitialize(dev); + addr_handle = dri_handle->fptr_create(info, &gpu_info, base_align); + return addr_handle; } static int amdgpu_init(struct driver *drv) @@ -276,12 +172,45 @@ static int amdgpu_init(struct driver *drv) void *addrlib; struct format_metadata metadata; uint64_t use_flags = BO_USE_RENDER_MASK; + struct drv_priv_ptr* drv_priv = (struct drv_priv_ptr*) malloc (sizeof(struct drv_priv_ptr)); + drv_priv->surf_info = (struct radeon_surf*) malloc (sizeof(struct radeon_surf)); + drv_priv->dri_handle = (struct dri_functors*) malloc (sizeof(struct dri_functors)); + drv_priv->dri_handle->handle = dlopen(DRI_PATH, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); + if (!drv_priv->dri_handle->handle) + return -1; + + drv_priv->dri_handle->fptr_create = + (addr_create)dlsym(drv_priv->dri_handle->handle, "amdgpu_addr_create"); + if (!drv_priv->dri_handle->fptr_create) + return -1; - addrlib = amdgpu_addrlib_init(drv_get_fd(drv)); + drv_priv->dri_handle->fptr_destroy = + (addr_destroy)dlsym(drv_priv->dri_handle->handle, "amdgpu_addr_destroy"); + if (!drv_priv->dri_handle->fptr_destroy) + return -1; + + drv_priv->dri_handle->fptr_compute_surface = + (compute_surface)dlsym(drv_priv->dri_handle->handle, "ac_compute_surface"); + if (!drv_priv->dri_handle->fptr_compute_surface) + return -1; + + drv_priv->dri_handle->fptr_query_gpu_info = + (query_gpu_info)dlsym(drv_priv->dri_handle->handle, "ac_query_gpu_info"); + if (!drv_priv->dri_handle->fptr_query_gpu_info) + return -1; + + drv_priv->dri_handle->fptr_read_write_tiled = + (read_write_tiled)dlsym(drv_priv->dri_handle->handle, "ac_read_write_tiled_data"); + if (!drv_priv->dri_handle->fptr_read_write_tiled) { + return -1; + } + + addrlib = amdgpu_addrlib_init(drv_get_fd(drv), drv_priv->dri_handle, &drv_priv->info, &drv_priv->base_align); if (!addrlib) return -1; - drv->priv = addrlib; + drv_priv->addrlib_handle = addrlib; + drv->priv = drv_priv; drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); @@ -299,7 +228,7 @@ static int amdgpu_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_SCANOUT); - metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; + metadata.tiling = RADEON_MICRO_MODE_DISPLAY << 16 | RADEON_SURF_MODE_LINEAR_ALIGNED; metadata.priority = 2; metadata.modifier = DRM_FORMAT_MOD_LINEAR; @@ -310,7 +239,7 @@ static int amdgpu_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); - metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; + metadata.tiling = RADEON_MICRO_MODE_THIN << 16 | RADEON_SURF_MODE_LINEAR_ALIGNED; metadata.priority = 3; metadata.modifier = DRM_FORMAT_MOD_LINEAR; @@ -321,7 +250,7 @@ static int amdgpu_init(struct driver *drv) use_flags &= ~BO_USE_SW_READ_OFTEN; use_flags &= ~BO_USE_LINEAR; - metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; + metadata.tiling = RADEON_MICRO_MODE_DISPLAY << 16 | RADEON_SURF_MODE_2D; metadata.priority = 4; drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), @@ -331,7 +260,7 @@ static int amdgpu_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); - metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; + metadata.tiling = RADEON_MICRO_MODE_THIN << 16 | RADEON_SURF_MODE_2D; metadata.priority = 5; drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), @@ -342,48 +271,75 @@ static int amdgpu_init(struct driver *drv) static void amdgpu_close(struct driver *drv) { - AddrDestroy(drv->priv); + struct drv_priv_ptr* drv_priv = (struct drv_priv_ptr*)drv->priv; + drv_priv->dri_handle->fptr_destroy(drv_priv->addrlib_handle); + drv_priv->addrlib_handle = NULL; + free(drv_priv->surf_info); + drv_priv->surf_info = NULL; + dlclose(drv_priv->dri_handle->handle); + free(drv_priv->dri_handle); + drv_priv->dri_handle = NULL; drv->priv = NULL; } static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { - void *addrlib = bo->drv->priv; + struct drv_priv_ptr *drv_priv = (struct drv_priv_ptr*)bo->drv->priv; + struct bo_priv_ptr *bo_priv = (struct bo_priv_ptr*)bo->priv; union drm_amdgpu_gem_create gem_create; struct amdgpu_bo_metadata metadata = { 0 }; - ADDR_COMPUTE_SURFACE_INFO_OUTPUT addr_out = { 0 }; uint32_t tiling_flags = 0; size_t plane; int ret; + struct driver* tmp_drv = bo->drv; + + if (bo->priv == NULL) { + bo_priv = (struct bo_priv_ptr*) malloc (sizeof(struct bo_priv_ptr)); + bo_priv->ref_count = 0; + bo_priv->untiled_buf_ptr = NULL; + bo->priv = bo_priv; + } else { + bo_priv = (struct bo_priv_ptr*)bo->priv; + } if (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV21) { drv_bo_from_format(bo, ALIGN(width, 64), height, format); } else { - if (amdgpu_addrlib_compute(addrlib, width, height, format, use_flags, &tiling_flags, - &addr_out) < 0) + if (amdgpu_addrlib_compute(drv_priv, width, height, format, use_flags, + &tiling_flags) < 0) { return -EINVAL; - + } bo->tiling = tiling_flags; /* RGB has 1 plane only */ - bo->offsets[0] = 0; - bo->total_size = bo->sizes[0] = addr_out.surfSize; - bo->strides[0] = addr_out.pixelPitch * DIV_ROUND_UP(addr_out.pixelBits, 8); + bo->offsets[0] = drv_priv->surf_info->u.legacy.level[0].offset; + bo->total_size = bo->sizes[0] = drv_priv->surf_info->surf_size; + + bo->strides[0] = drv_stride_from_format(format, + drv_priv->surf_info->u.legacy.level[0].nblk_x,0); } + //FIXME:drv pointer gets changed after amdgpu_addrlib_compute call + //store it in temp pointer + bo->drv = tmp_drv; + memset(&gem_create, 0, sizeof(gem_create)); gem_create.in.bo_size = bo->total_size; - gem_create.in.alignment = addr_out.baseAlign; + gem_create.in.alignment = drv_priv->surf_info->surf_alignment; + /* Set the placement. */ gem_create.in.domains = AMDGPU_GEM_DOMAIN_VRAM; gem_create.in.domain_flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; /* Allocate the buffer with the preferred heap. */ + ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, sizeof(gem_create)); - if (ret < 0) + if (ret < 0) { + fprintf(stderr, "drmCommandWriteRead failed with %d\n", ret); return ret; + } metadata.tiling_info = tiling_flags; @@ -395,10 +351,43 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint return ret; } +static int amdgpu_gbm_bo_import(struct bo *bo, struct drv_import_fd_data *data) +{ + struct drv_priv_ptr *drv_priv = (struct drv_priv_ptr*)bo->drv->priv; + struct bo_priv_ptr *bo_priv = NULL; + uint32_t width = data->width; + uint32_t height = data->height; + uint32_t format = data->format; + uint32_t usage = data->use_flags; + uint32_t tiling_flags = 0; + + if (bo->priv == NULL) { + bo_priv = (struct bo_priv_ptr*) malloc (sizeof(struct bo_priv_ptr)); + bo_priv->ref_count = 0; + bo->priv = bo_priv; + } else { + bo_priv = (struct bo_priv_ptr*)bo->priv; + } + + if (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV21) { + drv_bo_from_format(bo, ALIGN(width, 64), height, format); + } else { + if (amdgpu_addrlib_compute(drv_priv, width, height, format, usage, + &tiling_flags) < 0) { + return -EINVAL; + } + } + return drv_prime_bo_import(bo, data); +} + static void *amdgpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; union drm_amdgpu_gem_mmap gem_map; + void *addr = NULL; + int prot = drv_get_prot(map_flags); + struct bo_priv_ptr *bo_priv = (struct bo_priv_ptr*)bo->priv; + struct drv_priv_ptr *drv_priv = (struct drv_priv_ptr*)bo->drv->priv; memset(&gem_map, 0, sizeof(gem_map)); gem_map.in.handle = bo->handles[plane].u32; @@ -410,11 +399,54 @@ static void *amdgpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_ } vma->length = bo->total_size; - - return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, - gem_map.out.addr_ptr); + addr = mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, gem_map.out.addr_ptr); + if (drv_priv->surf_mode >= RADEON_SURF_MODE_2D) { + if (bo_priv->ref_count == 0) { + uint32_t buf_size = drv_priv->surf_info->u.legacy.level[0].nblk_x * + drv_priv->surf_config.info.height * + (drv_priv->surf_info->bpe); + bo_priv->untiled_buf_ptr = malloc(buf_size); + if (bo_priv->untiled_buf_ptr == NULL) { + munmap(addr, vma->length); + return NULL; + } + } + bo_priv->prot = prot; + bo_priv->ref_count++; + drv_priv->dri_handle->fptr_read_write_tiled(drv_priv->addrlib_handle, + &drv_priv->surf_config, + drv_priv->surf_info, addr, + (uint8_t*)bo_priv->untiled_buf_ptr, + 0); + return bo_priv->untiled_buf_ptr; + } + bo_priv->ref_count++; + return addr; } +static int amdgpu_bo_unmap(struct bo *bo, struct vma *vma) +{ + struct bo_priv_ptr *bo_priv = (struct bo_priv_ptr *)bo->priv; + struct drv_priv_ptr *drv_priv = (struct drv_priv_ptr *)bo->drv->priv; + bo_priv->ref_count--; + if (drv_priv->surf_mode >= RADEON_SURF_MODE_2D) { + if (bo_priv->untiled_buf_ptr != NULL) { + if (bo_priv->prot & PROT_WRITE) + drv_priv->dri_handle->fptr_read_write_tiled(drv_priv->addrlib_handle, + &drv_priv->surf_config, + drv_priv->surf_info, + vma->addr, + (uint8_t*)bo_priv->untiled_buf_ptr, + 1); + if (bo_priv->ref_count == 0) { + free(bo_priv->untiled_buf_ptr); + bo_priv->untiled_buf_ptr = NULL; + } + } + } + return munmap(vma->addr, vma->length); +} + static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { @@ -437,9 +469,9 @@ const struct backend backend_amdgpu = { .close = amdgpu_close, .bo_create = amdgpu_bo_create, .bo_destroy = drv_gem_bo_destroy, - .bo_import = drv_prime_bo_import, + .bo_import = amdgpu_gbm_bo_import, .bo_map = amdgpu_bo_map, - .bo_unmap = drv_bo_munmap, + .bo_unmap = amdgpu_bo_unmap, .resolve_format = amdgpu_resolve_format, }; |