diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build index 3b978dd4f33..577f8e06ea4 100644 --- a/src/imagination/vulkan/meson.build +++ b/src/imagination/vulkan/meson.build @@ -43,6 +43,7 @@ pvr_files = files( 'pvr_descriptor_set.c', 'pvr_device.c', 'pvr_formats.c', + 'pvr_hardcode.c', 'pvr_hw_pass.c', 'pvr_image.c', 'pvr_job_common.c', diff --git a/src/imagination/vulkan/pvr_hardcode.c b/src/imagination/vulkan/pvr_hardcode.c new file mode 100644 index 00000000000..1091cf4eb02 --- /dev/null +++ b/src/imagination/vulkan/pvr_hardcode.c @@ -0,0 +1,145 @@ +/* + * 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 +#include +#include +#include +#include + +#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); +} diff --git a/src/imagination/vulkan/pvr_hardcode.h b/src/imagination/vulkan/pvr_hardcode.h new file mode 100644 index 00000000000..c663eb76f10 --- /dev/null +++ b/src/imagination/vulkan/pvr_hardcode.h @@ -0,0 +1,71 @@ +/* + * 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 +#include +#include + +#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 */ diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index 97772100cf2..e767868e868 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -36,10 +36,10 @@ #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" @@ -52,37 +52,6 @@ #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 *****************************************************************************/ @@ -1043,42 +1012,58 @@ static VkResult pvr_compute_pipeline_compile( 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, @@ -1087,35 +1072,13 @@ static VkResult pvr_compute_pipeline_compile( 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); @@ -1137,7 +1100,7 @@ static VkResult pvr_compute_pipeline_compile( 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) diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 4b687db05f0..64130d7cebe 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -1037,7 +1037,10 @@ struct pvr_compute_pipeline { 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; diff --git a/src/imagination/vulkan/usc/programs/pvr_usc_compute_shader.h b/src/imagination/vulkan/usc/hardcoded_apps/pvr_simple_compute.h similarity index 95% rename from src/imagination/vulkan/usc/programs/pvr_usc_compute_shader.h rename to src/imagination/vulkan/usc/hardcoded_apps/pvr_simple_compute.h index 0d59c7577ff..9c79e27d2d4 100644 --- a/src/imagination/vulkan/usc/programs/pvr_usc_compute_shader.h +++ b/src/imagination/vulkan/usc/hardcoded_apps/pvr_simple_compute.h @@ -23,13 +23,13 @@ /* 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 /* 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, @@ -99,4 +99,4 @@ uint8_t pvr_usc_compute_shader[] = { }; /* clang-format on */ -#endif /* PVR_USC_COMPUTE_SHADER_H */ +#endif /* PVR_SIMPLE_COMPUTE_H */