Add blttest_gc7000
Extremely simple test that tests copying of buffers with the BLT and
validates the result.
Signed-off-by: Wladimir J. van der Laan <laanwj@gmail.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 92f14ce..a9c3a29 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,8 @@
etnaviv_cl_bench \
etnaviv_triangle_gc3000 \
etnaviv_cube_gc7000 \
- etnaviv_bltdemo_gc7000
+ etnaviv_bltdemo_gc7000 \
+ etnaviv_blttest_gc7000
EXTRA_LIBRARIES = libshared.a
@@ -38,3 +39,7 @@
etnaviv_bltdemo_gc7000_SOURCES = bltdemo_gc7000.c
etnaviv_bltdemo_gc7000_LDADD = libshared.a $(LIBDRM_LIBS) $(LIBDRM_ETNAVIV_LIBS)
etnaviv_bltdemo_gc7000_CFLAGS = $(LIBDRM_CFLAGS) $(LIBDRM_ETNAVIV_CFLAGS)
+
+etnaviv_blttest_gc7000_SOURCES = blttest_gc7000.c
+etnaviv_blttest_gc7000_LDADD = libshared.a $(LIBDRM_LIBS) $(LIBDRM_ETNAVIV_LIBS)
+etnaviv_blttest_gc7000_CFLAGS = $(LIBDRM_CFLAGS) $(LIBDRM_ETNAVIV_CFLAGS)
diff --git a/src/blttest_gc7000.c b/src/blttest_gc7000.c
new file mode 100644
index 0000000..4b475a5
--- /dev/null
+++ b/src/blttest_gc7000.c
@@ -0,0 +1,186 @@
+#define _POSIX_C_SOURCE 200112L
+#define _XOPEN_SOURCE 500
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "write_bmp.h"
+#include "memutil.h"
+
+#include "drm_setup.h"
+#include "cmdstream.h"
+#include "etna_util.h"
+
+#include <state.xml.h>
+#include <state_3d.xml.h>
+#include <state_blt.xml.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+
+struct test_info {
+ struct etna_bo *bo_data;
+
+ uint32_t ts_clear_value[2];
+};
+
+static void init_reloc(struct etna_reloc *reloc, struct etna_bo *bo, uint32_t offset, uint32_t flags)
+{
+ reloc->bo = bo;
+ reloc->offset = offset;
+ reloc->flags = flags;
+}
+
+#define DATA_SIZE (0x7f8000)
+
+struct test_info *test_init(struct etna_device *conn)
+{
+ struct test_info *info = CALLOC_STRUCT(test_info);
+
+ /* Allocate bos */
+ info->bo_data = etna_bo_new(conn, DATA_SIZE, DRM_ETNA_GEM_CACHE_WC);
+ assert(info->bo_data);
+
+ etna_bo_cpu_prep(info->bo_data, DRM_ETNA_PREP_WRITE);
+ memset(etna_bo_map(info->bo_data), 0, DATA_SIZE);
+ etna_bo_cpu_fini(info->bo_data);
+
+ return info;
+}
+
+void test_free(struct etna_device *conn, struct test_info *info)
+{
+ etna_bo_del(info->bo_data);
+ free(info);
+}
+
+void emit_blt_copybuffer(struct etna_cmd_stream *stream, struct etna_reloc *dest, struct etna_reloc *src, uint32_t size)
+{
+ etna_cmd_stream_reserve(stream, 64*2); /* Make sure BLT op doesn't get broken up */
+
+ etna_set_state(stream, VIVS_BLT_ENABLE, 0x00000001);
+ etna_set_state_reloc(stream, VIVS_BLT_SRC_ADDR, src);
+ etna_set_state_reloc(stream, VIVS_BLT_DEST_ADDR, dest);
+ etna_set_state(stream, VIVS_BLT_BUFFER_SIZE, size);
+ etna_set_state(stream, VIVS_BLT_SET_COMMAND, 0x00000003);
+ etna_set_state(stream, VIVS_BLT_COMMAND, VIVS_BLT_COMMAND_COMMAND_COPY_BUFFER);
+ etna_set_state(stream, VIVS_BLT_SET_COMMAND, 0x00000003);
+ etna_set_state(stream, VIVS_BLT_ENABLE, 0x00000000);
+
+ /* Synchronize FE with BLT, because we want to see result after finishing command buffer */
+ etna_set_state(stream, VIVS_BLT_ENABLE, 0x00000001);
+ etna_set_state(stream, VIVS_GL_SEMAPHORE_TOKEN, 0x30001001);
+ etna_cmd_stream_emit(stream, 0x48000000); /* command STALL (9) OP=STALL */
+ etna_cmd_stream_emit(stream, 0x30001001); /* command TOKEN FROM=FE,TO=BLT,UNK28=0x3 */
+ etna_set_state(stream, VIVS_BLT_ENABLE, 0x00000000);
+}
+
+int main(int argc, char **argv)
+{
+ struct drm_test_info *info;
+ uint64_t val;
+
+ if ((info = drm_test_setup(argc, argv)) == NULL) {
+ return 1;
+ }
+ if (etna_gpu_get_param(info->gpu, ETNA_GPU_MODEL, &val)) {
+ fprintf(stderr, "Could not get GPU model\n");
+ goto error;
+ }
+ if (val != 0x7000) {
+ fprintf(stderr, "This only runs on GC7000\n");
+ goto error;
+ }
+
+ struct test_info *tinfo = test_init(info->dev);
+ assert(tinfo);
+
+ uint8_t *data = etna_bo_map(tinfo->bo_data);
+ const char testdata[] = "Testing buffer copy *~*~*~*~*~*~~*~**~";
+ const size_t testdata_size = sizeof(testdata);
+
+ /***********************************/
+ printf("Test aligned copy "); fflush(stdout);
+ etna_bo_cpu_prep(tinfo->bo_data, DRM_ETNA_PREP_WRITE);
+ memcpy(data, testdata, testdata_size);
+ etna_bo_cpu_fini(tinfo->bo_data);
+
+ struct etna_reloc src, dest;
+ init_reloc(&src, tinfo->bo_data, 0, ETNA_RELOC_READ);
+ init_reloc(&dest, tinfo->bo_data, 0x200, ETNA_RELOC_WRITE);
+ emit_blt_copybuffer(info->stream, &dest, &src, testdata_size);
+
+ etna_cmd_stream_finish(info->stream);
+
+ etna_bo_cpu_prep(tinfo->bo_data, DRM_ETNA_PREP_READ);
+ if (memcmp(&data[0x200], testdata, testdata_size) == 0) {
+ printf("OK\n");
+ } else {
+ printf("FAIL\n");
+ }
+ etna_bo_cpu_fini(tinfo->bo_data);
+
+ /***********************************/
+ printf("Test unaligned desination "); fflush(stdout);
+
+ init_reloc(&src, tinfo->bo_data, 0, ETNA_RELOC_READ);
+ init_reloc(&dest, tinfo->bo_data, 0x213, ETNA_RELOC_WRITE);
+ emit_blt_copybuffer(info->stream, &dest, &src, testdata_size);
+
+ etna_cmd_stream_finish(info->stream);
+
+ etna_bo_cpu_prep(tinfo->bo_data, DRM_ETNA_PREP_READ);
+ if (memcmp(&data[0x213], testdata, testdata_size) == 0) {
+ printf("OK\n");
+ } else {
+ printf("FAIL\n");
+ }
+ etna_bo_cpu_fini(tinfo->bo_data);
+
+ /***********************************/
+ printf("Test unaligned source "); fflush(stdout);
+
+ init_reloc(&src, tinfo->bo_data, 0x213, ETNA_RELOC_READ);
+ init_reloc(&dest, tinfo->bo_data, 0x400, ETNA_RELOC_WRITE);
+ emit_blt_copybuffer(info->stream, &dest, &src, testdata_size);
+
+ etna_cmd_stream_finish(info->stream);
+
+ etna_bo_cpu_prep(tinfo->bo_data, DRM_ETNA_PREP_READ);
+ if (memcmp(&data[0x400], testdata, testdata_size) == 0) {
+ printf("OK\n");
+ } else {
+ printf("FAIL\n");
+ }
+ etna_bo_cpu_fini(tinfo->bo_data);
+
+ /***********************************/
+ printf("Test unaligned source and destination "); fflush(stdout);
+
+ init_reloc(&src, tinfo->bo_data, 0x213, ETNA_RELOC_READ);
+ init_reloc(&dest, tinfo->bo_data, 0x413, ETNA_RELOC_WRITE);
+ emit_blt_copybuffer(info->stream, &dest, &src, testdata_size);
+
+ etna_cmd_stream_finish(info->stream);
+
+ etna_bo_cpu_prep(tinfo->bo_data, DRM_ETNA_PREP_READ);
+ if (memcmp(&data[0x413], testdata, testdata_size) == 0) {
+ printf("OK\n");
+ } else {
+ printf("FAIL\n");
+ }
+ etna_bo_cpu_fini(tinfo->bo_data);
+
+ test_free(info->dev, tinfo);
+
+ drm_test_teardown(info);
+ return 0;
+error:
+ drm_test_teardown(info);
+ return 1;
+}
+