assert(pipeline);
/* Upload the uniforms to the indirect CL first */
+ struct v3dv_cl_reloc fs_uniforms =
+ v3dv_write_uniforms(cmd_buffer, pipeline->fs);
- /* FIXME: uniforms not supported yet */
+ struct v3dv_cl_reloc vs_uniforms =
+ v3dv_write_uniforms(cmd_buffer, pipeline->vs);
- struct v3dv_cl_reloc vs_uniforms = { NULL, 0 };
- struct v3dv_cl_reloc vs_bin_uniforms = { NULL, 0 };
- struct v3dv_cl_reloc fs_uniforms = { NULL, 0 };
+ struct v3dv_cl_reloc vs_bin_uniforms =
+ v3dv_write_uniforms(cmd_buffer, pipeline->vs_bin);
/* Update the cache dirty flag based on the shader progs data */
state->tmu_dirty_rcl |= pipeline->vs_bin->prog_data.vs->base.tmu_dirty_rcl;
--- /dev/null
+/*
+ * Copyright © 2019 Raspberry Pi
+ *
+ * Based in part on v3d driver which is:
+ *
+ * Copyright © 2014-2017 Broadcom
+ *
+ * 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 "v3dv_private.h"
+
+struct v3dv_cl_reloc
+v3dv_write_uniforms(struct v3dv_cmd_buffer *cmd_buffer,
+ struct v3dv_pipeline_stage *p_stage)
+{
+ struct v3d_uniform_list *uinfo = &p_stage->prog_data.base->uniforms;
+ struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
+
+ /* The hardware always pre-fetches the next uniform (also when there
+ * aren't any), so we always allocate space for an extra slot. This
+ * fixes MMU exceptions reported since Linux kernel 5.4 when the
+ * uniforms fill up the tail bytes of a page in the indirect
+ * BO. In that scenario, when the hardware pre-fetches after reading
+ * the last uniform it will read beyond the end of the page and trigger
+ * the MMU exception.
+ */
+ v3dv_cl_ensure_space(&cmd_buffer->indirect, (uinfo->count + 1) * 4, 4);
+
+ struct v3dv_cl_reloc uniform_stream =
+ v3dv_cl_get_address(&cmd_buffer->indirect);
+
+ struct v3dv_cl_out *uniforms =
+ cl_start(&cmd_buffer->indirect);
+
+ for (int i = 0; i < uinfo->count; i++) {
+ uint32_t data = uinfo->data[i];
+
+ switch (uinfo->contents[i]) {
+ case QUNIFORM_CONSTANT:
+ cl_aligned_u32(&uniforms, data);
+ break;
+
+ case QUNIFORM_VIEWPORT_X_SCALE:
+ cl_aligned_f(&uniforms, dynamic->viewport.scale[0][0] * 256.0f);
+ break;
+
+ case QUNIFORM_VIEWPORT_Y_SCALE:
+ cl_aligned_f(&uniforms, dynamic->viewport.scale[0][1] * 256.0f);
+ break;
+
+ case QUNIFORM_VIEWPORT_Z_OFFSET:
+ cl_aligned_f(&uniforms, dynamic->viewport.translate[0][2]);
+ break;
+
+ case QUNIFORM_VIEWPORT_Z_SCALE:
+ cl_aligned_f(&uniforms, dynamic->viewport.scale[0][2]);
+ break;
+
+ default:
+ unreachable("unsupported quniform_contents uniform type\n");
+ }
+ }
+
+ cl_end(&cmd_buffer->indirect, uniforms);
+
+ return uniform_stream;
+}