blob: da3512c244e325c077ab17003ff9d7570f0a9531 [file] [log] [blame]
Alyssa Rosenzweigfd186952020-03-24 13:24:03 -04001/*
2 * Copyright (C) 2020 Collabora Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
25 */
26
27#include "bit.h"
Alyssa Rosenzweig1c62b552020-08-05 16:16:00 -040028#include "panfrost/lib/decode.h"
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040029#include "drm-uapi/panfrost_drm.h"
Alyssa Rosenzweigd62a6e72020-08-05 16:25:52 -040030#include "panfrost/lib/pan_encoder.h"
Alyssa Rosenzweigfd186952020-03-24 13:24:03 -040031
32/* Standalone compiler tests submitting jobs directly to the hardware. Uses the
33 * `bit` prefix for `BIfrost Tests` and because bit sounds wicked cool. */
34
35static struct panfrost_bo *
36bit_bo_create(struct panfrost_device *dev, size_t size)
37{
38 struct panfrost_bo *bo = panfrost_bo_create(dev, size, PAN_BO_EXECUTE);
39 pandecode_inject_mmap(bo->gpu, bo->cpu, bo->size, NULL);
40 return bo;
41}
Alyssa Rosenzweigbf1929e2020-03-24 13:48:06 -040042
43struct panfrost_device *
44bit_initialize(void *memctx)
45{
46 int fd = drmOpenWithType("panfrost", NULL, DRM_NODE_RENDER);
47
48 if (fd < 0)
49 unreachable("No panfrost device found. Try chmod?");
50
51 struct panfrost_device *dev = rzalloc(memctx, struct panfrost_device);
52 panfrost_open_device(memctx, fd, dev);
53
54 pandecode_initialize(true);
55 printf("%X\n", dev->gpu_id);
56
57 return dev;
58}
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040059
60static bool
61bit_submit(struct panfrost_device *dev,
62 enum mali_job_type T,
63 void *payload, size_t payload_size,
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -040064 struct panfrost_bo **bos, size_t bo_count, enum bit_debug debug)
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040065{
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040066 struct panfrost_bo *job = bit_bo_create(dev, 4096);
Boris Brezilloneb923542020-09-08 07:07:41 +020067 pan_pack(job->cpu, JOB_HEADER, cfg) {
68 cfg.type = T;
69 cfg.index = 1;
70 }
71 memcpy(job->cpu + MALI_JOB_HEADER_LENGTH, payload, payload_size);
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040072
73 uint32_t *bo_handles = calloc(sizeof(uint32_t), bo_count);
74
75 for (unsigned i = 0; i < bo_count; ++i)
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -040076 bo_handles[i] = bos[i]->gem_handle;
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040077
78 uint32_t syncobj = 0;
79 int ret = 0;
80
81 ret = drmSyncobjCreate(dev->fd, DRM_SYNCOBJ_CREATE_SIGNALED, &syncobj);
82 assert(!ret);
83
84 struct drm_panfrost_submit submit = {
85 .jc = job->gpu,
86 .bo_handles = (uintptr_t) bo_handles,
87 .bo_handle_count = bo_count,
88 .out_sync = syncobj,
89 };
90
91 ret = drmIoctl(dev->fd, DRM_IOCTL_PANFROST_SUBMIT, &submit);
92 assert(!ret);
93 free(bo_handles);
94
95 drmSyncobjWait(dev->fd, &syncobj, 1, INT64_MAX, 0, NULL);
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -040096 if (debug >= BIT_DEBUG_ALL)
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -040097 pandecode_jc(submit.jc, true, dev->gpu_id, false);
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -040098 return true;
99}
100
101/* Checks that the device is alive and responding to basic jobs as a sanity
102 * check - prerequisite to running code on the device. We test this via a
103 * WRITE_VALUE job */
104
105bool
106bit_sanity_check(struct panfrost_device *dev)
107{
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400108 struct panfrost_bo *scratch = bit_bo_create(dev, 65536);
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -0400109 ((uint32_t *) scratch->cpu)[0] = 0xAA;
110
Boris Brezillon9121e7d2020-09-08 10:39:23 +0200111 struct mali_write_value_job_payload_packed payload;
112
113 pan_pack(&payload, WRITE_VALUE_JOB_PAYLOAD, cfg) {
114 cfg.address = scratch->gpu;
115 cfg.type = MALI_WRITE_VALUE_TYPE_ZERO;
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -0400116 };
117
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400118 struct panfrost_bo *bos[] = { scratch };
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -0400119 bool success = bit_submit(dev, MALI_JOB_TYPE_WRITE_VALUE,
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400120 &payload, sizeof(payload), bos, 1, false);
Alyssa Rosenzweiga0d1be32020-03-24 14:08:16 -0400121
122 return success && (((uint8_t *) scratch->cpu)[0] == 0x0);
123}
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400124
125/* Constructs a vertex job */
126
127bool
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400128bit_vertex(struct panfrost_device *dev, panfrost_program prog,
129 uint32_t *iubo, size_t sz_ubo,
130 uint32_t *iattr, size_t sz_attr,
131 uint32_t *expected, size_t sz_expected, enum bit_debug debug)
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400132{
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400133 struct panfrost_bo *shader = bit_bo_create(dev, prog.compiled.size);
134 struct panfrost_bo *shader_desc = bit_bo_create(dev, 4096);
135 struct panfrost_bo *ubo = bit_bo_create(dev, 4096);
136 struct panfrost_bo *var = bit_bo_create(dev, 4096);
137 struct panfrost_bo *attr = bit_bo_create(dev, 4096);
138
Alyssa Rosenzweigb10f34a2020-09-09 16:29:41 -0400139 pan_pack(attr->cpu, ATTRIBUTE, cfg) {
Alyssa Rosenzweigeb2762a2020-08-14 15:27:40 -0400140 cfg.format = (MALI_RGBA32UI << 12);
141 cfg.unknown = true;
Alyssa Rosenzweigfa949672020-08-05 21:39:25 -0400142 }
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400143
Alyssa Rosenzweigb10f34a2020-09-09 16:29:41 -0400144 pan_pack(var->cpu, ATTRIBUTE, cfg) {
Alyssa Rosenzweigeb2762a2020-08-14 15:27:40 -0400145 cfg.format = (MALI_RGBA32UI << 12);
Alyssa Rosenzweigb10f34a2020-09-09 16:29:41 -0400146 cfg.unknown = false;
147 }
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400148
Alyssa Rosenzweigeb2762a2020-08-14 15:27:40 -0400149 pan_pack(var->cpu + 256, ATTRIBUTE_BUFFER, cfg) {
150 cfg.pointer = (var->gpu + 1024);
151 cfg.size = 1024;
152 }
153
154 pan_pack(attr->cpu + 256, ATTRIBUTE_BUFFER, cfg) {
155 cfg.pointer = (attr->gpu + 1024);
156 cfg.size = 1024;
157 }
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400158
Alyssa Rosenzweigb10f34a2020-09-09 16:29:41 -0400159 pan_pack(ubo->cpu, UNIFORM_BUFFER, cfg) {
160 cfg.entries = sz_ubo / 16;
161 cfg.pointer = ubo->gpu + 1024;
162 }
163
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400164 if (sz_ubo)
165 memcpy(ubo->cpu + 1024, iubo, sz_ubo);
166
167 if (sz_attr)
168 memcpy(attr->cpu + 1024, iattr, sz_attr);
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400169
170 struct panfrost_bo *shmem = bit_bo_create(dev, 4096);
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400171
Boris Brezillon3a06fc32020-09-03 09:18:09 +0200172 pan_pack(shmem->cpu, LOCAL_STORAGE, cfg) {
173 cfg.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM;
174 }
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400175
Boris Brezillonf734e672020-09-29 15:47:04 +0200176 pan_pack(shader_desc->cpu, RENDERER_STATE, cfg) {
Alyssa Rosenzweiga7b23172020-08-21 16:27:17 -0400177 cfg.shader.shader = shader->gpu;
178 cfg.shader.attribute_count = cfg.shader.varying_count = 1;
Boris Brezillon7bb85ea2020-09-15 17:03:28 +0200179 cfg.properties.uniform_buffer_count = 1;
Boris Brezillon519643b2020-10-13 18:32:14 +0200180 cfg.properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
Boris Brezillon7bb85ea2020-09-15 17:03:28 +0200181 cfg.preload.vertex_id = true;
182 cfg.preload.instance_id = true;
Alyssa Rosenzweiga7b23172020-08-21 16:27:17 -0400183 cfg.preload.uniform_count = (sz_ubo / 16);
184 }
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400185
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400186 memcpy(shader->cpu, prog.compiled.data, prog.compiled.size);
187
Boris Brezillond2892092020-09-08 19:41:51 +0200188 struct mali_compute_job_packed job;
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400189
Boris Brezillond2892092020-09-08 19:41:51 +0200190 pan_section_pack(&job, COMPUTE_JOB, PARAMETERS, cfg) {
191 cfg.job_task_split = 5;
192 }
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400193
Boris Brezillond2892092020-09-08 19:41:51 +0200194 pan_section_pack(&job, COMPUTE_JOB, DRAW, cfg) {
Boris Brezillond343f232020-09-29 10:45:23 +0200195 cfg.draw_descriptor_is_64b = true;
196 cfg.thread_storage = shmem->gpu;
Alyssa Rosenzweigeb261a82020-08-26 17:10:37 -0400197 cfg.state = shader_desc->gpu;
198 cfg.push_uniforms = ubo->gpu + 1024;
199 cfg.uniform_buffers = ubo->gpu;
200 cfg.attributes = attr->gpu;
201 cfg.attribute_buffers = attr->gpu + 256;
202 cfg.varyings = var->gpu;
203 cfg.varying_buffers = var->gpu + 256;
204 }
205
Boris Brezillond2892092020-09-08 19:41:51 +0200206 void *invocation = pan_section_ptr(&job, COMPUTE_JOB, INVOCATION);
207 panfrost_pack_work_groups_compute(invocation,
208 1, 1, 1,
209 1, 1, 1,
210 true);
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400211
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400212 struct panfrost_bo *bos[] = {
Alyssa Rosenzweigb10f34a2020-09-09 16:29:41 -0400213 shmem, shader, shader_desc, ubo, var, attr
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400214 };
215
Boris Brezillond2892092020-09-08 19:41:51 +0200216 bool succ = bit_submit(dev, MALI_JOB_TYPE_VERTEX,
217 ((void *)&job) + MALI_JOB_HEADER_LENGTH,
218 MALI_COMPUTE_JOB_LENGTH - MALI_JOB_HEADER_LENGTH,
219 bos, ARRAY_SIZE(bos), debug);
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400220
221 /* Check the output varyings */
222
Alyssa Rosenzweig1a1c5572020-04-05 18:45:00 -0400223 uint32_t *output = (uint32_t *) (var->cpu + 1024);
224 float *foutput = (float *) output;
225 float *fexpected = (float *) expected;
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400226
Alyssa Rosenzweig1a1c5572020-04-05 18:45:00 -0400227 if (sz_expected) {
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400228 unsigned comp = memcmp(output, expected, sz_expected);
229 succ &= (comp == 0);
230
231 if (comp && (debug >= BIT_DEBUG_FAIL)) {
232 fprintf(stderr, "expected [");
233
234 for (unsigned i = 0; i < (sz_expected >> 2); ++i)
235 fprintf(stderr, "%08X /* %f */ ", expected[i], fexpected[i]);
236
237 fprintf(stderr, "], got [");
238
239 for (unsigned i = 0; i < (sz_expected >> 2); ++i)
240 fprintf(stderr, "%08X /* %f */ ", output[i], foutput[i]);
241
242 fprintf(stderr, "\n");
243 }
Alyssa Rosenzweig1a1c5572020-04-05 18:45:00 -0400244 } else if (debug == BIT_DEBUG_ALL) {
245 fprintf(stderr, "got [");
246
247 for (unsigned i = 0; i < 4; ++i)
248 fprintf(stderr, "%08X /* %f */ ", output[i], foutput[i]);
249
250 fprintf(stderr, "\n");
Alyssa Rosenzweigb0331892020-03-31 12:20:18 -0400251 }
252
253 return succ;
Alyssa Rosenzweig3d7166f2020-03-25 14:56:06 -0400254}