* [RFC i-g-t PATCH 1/3] lib: add igt_dummyload
2016-10-12 11:59 [RFC i-g-t] Extract autotuned dummy load into lib Abdiel Janulgue
@ 2016-10-12 11:59 ` Abdiel Janulgue
2016-10-12 11:59 ` [RFC i-g-t PATCH 2/3] igt/gem_wait: Use new igt_dummyload api Abdiel Janulgue
2016-10-12 11:59 ` [RFC i-g-t PATCH 3/3] igt/kms_flip: " Abdiel Janulgue
2 siblings, 0 replies; 9+ messages in thread
From: Abdiel Janulgue @ 2016-10-12 11:59 UTC (permalink / raw)
To: intel-gfx
Generalized from auto-tuned GPU dummy workload in gem_wait and kms_flip
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
lib/Makefile.sources | 2 +
lib/igt.h | 1 +
lib/igt_dummyload.c | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/igt_dummyload.h | 63 ++++++++
4 files changed, 485 insertions(+)
create mode 100644 lib/igt_dummyload.c
create mode 100644 lib/igt_dummyload.h
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index e8e277b..7fc5ec2 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -75,6 +75,8 @@ lib_source_list = \
igt_draw.h \
igt_pm.c \
igt_pm.h \
+ igt_dummyload.c \
+ igt_dummyload.h \
uwildmat/uwildmat.h \
uwildmat/uwildmat.c \
$(NULL)
diff --git a/lib/igt.h b/lib/igt.h
index d751f24..a0028d5 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -32,6 +32,7 @@
#include "igt_core.h"
#include "igt_debugfs.h"
#include "igt_draw.h"
+#include "igt_dummyload.h"
#include "igt_fb.h"
#include "igt_gt.h"
#include "igt_kms.h"
diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
new file mode 100644
index 0000000..908d839
--- /dev/null
+++ b/lib/igt_dummyload.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "igt.h"
+#include "igt_dummyload.h"
+#include <time.h>
+
+/**
+ * SECTION:igt_dummyload
+ * @short_description: Library for submitting auto-tuned dummy GPU workloads
+ * @title: Dummyload
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some dummy load to make sure a race window is
+ * big enough. Unfortunately having a fixed amount of workload leads to
+ * spurious test failures or overtly long runtimes on some fast/slow platforms.
+ * This library contains functionality to submit GPU workloads that is
+ * dynamically tuned to consume a specific amount of time.
+ */
+
+#define USEC_PER_SEC 1000000L
+#define NSEC_PER_SEC 1000000000L
+
+/* Internal data structures to avoid having to pass tons of parameters
+ * around. */
+struct dummy_info {
+ drm_intel_bufmgr *bufmgr;
+ struct intel_batchbuffer *batch;
+ int drm_fd;
+ uint32_t buf_handle;
+ uint32_t buf_stride;
+ uint32_t buf_tiling;
+ int fb_width;
+ int fb_height;
+};
+
+static void blit_copy(struct intel_batchbuffer *batch,
+ drm_intel_bo *dst, drm_intel_bo *src,
+ unsigned int width, unsigned int height,
+ unsigned int dst_pitch, unsigned int src_pitch)
+{
+ BLIT_COPY_BATCH_START(0);
+ OUT_BATCH((3 << 24) | /* 32 bits */
+ (0xcc << 16) | /* copy ROP */
+ dst_pitch);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(height << 16 | width);
+ OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ OUT_BATCH(0 << 16 | 0);
+ OUT_BATCH(src_pitch);
+ OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0);
+ ADVANCE_BATCH();
+
+ if (batch->gen >= 6) {
+ BEGIN_BATCH(3, 0);
+ OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ }
+}
+
+static void blit_fill(struct intel_batchbuffer *batch, drm_intel_bo *dst,
+ unsigned int width, unsigned int height)
+{
+ COLOR_BLIT_COPY_BATCH_START(COLOR_BLT_WRITE_ALPHA |
+ XY_COLOR_BLT_WRITE_RGB);
+ OUT_BATCH((3 << 24) | /* 32 Bit Color */
+ (0xF0 << 16) | /* Raster OP copy background register */
+ 0); /* Dest pitch is 0 */
+ OUT_BATCH(0);
+ OUT_BATCH(width << 16 |
+ height);
+ OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ OUT_BATCH(rand()); /* random pattern */
+ ADVANCE_BATCH();
+}
+
+static int emit_dummy_load_blitcopy(struct dummy_info *d, int limit, int timeout)
+{
+ int i, ret = 0;
+ drm_intel_bo *src_bo, *dst_bo, *fb_bo;
+ struct intel_batchbuffer *batch = d->batch;
+ drm_intel_bufmgr *bufmgr = d->bufmgr;
+
+ igt_require(bufmgr);
+
+ src_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
+ igt_assert(src_bo);
+
+ dst_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
+ igt_assert(dst_bo);
+
+ fb_bo = gem_handle_to_libdrm_bo(bufmgr, d->drm_fd, "imported",
+ d->buf_handle);
+ igt_assert(fb_bo);
+
+ for (i = 0; i < limit; i++) {
+ blit_copy(batch, dst_bo, src_bo,
+ 2048, 2048,
+ 2048*4, 2048*4);
+ igt_swap(src_bo, dst_bo);
+ }
+ blit_copy(batch, fb_bo, src_bo,
+ min(d->fb_width, 2048), min(d->fb_height, 2048),
+ d->buf_stride, 2048*4);
+
+ intel_batchbuffer_flush(batch);
+
+ if (timeout > 0)
+ ret = drm_intel_gem_bo_wait(fb_bo, timeout * NSEC_PER_SEC);
+ drm_intel_bo_unreference(src_bo);
+ drm_intel_bo_unreference(dst_bo);
+ drm_intel_bo_unreference(fb_bo);
+
+ return ret;
+}
+
+static int emit_dummy_load_blitfill(struct dummy_info *d, int limit, int timeout)
+{
+ int i, ret = 0;
+ struct intel_batchbuffer *batch = d->batch;
+ drm_intel_bufmgr *bufmgr = d->bufmgr;
+ drm_intel_bo *dst_bo = gem_handle_to_libdrm_bo(bufmgr, d->drm_fd, "",
+ d->buf_handle);
+ igt_require(bufmgr);
+ igt_assert(dst_bo);
+
+ for (i = 0; i < limit; i++) {
+ blit_fill(batch, dst_bo,
+ min(d->fb_width, dst_bo->size/2),
+ min(d->fb_height, dst_bo->size/2));
+ }
+ intel_batchbuffer_flush(batch);
+
+ if (timeout > 0)
+ ret = drm_intel_gem_bo_wait(dst_bo, timeout * NSEC_PER_SEC);
+ drm_intel_bo_unreference(dst_bo);
+
+ return ret;
+}
+
+static int emit_dummy_load_rendercopy(struct dummy_info *d, int limit, int timeout)
+{
+ struct intel_batchbuffer *batch = d->batch;
+ drm_intel_bufmgr *bufmgr = d->bufmgr;
+ static uint32_t devid = 0;
+ igt_render_copyfunc_t copyfunc;
+ struct igt_buf sb[3], *src, *dst, *fb;
+ int i, ret = 0;
+
+ igt_require(bufmgr);
+
+ if (!devid)
+ devid = intel_get_drm_devid(d->drm_fd);
+ copyfunc = igt_get_render_copyfunc(devid);
+ if (copyfunc == NULL)
+ return emit_dummy_load_blitfill(d, limit, timeout);
+
+ sb[0].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
+ igt_assert(sb[0].bo);
+ sb[0].size = sb[0].bo->size;
+ sb[0].tiling = I915_TILING_NONE;
+ sb[0].data = NULL;
+ sb[0].num_tiles = sb[0].bo->size;
+ sb[0].stride = 4 * 2048;
+
+ sb[1].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
+ igt_assert(sb[1].bo);
+ sb[1].size = sb[1].bo->size;
+ sb[1].tiling = I915_TILING_NONE;
+ sb[1].data = NULL;
+ sb[1].num_tiles = sb[1].bo->size;
+ sb[1].stride = 4 * 2048;
+
+ sb[2].bo = gem_handle_to_libdrm_bo(bufmgr, d->drm_fd, "imported",
+ d->buf_handle);
+ igt_assert(sb[2].bo);
+ sb[2].size = sb[2].bo->size;
+ sb[2].tiling = d->buf_tiling;
+ sb[2].data = NULL;
+ sb[2].num_tiles = sb[2].bo->size;
+ sb[2].stride = d->buf_stride;
+
+ src = &sb[0];
+ dst = &sb[1];
+ fb = &sb[2];
+
+ for (i = 0; i < limit; i++) {
+ copyfunc(batch, NULL,
+ src, 0, 0,
+ 2048, 2048,
+ dst, 0, 0);
+
+ igt_swap(src, dst);
+ }
+ copyfunc(batch, NULL,
+ src, 0, 0,
+ min(d->fb_width, 2048), min(d->fb_height, 2048),
+ fb, 0, 0);
+ intel_batchbuffer_flush(batch);
+
+ if (timeout > 0)
+ ret = drm_intel_gem_bo_wait(fb->bo, timeout * NSEC_PER_SEC);
+ drm_intel_bo_unreference(sb[0].bo);
+ drm_intel_bo_unreference(sb[1].bo);
+ drm_intel_bo_unreference(sb[2].bo);
+
+ return ret;
+}
+
+static unsigned long gettime_us(void)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
+}
+
+static int calibrate_dummy_load(struct dummy_info *d,
+ const char *ring_name,
+ int enough_work_in_seconds,
+ int (*emit)(struct dummy_info *d, int limit, int timeout))
+{
+ unsigned long start;
+ int ops = 1;
+
+ do {
+ unsigned long diff;
+ int ret;
+ start = gettime_us();
+ ret = emit(d, ops, 10);
+ diff = gettime_us() - start;
+
+ if (ret || diff / USEC_PER_SEC > enough_work_in_seconds)
+ break;
+ ops += ops;
+ } while (ops < 100000);
+
+ igt_debug("%s dummy load calibrated: %d operations / second\n",
+ ring_name, ops);
+
+ return ops;
+}
+
+static void igt_dummy_load_blitcopy(struct dummy_info* d, int seconds)
+{
+ static int ops_per_sec = 0;
+
+ if (ops_per_sec == 0)
+ ops_per_sec = calibrate_dummy_load(d, "bcs", seconds,
+ emit_dummy_load_blitcopy);
+
+ emit_dummy_load_blitcopy(d, seconds * ops_per_sec, 0);
+}
+
+static void igt_dummy_load_blitfill(struct dummy_info* d, int seconds)
+{
+ static int ops_per_sec = 0;
+
+ if (ops_per_sec == 0)
+ ops_per_sec = calibrate_dummy_load(d, "bcs", seconds,
+ emit_dummy_load_blitfill);
+
+ emit_dummy_load_blitfill(d, seconds * ops_per_sec, 0);
+}
+
+static void igt_dummy_load_rendercopy(struct dummy_info* d, int seconds)
+{
+ static int ops_per_sec = 0;
+
+ if (ops_per_sec == 0)
+ ops_per_sec = calibrate_dummy_load(d, "rcs", seconds,
+ emit_dummy_load_rendercopy);
+
+ emit_dummy_load_rendercopy(d, seconds * ops_per_sec, 0);
+}
+
+/**
+ * igt_calibrate_dummy_load:
+ * @bufmgr: the libdrm bufmgr
+ * @batch: the batchbuffer
+ * @drm_fd: the DRM file descriptor
+ * @buf_handle: handle of the destination buffer where the operation is applied.
+ * For IGT_DUMMY_BLIT_COPY and IGT_DUMMY_RENDER_COPY this
+ * is the destination buffer where final results are copied into
+ * @buf_stride: the stride of the buffer, ignored by IGT_DUMMY_BLIT_FILL
+ * @fb_width: width of the rectangle
+ * @fb_height: height of the rectangle
+ * @enough_work_in_seconds: time it takes to execute a GPU workload
+ * @method: Type of GPU workload
+ *
+ * This function returns the amount of operations a GPU workload executes in
+ * a specific amount of time.
+ */
+int igt_calibrate_dummy_load(drm_intel_bufmgr *bufmgr,
+ struct intel_batchbuffer *batch,
+ int drm_fd,
+ uint32_t buf_handle,
+ uint32_t buf_stride,
+ int fb_width,
+ int fb_height,
+ int enough_work_in_seconds,
+ enum igt_dummy_load_method method)
+{
+ struct dummy_info dummy_info = {
+ .bufmgr = bufmgr,
+ .batch = batch,
+ .drm_fd = drm_fd,
+ .buf_handle = buf_handle,
+ .buf_stride = buf_stride,
+ .fb_width = fb_width,
+ .fb_height = fb_height,
+ };
+
+ switch (method) {
+ case IGT_DUMMY_RENDER_COPY:
+ return calibrate_dummy_load(&dummy_info, "rcs",
+ enough_work_in_seconds,
+ emit_dummy_load_rendercopy);
+ case IGT_DUMMY_BLIT_COPY:
+ return calibrate_dummy_load(&dummy_info, "bcs",
+ enough_work_in_seconds,
+ emit_dummy_load_blitcopy);
+ case IGT_DUMMY_BLIT_FILL:
+ return calibrate_dummy_load(&dummy_info, "bcs",
+ enough_work_in_seconds,
+ emit_dummy_load_blitfill);
+ default:
+ igt_assert(false);
+ }
+}
+
+/**
+ * igt_emit_dummy_load:
+ * @bufmgr: the libdrm bufmgr
+ * @batch: the batchbuffer
+ * @drm_fd: the DRM file descriptor
+ * @buf_handle: handle of the destination buffer where the operation is applied.
+ * For IGT_DUMMY_BLIT_COPY and IGT_DUMMY_RENDER_COPY this
+ * is the destination buffer where final results are copied into
+ * @buf_stride: the stride of the buffer, ignored by IGT_DUMMY_BLIT_FILL
+ * @fb_width: width of the rectangle
+ * @fb_height: height of the rectangle
+ * @iterations: manually specify the amount of operations that the dummy load
+ * executes. If less than 1, automatically determine the amount of
+ * iterations it takes to execute @enough_work_in_seconds
+ * seconds of GPU workload
+ * @enough_work_in_seconds: time it takes to execute a GPU workload. Ignored when
+ * auto-calibration is disabled (@iterations >= 1)
+ * @method: Type of GPU workload
+ *
+ * This functions submits a dummy workload to the GPU optionally auto-tuning it
+ * so the workload consumes a specific amount of time.
+ */
+void igt_emit_dummy_load(drm_intel_bufmgr *bufmgr,
+ struct intel_batchbuffer *batch,
+ int drm_fd,
+ uint32_t buf_handle,
+ uint32_t buf_stride,
+ int fb_width,
+ int fb_height,
+ int iterations,
+ int enough_work_in_seconds,
+ enum igt_dummy_load_method method)
+{
+ struct dummy_info dummy_info = {
+ .bufmgr = bufmgr,
+ .batch = batch,
+ .drm_fd = drm_fd,
+ .buf_handle = buf_handle,
+ .buf_stride = buf_stride,
+ .fb_width = fb_width,
+ .fb_height = fb_height,
+ };
+
+ switch (method) {
+ case IGT_DUMMY_RENDER_COPY:
+ iterations > 0 ? emit_dummy_load_rendercopy(&dummy_info,
+ iterations, 0):
+ igt_dummy_load_rendercopy(&dummy_info, enough_work_in_seconds);
+ break;
+ case IGT_DUMMY_BLIT_COPY:
+ iterations > 0 ? emit_dummy_load_blitcopy(&dummy_info,
+ iterations, 0):
+ igt_dummy_load_blitcopy(&dummy_info, enough_work_in_seconds);
+ break;
+ case IGT_DUMMY_BLIT_FILL:
+ iterations > 0 ? emit_dummy_load_blitfill(&dummy_info,
+ iterations, 0):
+ igt_dummy_load_blitfill(&dummy_info, enough_work_in_seconds);
+ break;
+ default:
+ igt_assert(false);
+ break;
+ }
+}
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
new file mode 100644
index 0000000..9e40fd1
--- /dev/null
+++ b/lib/igt_dummyload.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __IGT_DUMMYLOAD_H__
+#define __IGT_DUMMYLOAD_H__
+
+/**
+ * igt_dummy_load_method:
+ * @IGT_DUMMY_BLIT_FILL: Use blitter engine to fill a buffer with random color
+ * @IGT_DUMMY_BLIT_COPY: Use blitter engine to copy between buffers
+ * @IGT_DUMMY_RENDER_COPY: Use render engine to copy between buffers
+ *
+ * Method to generate a GPU dummy load
+ */
+enum igt_dummy_load_method {
+ IGT_DUMMY_BLIT_FILL,
+ IGT_DUMMY_BLIT_COPY,
+ IGT_DUMMY_RENDER_COPY,
+};
+
+int igt_calibrate_dummy_load(drm_intel_bufmgr *bufmgr,
+ struct intel_batchbuffer *batch,
+ int drm_fd,
+ uint32_t buf_handle,
+ uint32_t buf_stride,
+ int fb_width,
+ int fb_height,
+ int enough_work_in_seconds,
+ enum igt_dummy_load_method method);
+
+void igt_emit_dummy_load(drm_intel_bufmgr *bufmgr,
+ struct intel_batchbuffer *batch,
+ int drm_fd,
+ uint32_t buf_handle,
+ uint32_t buf_stride,
+ int fb_width,
+ int fb_height,
+ int iterations,
+ int enough_work_in_seconds,
+ enum igt_dummy_load_method method);
+
+#endif /* __IGT_DUMMYLOAD_H__ */
--
2.7.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC i-g-t PATCH 2/3] igt/gem_wait: Use new igt_dummyload api
2016-10-12 11:59 [RFC i-g-t] Extract autotuned dummy load into lib Abdiel Janulgue
2016-10-12 11:59 ` [RFC i-g-t PATCH 1/3] lib: add igt_dummyload Abdiel Janulgue
@ 2016-10-12 11:59 ` Abdiel Janulgue
2016-10-12 12:07 ` Chris Wilson
2016-10-12 11:59 ` [RFC i-g-t PATCH 3/3] igt/kms_flip: " Abdiel Janulgue
2 siblings, 1 reply; 9+ messages in thread
From: Abdiel Janulgue @ 2016-10-12 11:59 UTC (permalink / raw)
To: intel-gfx
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
tests/gem_wait.c | 77 +++++++++-----------------------------------------------
1 file changed, 12 insertions(+), 65 deletions(-)
diff --git a/tests/gem_wait.c b/tests/gem_wait.c
index 461efdb..24a5f5e 100644
--- a/tests/gem_wait.c
+++ b/tests/gem_wait.c
@@ -54,36 +54,6 @@
#define BUF_PAGES ((8<<20)>>12)
drm_intel_bo *dst, *dst2;
-/* returns time diff in milliseconds */
-static int64_t
-do_time_diff(struct timespec *end, struct timespec *start)
-{
- int64_t ret;
- ret = (MSEC_PER_SEC * difftime(end->tv_sec, start->tv_sec)) +
- ((end->tv_nsec/NSEC_PER_MSEC) - (start->tv_nsec/NSEC_PER_MSEC));
- return ret;
-}
-
-static void blt_color_fill(struct intel_batchbuffer *batch,
- drm_intel_bo *buf,
- const unsigned int pages)
-{
- const unsigned short height = pages/4;
- const unsigned short width = 4096;
-
- COLOR_BLIT_COPY_BATCH_START(COLOR_BLT_WRITE_ALPHA |
- XY_COLOR_BLT_WRITE_RGB);
- OUT_BATCH((3 << 24) | /* 32 Bit Color */
- (0xF0 << 16) | /* Raster OP copy background register */
- 0); /* Dest pitch is 0 */
- OUT_BATCH(0);
- OUT_BATCH(width << 16 |
- height);
- OUT_RELOC_FENCED(buf, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
- OUT_BATCH(rand()); /* random pattern */
- ADVANCE_BATCH();
-}
-
static void render_timeout(int fd)
{
drm_intel_bufmgr *bufmgr;
@@ -91,10 +61,11 @@ static void render_timeout(int fd)
int64_t timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC;
int64_t negative_timeout = -1;
int ret;
+ const unsigned short height = BUF_PAGES/4;
+ const unsigned short width = 4096;
const bool do_signals = true; /* signals will seem to make the operation
* use less process CPU time */
- bool done = false;
- int i, iter = 1;
+ int iter = 1;
igt_skip_on_simulation();
@@ -112,30 +83,9 @@ static void render_timeout(int fd)
/* Figure out a rough number of fills required to consume 1 second of
* GPU work.
*/
- do {
- struct timespec start, end;
- long diff;
-
-#ifndef CLOCK_MONOTONIC_RAW
-#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
-#endif
-
- igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &start) == 0);
- for (i = 0; i < iter; i++)
- blt_color_fill(batch, dst, BUF_PAGES);
- intel_batchbuffer_flush(batch);
- drm_intel_bo_wait_rendering(dst);
- igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &end) == 0);
-
- diff = do_time_diff(&end, &start);
- igt_assert(diff >= 0);
-
- if ((diff / MSEC_PER_SEC) > ENOUGH_WORK_IN_SECONDS)
- done = true;
- else
- iter <<= 1;
- } while (!done && iter < 1000000);
-
+ iter = igt_calibrate_dummy_load(bufmgr, batch, fd,
+ dst->handle, 0,
+ width, height, 1, IGT_DUMMY_BLIT_FILL);
igt_assert_lt(iter, 1000000);
igt_debug("%d iters is enough work\n", iter);
@@ -146,10 +96,9 @@ static void render_timeout(int fd)
/* We should be able to do half as much work in the same amount of time,
* but because we might schedule almost twice as much as required, we
* might accidentally time out. Hence add some fudge. */
- for (i = 0; i < iter/3; i++)
- blt_color_fill(batch, dst2, BUF_PAGES);
- intel_batchbuffer_flush(batch);
+ igt_emit_dummy_load(bufmgr, batch, fd, dst2->handle, 0,
+ width, height, iter/3, 0, IGT_DUMMY_BLIT_FILL);
igt_assert(gem_bo_busy(fd, dst2->handle) == true);
igt_assert_eq(gem_wait(fd, dst2->handle, &timeout), 0);
@@ -168,10 +117,9 @@ static void render_timeout(int fd)
/* Now check that we correctly time out, twice the auto-tune load should
* be good enough. */
timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC;
- for (i = 0; i < iter*2; i++)
- blt_color_fill(batch, dst2, BUF_PAGES);
- intel_batchbuffer_flush(batch);
+ igt_emit_dummy_load(bufmgr, batch, fd, dst2->handle, 0,
+ width, height, iter*2, 0, IGT_DUMMY_BLIT_FILL);
ret = gem_wait(fd, dst2->handle, &timeout);
igt_assert_eq(ret, -ETIME);
@@ -186,10 +134,9 @@ static void render_timeout(int fd)
/* Now check that we can pass negative (infinite) timeouts. */
negative_timeout = -1;
- for (i = 0; i < iter; i++)
- blt_color_fill(batch, dst2, BUF_PAGES);
- intel_batchbuffer_flush(batch);
+ igt_emit_dummy_load(bufmgr, batch, fd, dst2->handle, 0,
+ width, height, iter, 0, IGT_DUMMY_BLIT_FILL);
igt_assert_eq(gem_wait(fd, dst2->handle, &negative_timeout), 0);
igt_assert_eq(negative_timeout, -1); /* infinity always remains */
--
2.7.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread* [RFC i-g-t PATCH 3/3] igt/kms_flip: Use new igt_dummyload api
2016-10-12 11:59 [RFC i-g-t] Extract autotuned dummy load into lib Abdiel Janulgue
2016-10-12 11:59 ` [RFC i-g-t PATCH 1/3] lib: add igt_dummyload Abdiel Janulgue
2016-10-12 11:59 ` [RFC i-g-t PATCH 2/3] igt/gem_wait: Use new igt_dummyload api Abdiel Janulgue
@ 2016-10-12 11:59 ` Abdiel Janulgue
2 siblings, 0 replies; 9+ messages in thread
From: Abdiel Janulgue @ 2016-10-12 11:59 UTC (permalink / raw)
To: intel-gfx
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
---
tests/kms_flip.c | 191 +++----------------------------------------------------
1 file changed, 10 insertions(+), 181 deletions(-)
diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index 065ad66..93cf391 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -187,109 +187,6 @@ static unsigned long gettime_us(void)
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
-static int calibrate_dummy_load(struct test_output *o,
- const char *ring_name,
- int (*emit)(struct test_output *o, int limit, int timeout))
-{
- unsigned long start;
- int ops = 1;
-
- start = gettime_us();
-
- do {
- unsigned long diff;
- int ret;
-
- ret = emit(o, (ops+1)/2, 10);
- diff = gettime_us() - start;
-
- if (ret || diff / USEC_PER_SEC >= 1)
- break;
-
- ops += ops;
- } while (ops < 100000);
-
- igt_debug("%s dummy load calibrated: %d operations / second\n",
- ring_name, ops);
-
- return ops;
-}
-
-static void blit_copy(drm_intel_bo *dst, drm_intel_bo *src,
- unsigned int width, unsigned int height,
- unsigned int dst_pitch, unsigned int src_pitch)
-{
- BLIT_COPY_BATCH_START(0);
- OUT_BATCH((3 << 24) | /* 32 bits */
- (0xcc << 16) | /* copy ROP */
- dst_pitch);
- OUT_BATCH(0 << 16 | 0);
- OUT_BATCH(height << 16 | width);
- OUT_RELOC_FENCED(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
- OUT_BATCH(0 << 16 | 0);
- OUT_BATCH(src_pitch);
- OUT_RELOC_FENCED(src, I915_GEM_DOMAIN_RENDER, 0, 0);
- ADVANCE_BATCH();
-
- if (batch->gen >= 6) {
- BEGIN_BATCH(3, 0);
- OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
- OUT_BATCH(0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
- }
-}
-
-static int _emit_dummy_load__bcs(struct test_output *o, int limit, int timeout)
-{
- int i, ret = 0;
- drm_intel_bo *src_bo, *dst_bo, *fb_bo;
- struct igt_fb *fb_info = &o->fb_info[o->current_fb_id];
-
- igt_require(bufmgr);
-
- src_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(src_bo);
-
- dst_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(dst_bo);
-
- fb_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
- igt_assert(fb_bo);
-
- for (i = 0; i < limit; i++) {
- blit_copy(dst_bo, src_bo,
- 2048, 2048,
- 2048*4, 2048*4);
-
- igt_swap(src_bo, dst_bo);
- }
- blit_copy(fb_bo, src_bo,
- min(o->fb_width, 2048), min(o->fb_height, 2048),
- fb_info->stride, 2048*4);
- intel_batchbuffer_flush(batch);
-
- if (timeout > 0)
- ret = drm_intel_gem_bo_wait(fb_bo, timeout * NSEC_PER_SEC);
-
- drm_intel_bo_unreference(src_bo);
- drm_intel_bo_unreference(dst_bo);
- drm_intel_bo_unreference(fb_bo);
-
- return ret;
-}
-
-static void emit_dummy_load__bcs(struct test_output *o, int seconds)
-{
- static int ops_per_sec;
-
- if (ops_per_sec == 0)
- ops_per_sec = calibrate_dummy_load(o, "bcs",
- _emit_dummy_load__bcs);
-
- _emit_dummy_load__bcs(o, seconds * ops_per_sec, 0);
-}
-
static void emit_fence_stress(struct test_output *o)
{
const int num_fences = gem_available_fences(drm_fd);
@@ -334,82 +231,6 @@ static void emit_fence_stress(struct test_output *o)
free(exec);
}
-static int _emit_dummy_load__rcs(struct test_output *o, int limit, int timeout)
-{
- const struct igt_fb *fb_info = &o->fb_info[o->current_fb_id];
- igt_render_copyfunc_t copyfunc;
- struct igt_buf sb[3], *src, *dst, *fb;
- int i, ret = 0;
-
- igt_require(bufmgr);
-
- copyfunc = igt_get_render_copyfunc(devid);
- if (copyfunc == NULL)
- return _emit_dummy_load__bcs(o, limit, timeout);
-
- sb[0].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(sb[0].bo);
- sb[0].size = sb[0].bo->size;
- sb[0].tiling = I915_TILING_NONE;
- sb[0].data = NULL;
- sb[0].num_tiles = sb[0].bo->size;
- sb[0].stride = 4 * 2048;
-
- sb[1].bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", 2048*2048*4, 4096);
- igt_assert(sb[1].bo);
- sb[1].size = sb[1].bo->size;
- sb[1].tiling = I915_TILING_NONE;
- sb[1].data = NULL;
- sb[1].num_tiles = sb[1].bo->size;
- sb[1].stride = 4 * 2048;
-
- sb[2].bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
- igt_assert(sb[2].bo);
- sb[2].size = sb[2].bo->size;
- sb[2].tiling = fb_info->tiling;
- sb[2].data = NULL;
- sb[2].num_tiles = sb[2].bo->size;
- sb[2].stride = fb_info->stride;
-
- src = &sb[0];
- dst = &sb[1];
- fb = &sb[2];
-
- for (i = 0; i < limit; i++) {
- copyfunc(batch, NULL,
- src, 0, 0,
- 2048, 2048,
- dst, 0, 0);
-
- igt_swap(src, dst);
- }
- copyfunc(batch, NULL,
- src, 0, 0,
- min(o->fb_width, 2048), min(o->fb_height, 2048),
- fb, 0, 0);
- intel_batchbuffer_flush(batch);
-
- if (timeout > 0)
- ret = drm_intel_gem_bo_wait(fb->bo, timeout * NSEC_PER_SEC);
-
- drm_intel_bo_unreference(sb[0].bo);
- drm_intel_bo_unreference(sb[1].bo);
- drm_intel_bo_unreference(sb[2].bo);
-
- return ret;
-}
-
-static void emit_dummy_load__rcs(struct test_output *o, int seconds)
-{
- static int ops_per_sec;
-
- if (ops_per_sec == 0)
- ops_per_sec = calibrate_dummy_load(o, "rcs",
- _emit_dummy_load__rcs);
-
- _emit_dummy_load__bcs(o, seconds * ops_per_sec, 0);
-}
-
static void dpms_off_other_outputs(struct test_output *o)
{
int i, n;
@@ -865,10 +686,18 @@ static unsigned int run_test_step(struct test_output *o)
o->current_fb_id = !o->current_fb_id;
if (o->flags & TEST_WITH_DUMMY_BCS)
- emit_dummy_load__bcs(o, 1);
+ igt_emit_dummy_load(bufmgr, batch, drm_fd,
+ o->fb_info[o->current_fb_id].gem_handle,
+ o->fb_info[o->current_fb_id].stride,
+ o->fb_width, o->fb_height, 0, 1,
+ IGT_DUMMY_BLIT_COPY);
if (o->flags & TEST_WITH_DUMMY_RCS)
- emit_dummy_load__rcs(o, 1);
+ igt_emit_dummy_load(bufmgr, batch, drm_fd,
+ o->fb_info[o->current_fb_id].gem_handle,
+ o->fb_info[o->current_fb_id].stride,
+ o->fb_width, o->fb_height, 0, 1,
+ IGT_DUMMY_RENDER_COPY);
if (o->flags & TEST_FB_RECREATE)
recreate_fb(o);
--
2.7.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread