'pvr_descriptor_set.c',
'pvr_device.c',
'pvr_formats.c',
+ 'pvr_hardcode.c',
'pvr_hw_pass.c',
'pvr_image.c',
'pvr_job_common.c',
--- /dev/null
+/*
+ * Copyright © 2022 Imagination Technologies Ltd.
+ *
+ * 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 <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <vulkan/vulkan_core.h>
+
+#include "hwdef/rogue_hw_utils.h"
+#include "pvr_hardcode.h"
+#include "pvr_private.h"
+#include "rogue/rogue.h"
+#include "usc/hardcoded_apps/pvr_simple_compute.h"
+#include "util/macros.h"
+#include "util/u_process.h"
+
+/**
+ * \file pvr_hardcode.c
+ *
+ * \brief Contains hard coding functions.
+ * This should eventually be deleted as the compiler becomes more capable.
+ */
+
+/* Applications for which the compiler is capable of generating valid shaders.
+ */
+static const char *const compilable_progs[] = {
+ "triangle",
+};
+
+static const struct pvr_hard_coding_data {
+ const char *const name;
+
+ union {
+ struct {
+ const uint8_t *const shader;
+ size_t shader_size;
+
+ /* Note that the bo field will be unused. */
+ const struct pvr_compute_pipeline_shader_state shader_info;
+
+ const struct pvr_hard_code_compute_build_info build_info;
+ } compute;
+ };
+
+} hard_coding_table[] = {
+ {
+ .name = "simple-compute",
+ .compute = {
+ .shader = pvr_simple_compute_shader,
+ .shader_size = sizeof(pvr_simple_compute_shader),
+
+ .shader_info = {
+ .uses_atomic_ops = false,
+ .uses_barrier = false,
+ .uses_num_workgroups = false,
+
+ .const_shared_reg_count = 4,
+ .input_register_count = 8,
+ .work_size = 1 * 1 * 1,
+ .coefficient_register_count = 4,
+ },
+
+ .build_info = {
+ .ubo_data = { 0 },
+
+ .local_invocation_regs = { 0, 1 },
+ .work_group_regs = { 0, 1, 2 },
+ .barrier_reg = ROGUE_REG_UNUSED,
+ .usc_temps = 0,
+
+ .explicit_conts_usage = {
+ .start_offset = 0,
+ },
+ },
+ }
+ },
+};
+
+bool pvr_hard_code_shader_required(void)
+{
+ const char *const program = util_get_process_name();
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(compilable_progs); i++) {
+ if (strcmp(program, compilable_progs[i]) == 0)
+ return false;
+ }
+
+ return true;
+}
+
+static const struct pvr_hard_coding_data *pvr_get_hard_coding_data()
+{
+ const char *const program = util_get_process_name();
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(hard_coding_table); i++) {
+ if (strcmp(program, hard_coding_table[i].name) == 0)
+ return &hard_coding_table[i];
+ }
+
+ mesa_loge("Could not find hard coding data for %s", program);
+
+ return NULL;
+}
+
+VkResult pvr_hard_code_compute_pipeline(
+ struct pvr_device *const device,
+ struct pvr_compute_pipeline_shader_state *const shader_state_out,
+ struct pvr_hard_code_compute_build_info *const build_info_out)
+{
+ const uint32_t cache_line_size =
+ rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
+ const struct pvr_hard_coding_data *const data = pvr_get_hard_coding_data();
+
+ mesa_logd("Hard coding compute pipeline for %s", data->name);
+
+ *build_info_out = data->compute.build_info;
+ *shader_state_out = data->compute.shader_info;
+
+ return pvr_gpu_upload_usc(device,
+ data->compute.shader,
+ data->compute.shader_size,
+ cache_line_size,
+ &shader_state_out->bo);
+}
--- /dev/null
+/*
+ * Copyright © 2022 Imagination Technologies Ltd.
+ *
+ * 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 PVR_HARDCODE_SHADERS_H
+#define PVR_HARDCODE_SHADERS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <vulkan/vulkan_core.h>
+
+#include "rogue/rogue_build_data.h"
+
+/**
+ * \file pvr_hardcode.h
+ *
+ * \brief Contains hard coding functions.
+ * This should eventually be deleted as the compiler becomes more capable.
+ */
+
+struct pvr_compute_pipeline_shader_state;
+struct pvr_device;
+
+struct pvr_explicit_constant_usage {
+ /* Hardware register number assigned to the explicit constant with the lower
+ * pre_assigned offset.
+ */
+ uint32_t start_offset;
+};
+
+struct pvr_hard_code_compute_build_info {
+ struct rogue_ubo_data ubo_data;
+
+ uint32_t local_invocation_regs[2];
+ uint32_t work_group_regs[3];
+ uint32_t barrier_reg;
+ uint32_t usc_temps;
+
+ struct pvr_explicit_constant_usage explicit_conts_usage;
+};
+
+/* Returns true if the shader for the currently running program requires hard
+ * coded shaders.
+ */
+bool pvr_hard_code_shader_required(void);
+
+VkResult pvr_hard_code_compute_pipeline(
+ struct pvr_device *const device,
+ struct pvr_compute_pipeline_shader_state *const shader_state_out,
+ struct pvr_hard_code_compute_build_info *const build_info_out);
+
+#endif /* PVR_HARDCODE_SHADERS_H */
#include "pvr_bo.h"
#include "pvr_csb.h"
#include "pvr_csb_enum_helpers.h"
+#include "pvr_hardcode.h"
#include "pvr_pds.h"
#include "pvr_private.h"
#include "pvr_shader.h"
-#include "pvr_usc_compute_shader.h"
#include "pvr_winsys.h"
#include "rogue/rogue.h"
#include "rogue/rogue_build_data.h"
#include "vk_object.h"
#include "vk_util.h"
-/* FIXME: Remove this when the compiler is hooked up. */
-/******************************************************************************
- Hard coding
- ******************************************************************************/
-/* This section contains hard coding related structs. */
-
-struct pvr_explicit_constant_usage {
- /* Hardware register number assigned to the explicit constant with the lower
- * pre_assigned offset.
- */
- uint32_t start_offset;
-};
-
-static const struct {
- uint32_t local_invocation_regs[2];
-
- uint32_t work_group_regs[PVR_WORKGROUP_DIMENSIONS];
-
- uint32_t barrier_reg;
-
- uint32_t usc_temps;
-} pvr_pds_compute_program_params = {
- .local_invocation_regs = { 0, 1 },
-
- .work_group_regs = { 0, 1, 2 },
-
- .barrier_reg = ROGUE_REG_UNUSED,
-
- .usc_temps = 0,
-};
-
/*****************************************************************************
PDS functions
*****************************************************************************/
const VkAllocationCallbacks *const allocator,
struct pvr_compute_pipeline *const compute_pipeline)
{
- /* FIXME: Remove this hard coding. */
- const struct pvr_explicit_constant_usage explicit_const_usage = {
- .start_offset = 0,
- };
- const struct rogue_ubo_data uniform_program_ubo_data = { 0 };
-
- const uint32_t cache_line_size =
- rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
uint32_t work_group_input_regs[PVR_WORKGROUP_DIMENSIONS];
+ struct pvr_explicit_constant_usage explicit_const_usage;
uint32_t local_input_regs[PVR_WORKGROUP_DIMENSIONS];
+ struct rogue_ubo_data ubo_data;
uint32_t barrier_coefficient;
+ uint32_t usc_temps;
VkResult result;
- /* FIXME: Compile the shader. */
+ if (pvr_hard_code_shader_required()) {
+ struct pvr_hard_code_compute_build_info build_info;
- /* FIXME: Remove this hard coding. */
- compute_pipeline->state.shader.uses_atomic_ops = false;
- compute_pipeline->state.shader.uses_barrier = false;
- compute_pipeline->state.shader.uses_num_workgroups = false;
- compute_pipeline->state.shader.const_shared_reg_count = 4;
- compute_pipeline->state.shader.input_register_count = 8;
- compute_pipeline->state.shader.work_size = 1 * 1 * 1;
- compute_pipeline->state.shader.coefficient_register_count = 4;
+ result = pvr_hard_code_compute_pipeline(device,
+ &compute_pipeline->state.shader,
+ &build_info);
+ if (result != VK_SUCCESS)
+ return result;
- result = pvr_gpu_upload_usc(device,
- pvr_usc_compute_shader,
- sizeof(pvr_usc_compute_shader),
- cache_line_size,
- &compute_pipeline->state.shader.bo);
- if (result != VK_SUCCESS)
- return result;
+ ubo_data = build_info.ubo_data;
+
+ /* We make sure that the compiler's unused reg value is compatible with
+ * the pds api.
+ */
+ STATIC_ASSERT(ROGUE_REG_UNUSED == PVR_PDS_COMPUTE_INPUT_REG_UNUSED);
+
+ barrier_coefficient = build_info.barrier_reg;
+
+ /* TODO: Maybe change the pds api to use pointers so we avoid the copy. */
+ local_input_regs[0] = build_info.local_invocation_regs[0];
+ local_input_regs[1] = build_info.local_invocation_regs[1];
+ /* This is not a mistake. We want to assign element 1 to 2. */
+ local_input_regs[2] = build_info.local_invocation_regs[1];
+
+ STATIC_ASSERT(
+ __same_type(work_group_input_regs, build_info.work_group_regs));
+ typed_memcpy(work_group_input_regs,
+ build_info.work_group_regs,
+ PVR_WORKGROUP_DIMENSIONS);
+
+ usc_temps = build_info.usc_temps;
+
+ explicit_const_usage = build_info.explicit_conts_usage;
+
+ } else {
+ /* FIXME: Compile and upload the shader. */
+ /* FIXME: Initialize the shader state and setup build info. */
+ abort();
+ };
result = pvr_pds_uniform_program_create_and_upload(
device,
allocator,
- &uniform_program_ubo_data,
+ &ubo_data,
&explicit_const_usage,
compute_pipeline->base.layout,
PVR_STAGE_ALLOCATION_COMPUTE,
if (result != VK_SUCCESS)
goto err_free_shader;
- /* We make sure that the compiler's unused reg value is compatible with the
- * pds api.
- */
- STATIC_ASSERT(ROGUE_REG_UNUSED == PVR_PDS_COMPUTE_INPUT_REG_UNUSED);
-
- barrier_coefficient = pvr_pds_compute_program_params.barrier_reg;
-
- /* TODO: Maybe change the pds api to use pointers so we avoid the copy. */
- local_input_regs[0] =
- pvr_pds_compute_program_params.local_invocation_regs[0];
- local_input_regs[1] =
- pvr_pds_compute_program_params.local_invocation_regs[1];
- /* This is not a mistake. We want to assign element 1 to 2. */
- local_input_regs[2] =
- pvr_pds_compute_program_params.local_invocation_regs[1];
-
- STATIC_ASSERT(__same_type(work_group_input_regs,
- pvr_pds_compute_program_params.work_group_regs));
- typed_memcpy(work_group_input_regs,
- pvr_pds_compute_program_params.work_group_regs,
- PVR_WORKGROUP_DIMENSIONS);
-
result = pvr_pds_compute_program_create_and_upload(
device,
allocator,
local_input_regs,
work_group_input_regs,
barrier_coefficient,
- pvr_pds_compute_program_params.usc_temps,
+ usc_temps,
compute_pipeline->state.shader.bo->vma->dev_addr,
&compute_pipeline->state.primary_program,
&compute_pipeline->state.primary_program_info);
local_input_regs,
work_group_input_regs,
barrier_coefficient,
- pvr_pds_compute_program_params.usc_temps,
+ usc_temps,
compute_pipeline->state.shader.bo->vma->dev_addr,
&compute_pipeline->state.primary_base_workgroup_variant_program);
if (result != VK_SUCCESS)
struct pvr_pipeline base;
struct {
- struct {
+ /* TODO: Change this to be an anonymous struct once the shader hardcoding
+ * is removed.
+ */
+ struct pvr_compute_pipeline_shader_state {
/* Pointer to a buffer object that contains the shader binary. */
struct pvr_bo *bo;
/* Auto-generated file - don't edit */
-#ifndef PVR_USC_COMPUTE_SHADER_H
-#define PVR_USC_COMPUTE_SHADER_H
+#ifndef PVR_SIMPLE_COMPUTE_H
+#define PVR_SIMPLE_COMPUTE_H
#include <stdint.h>
/* clang-format off */
-uint8_t pvr_usc_compute_shader[] = {
+static const uint8_t pvr_simple_compute_shader[] = {
0x44, 0x12, 0xd3, 0x3f,
0x00, 0x00, 0x00, 0x24,
0x46, 0x40, 0xf9, 0xb0,
};
/* clang-format on */
-#endif /* PVR_USC_COMPUTE_SHADER_H */
+#endif /* PVR_SIMPLE_COMPUTE_H */