[Mesa-dev] [PATCH v2] radeonsi: Adding tiled to linear conversion functionality

Satyajit Sahu satyajit.sahu at amd.com
Fri Nov 24 05:22:06 UTC 2017


Add tiled to linear conversion and expose outside mesa. This function converts
tiled image to linear and vice versa.
One of the use-case is, a chromiumos test case where the captured fb is
compared against a reference image. As the fb is tiled mode it needs to
be converted before comparision.

Also exposing create, compute and destroy surface functions outside. These
functions are also used when accessing addrlib outside of mesa.

Signed-off-by: Satyajit Sahu <satyajit.sahu at amd.com>
---
 src/amd/Makefile.common.am          |   4 ++
 src/amd/common/ac_gpu_info.c        |   2 +
 src/amd/common/ac_surface.c         | 102 ++++++++++++++++++++++++++++++++++++
 src/amd/common/ac_surface.h         |   9 ++++
 src/gallium/targets/dri/Makefile.am |   1 +
 src/gallium/targets/dri/dri.sym     |   5 ++
 6 files changed, 123 insertions(+)

diff --git a/src/amd/Makefile.common.am b/src/amd/Makefile.common.am
index d62e9d4..651b3c7 100644
--- a/src/amd/Makefile.common.am
+++ b/src/amd/Makefile.common.am
@@ -53,6 +53,10 @@ common_libamd_common_la_CXXFLAGS = \
 	$(LLVM_CXXFLAGS)
 
 noinst_LTLIBRARIES += $(COMMON_LIBS)
+include_HEADERS = $(top_srcdir)/src/amd/common/ac_surface.h \
+		$(top_srcdir)/src/amd/common/ac_gpu_info.h \
+		$(top_srcdir)/src/amd/common/amd_family.h
+
 
 common_libamd_common_la_SOURCES = \
 	$(AMD_COMMON_FILES) \
diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c
index 6e34a07..bb4f03f 100644
--- a/src/amd/common/ac_gpu_info.c
+++ b/src/amd/common/ac_gpu_info.c
@@ -28,6 +28,7 @@
 #include "gfx9d.h"
 
 #include "util/u_math.h"
+#include "util/macros.h"
 
 #include <stdio.h>
 
@@ -92,6 +93,7 @@ static bool has_syncobj(int fd)
 	return value ? true : false;
 }
 
+PUBLIC
 bool ac_query_gpu_info(int fd, amdgpu_device_handle dev,
 		       struct radeon_info *info,
 		       struct amdgpu_gpu_info *amdinfo)
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index f7600a3..67bf28a 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -155,6 +155,7 @@ static ADDR_E_RETURNCODE ADDR_API freeSysMem(const ADDR_FREESYSMEM_INPUT * pInpu
 	return ADDR_OK;
 }
 
+PUBLIC
 ADDR_HANDLE amdgpu_addr_create(const struct radeon_info *info,
 			       const struct amdgpu_gpu_info *amdinfo,
 			       uint64_t *max_alignment)
@@ -219,6 +220,15 @@ ADDR_HANDLE amdgpu_addr_create(const struct radeon_info *info,
 	return addrCreateOutput.hLib;
 }
 
+PUBLIC
+int amdgpu_addr_destroy(ADDR_HANDLE handle) {
+       ADDR_E_RETURNCODE ret = AddrDestroy(handle);
+       if(ret = ADDR_OK)
+               return 0;
+       else
+               return -((int)ret);
+}
+
 static int surf_config_sanity(const struct ac_surf_config *config)
 {
 	/* all dimension must be at least 1 ! */
@@ -1246,6 +1256,7 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 	return 0;
 }
 
+PUBLIC
 int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info,
 		       const struct ac_surf_config *config,
 		       enum radeon_surf_mode mode,
@@ -1262,3 +1273,94 @@ int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info,
 	else
 		return gfx6_compute_surface(addrlib, info, config, mode, surf);
 }
+
+PUBLIC
+int ac_read_write_tiled_data(ADDR_HANDLE addrlib,
+			  struct ac_surf_config * config,
+                          struct radeon_surf * surf,
+                          void * addr, uint8_t * linear_ptr,
+                          bool write_to_tiled_buf) {
+	ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT in_param = { 0 };
+	ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT out_param;
+	const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT *in_param_ptr = &in_param;
+	ADDR_TILEINFO tile_info = {0};
+	ADDR_E_RETURNCODE ret = ADDR_OK;
+	uint8_t *tiled_ptr;
+
+	if (!addr || !linear_ptr)
+		return -EINVAL;
+	out_param.size = sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT);
+	in_param.size = sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT);
+	tile_info.banks = surf->u.legacy.num_banks;
+	tile_info.bankWidth = surf->u.legacy.bankw;
+	tile_info.bankHeight = surf->u.legacy.bankh;
+	tile_info.macroAspectRatio = surf->u.legacy.mtilea;
+	tile_info.tileSplitBytes = surf->u.legacy.tile_split;
+	tile_info.pipeConfig = surf->u.legacy.pipe_config;
+	/* bpp in bytes */
+	in_param.bpp = surf->bpe << 3;
+	in_param.pitch = surf->u.legacy.level[0].nblk_x;
+	in_param.height = surf->u.legacy.level[0].nblk_y;
+	in_param.numSlices = config->info.depth;
+	in_param.numSamples = config->info.samples;
+        switch (surf->u.legacy.level[0].mode) {
+	        case RADEON_SURF_MODE_LINEAR_ALIGNED:
+			in_param.tileMode = ADDR_TM_LINEAR_ALIGNED;
+		        break;
+		case RADEON_SURF_MODE_1D:
+		        in_param.tileMode = ADDR_TM_1D_TILED_THIN1;
+		        break;
+		case RADEON_SURF_MODE_2D:
+			in_param.tileMode = ADDR_TM_2D_TILED_THIN1;
+			tile_info.pipeConfig = surf->u.legacy.pipe_config + 1;
+			break;
+		default:
+			return -EINVAL;
+	}
+	if (surf->flags & RADEON_SURF_SCANOUT)
+		in_param.tileType = ADDR_DISPLAYABLE;
+	else if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_FMASK))
+		in_param.tileType = ADDR_DEPTH_SAMPLE_ORDER;
+	else
+		in_param.tileType = ADDR_NON_DISPLAYABLE;
+	in_param.pTileInfo = &tile_info;
+	in_param.tileIndex = -1;
+	if (write_to_tiled_buf)	{
+		for (uint32_t j = 0; j < in_param.height; j++) {
+			for (uint32_t i = 0; i < in_param.pitch; i++) {
+				in_param.x = i;
+				in_param.y = j;
+				ret = AddrComputeSurfaceAddrFromCoord(addrlib, in_param_ptr, &out_param);
+				if (ADDR_OK == ret) {
+					/* get the pixel data ptr by adding the offset returned */
+					tiled_ptr = ((uint8_t *)addr) + out_param.addr;
+					if (tiled_ptr != NULL) {
+						memcpy(tiled_ptr, linear_ptr, (in_param.bpp >> 3));
+						linear_ptr += in_param.bpp >> 3;
+					}
+				} else {
+					return -((int)ret);
+				}
+			}
+		}
+	} else {
+		for (uint32_t j = 0; j < in_param.height; j++) {
+			for (uint32_t i = 0; i < in_param.pitch; i++) {
+				in_param.x = i;
+				in_param.y = j;
+				ret = AddrComputeSurfaceAddrFromCoord(addrlib, in_param_ptr, &out_param);
+				if (ADDR_OK == ret) {
+					/* get the pixel data ptr by adding the offset returned */
+					tiled_ptr = ((uint8_t *)addr) + out_param.addr;
+					if (tiled_ptr != NULL) {
+						memcpy(linear_ptr, tiled_ptr, (in_param.bpp >> 3));
+						linear_ptr += in_param.bpp >> 3;
+					}
+				} else {
+					return -((int)ret);
+				}
+			}
+		}
+	}
+	return 0;
+}
diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
index 7ac4737..61b094f 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -26,6 +26,7 @@
 #ifndef AC_SURFACE_H
 #define AC_SURFACE_H
 
+#include <stdbool.h>
 #include <stdint.h>
 
 #include "amd_family.h"
@@ -229,11 +230,19 @@ ADDR_HANDLE amdgpu_addr_create(const struct radeon_info *info,
 			       const struct amdgpu_gpu_info *amdinfo,
 			       uint64_t *max_alignment);
 
+int amdgpu_addr_destroy(ADDR_HANDLE handle);
+
 int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info,
 		       const struct ac_surf_config * config,
 		       enum radeon_surf_mode mode,
 		       struct radeon_surf *surf);
 
+int ac_read_write_tiled_data(ADDR_HANDLE addrlib,
+			  struct ac_surf_config * config,
+			  struct radeon_surf * surf,
+			  void * addr, uint8_t * linear_ptr,
+			  bool write_to_tiled_buf);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gallium/targets/dri/Makefile.am b/src/gallium/targets/dri/Makefile.am
index c54f7a6..681a7cf 100644
--- a/src/gallium/targets/dri/Makefile.am
+++ b/src/gallium/targets/dri/Makefile.am
@@ -27,6 +27,7 @@ gallium_dri_la_LDFLAGS = \
 	-module \
 	-no-undefined \
 	-avoid-version \
+	-Wl, --allow-multiple-definition \
 	$(GC_SECTIONS) \
 	$(LD_NO_UNDEFINED)
 
diff --git a/src/gallium/targets/dri/dri.sym b/src/gallium/targets/dri/dri.sym
index 1fdf18b..18a5f4b 100644
--- a/src/gallium/targets/dri/dri.sym
+++ b/src/gallium/targets/dri/dri.sym
@@ -4,6 +4,11 @@
 		__driDriverGetExtensions*;
 		nouveau_drm_screen_create;
 		radeon_drm_winsys_create;
+		ac_compute_surface;
+		ac_query_gpu_info;
+		ac_read_write_tiled_data;
+		amdgpu_addr_create;
+		amdgpu_addr_destroy;
 		amdgpu_winsys_create;
 		fd_drm_screen_create;
 	local:
-- 
1.9.1



More information about the mesa-dev mailing list