diff --git a/src/amd/vulkan/bvh/build_helpers.h b/src/amd/vulkan/bvh/build_helpers.h new file mode 100644 index 00000000000..5147a455dd7 --- /dev/null +++ b/src/amd/vulkan/bvh/build_helpers.h @@ -0,0 +1,324 @@ +/* + * Copyright © 2022 Konstantin Seurer + * + * 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 BVH_BUILD_HELPERS_H +#define BVH_BUILD_HELPERS_H + +#include "bvh.h" + +#define VK_FORMAT_UNDEFINED 0 +#define VK_FORMAT_R4G4_UNORM_PACK8 1 +#define VK_FORMAT_R4G4B4A4_UNORM_PACK16 2 +#define VK_FORMAT_B4G4R4A4_UNORM_PACK16 3 +#define VK_FORMAT_R5G6B5_UNORM_PACK16 4 +#define VK_FORMAT_B5G6R5_UNORM_PACK16 5 +#define VK_FORMAT_R5G5B5A1_UNORM_PACK16 6 +#define VK_FORMAT_B5G5R5A1_UNORM_PACK16 7 +#define VK_FORMAT_A1R5G5B5_UNORM_PACK16 8 +#define VK_FORMAT_R8_UNORM 9 +#define VK_FORMAT_R8_SNORM 10 +#define VK_FORMAT_R8_USCALED 11 +#define VK_FORMAT_R8_SSCALED 12 +#define VK_FORMAT_R8_UINT 13 +#define VK_FORMAT_R8_SINT 14 +#define VK_FORMAT_R8_SRGB 15 +#define VK_FORMAT_R8G8_UNORM 16 +#define VK_FORMAT_R8G8_SNORM 17 +#define VK_FORMAT_R8G8_USCALED 18 +#define VK_FORMAT_R8G8_SSCALED 19 +#define VK_FORMAT_R8G8_UINT 20 +#define VK_FORMAT_R8G8_SINT 21 +#define VK_FORMAT_R8G8_SRGB 22 +#define VK_FORMAT_R8G8B8_UNORM 23 +#define VK_FORMAT_R8G8B8_SNORM 24 +#define VK_FORMAT_R8G8B8_USCALED 25 +#define VK_FORMAT_R8G8B8_SSCALED 26 +#define VK_FORMAT_R8G8B8_UINT 27 +#define VK_FORMAT_R8G8B8_SINT 28 +#define VK_FORMAT_R8G8B8_SRGB 29 +#define VK_FORMAT_B8G8R8_UNORM 30 +#define VK_FORMAT_B8G8R8_SNORM 31 +#define VK_FORMAT_B8G8R8_USCALED 32 +#define VK_FORMAT_B8G8R8_SSCALED 33 +#define VK_FORMAT_B8G8R8_UINT 34 +#define VK_FORMAT_B8G8R8_SINT 35 +#define VK_FORMAT_B8G8R8_SRGB 36 +#define VK_FORMAT_R8G8B8A8_UNORM 37 +#define VK_FORMAT_R8G8B8A8_SNORM 38 +#define VK_FORMAT_R8G8B8A8_USCALED 39 +#define VK_FORMAT_R8G8B8A8_SSCALED 40 +#define VK_FORMAT_R8G8B8A8_UINT 41 +#define VK_FORMAT_R8G8B8A8_SINT 42 +#define VK_FORMAT_R8G8B8A8_SRGB 43 +#define VK_FORMAT_B8G8R8A8_UNORM 44 +#define VK_FORMAT_B8G8R8A8_SNORM 45 +#define VK_FORMAT_B8G8R8A8_USCALED 46 +#define VK_FORMAT_B8G8R8A8_SSCALED 47 +#define VK_FORMAT_B8G8R8A8_UINT 48 +#define VK_FORMAT_B8G8R8A8_SINT 49 +#define VK_FORMAT_B8G8R8A8_SRGB 50 +#define VK_FORMAT_A8B8G8R8_UNORM_PACK32 51 +#define VK_FORMAT_A8B8G8R8_SNORM_PACK32 52 +#define VK_FORMAT_A8B8G8R8_USCALED_PACK32 53 +#define VK_FORMAT_A8B8G8R8_SSCALED_PACK32 54 +#define VK_FORMAT_A8B8G8R8_UINT_PACK32 55 +#define VK_FORMAT_A8B8G8R8_SINT_PACK32 56 +#define VK_FORMAT_A8B8G8R8_SRGB_PACK32 57 +#define VK_FORMAT_A2R10G10B10_UNORM_PACK32 58 +#define VK_FORMAT_A2R10G10B10_SNORM_PACK32 59 +#define VK_FORMAT_A2R10G10B10_USCALED_PACK32 60 +#define VK_FORMAT_A2R10G10B10_SSCALED_PACK32 61 +#define VK_FORMAT_A2R10G10B10_UINT_PACK32 62 +#define VK_FORMAT_A2R10G10B10_SINT_PACK32 63 +#define VK_FORMAT_A2B10G10R10_UNORM_PACK32 64 +#define VK_FORMAT_A2B10G10R10_SNORM_PACK32 65 +#define VK_FORMAT_A2B10G10R10_USCALED_PACK32 66 +#define VK_FORMAT_A2B10G10R10_SSCALED_PACK32 67 +#define VK_FORMAT_A2B10G10R10_UINT_PACK32 68 +#define VK_FORMAT_A2B10G10R10_SINT_PACK32 69 +#define VK_FORMAT_R16_UNORM 70 +#define VK_FORMAT_R16_SNORM 71 +#define VK_FORMAT_R16_USCALED 72 +#define VK_FORMAT_R16_SSCALED 73 +#define VK_FORMAT_R16_UINT 74 +#define VK_FORMAT_R16_SINT 75 +#define VK_FORMAT_R16_SFLOAT 76 +#define VK_FORMAT_R16G16_UNORM 77 +#define VK_FORMAT_R16G16_SNORM 78 +#define VK_FORMAT_R16G16_USCALED 79 +#define VK_FORMAT_R16G16_SSCALED 80 +#define VK_FORMAT_R16G16_UINT 81 +#define VK_FORMAT_R16G16_SINT 82 +#define VK_FORMAT_R16G16_SFLOAT 83 +#define VK_FORMAT_R16G16B16_UNORM 84 +#define VK_FORMAT_R16G16B16_SNORM 85 +#define VK_FORMAT_R16G16B16_USCALED 86 +#define VK_FORMAT_R16G16B16_SSCALED 87 +#define VK_FORMAT_R16G16B16_UINT 88 +#define VK_FORMAT_R16G16B16_SINT 89 +#define VK_FORMAT_R16G16B16_SFLOAT 90 +#define VK_FORMAT_R16G16B16A16_UNORM 91 +#define VK_FORMAT_R16G16B16A16_SNORM 92 +#define VK_FORMAT_R16G16B16A16_USCALED 93 +#define VK_FORMAT_R16G16B16A16_SSCALED 94 +#define VK_FORMAT_R16G16B16A16_UINT 95 +#define VK_FORMAT_R16G16B16A16_SINT 96 +#define VK_FORMAT_R16G16B16A16_SFLOAT 97 +#define VK_FORMAT_R32_UINT 98 +#define VK_FORMAT_R32_SINT 99 +#define VK_FORMAT_R32_SFLOAT 100 +#define VK_FORMAT_R32G32_UINT 101 +#define VK_FORMAT_R32G32_SINT 102 +#define VK_FORMAT_R32G32_SFLOAT 103 +#define VK_FORMAT_R32G32B32_UINT 104 +#define VK_FORMAT_R32G32B32_SINT 105 +#define VK_FORMAT_R32G32B32_SFLOAT 106 +#define VK_FORMAT_R32G32B32A32_UINT 107 +#define VK_FORMAT_R32G32B32A32_SINT 108 +#define VK_FORMAT_R32G32B32A32_SFLOAT 109 +#define VK_FORMAT_R64_UINT 110 +#define VK_FORMAT_R64_SINT 111 +#define VK_FORMAT_R64_SFLOAT 112 +#define VK_FORMAT_R64G64_UINT 113 +#define VK_FORMAT_R64G64_SINT 114 +#define VK_FORMAT_R64G64_SFLOAT 115 +#define VK_FORMAT_R64G64B64_UINT 116 +#define VK_FORMAT_R64G64B64_SINT 117 +#define VK_FORMAT_R64G64B64_SFLOAT 118 +#define VK_FORMAT_R64G64B64A64_UINT 119 +#define VK_FORMAT_R64G64B64A64_SINT 120 +#define VK_FORMAT_R64G64B64A64_SFLOAT 121 + +#define VK_INDEX_TYPE_UINT16 0 +#define VK_INDEX_TYPE_UINT32 1 +#define VK_INDEX_TYPE_NONE_KHR 1000165000 +#define VK_INDEX_TYPE_UINT8_EXT 1000265000 + +#define VK_GEOMETRY_TYPE_TRIANGLES_KHR 0 +#define VK_GEOMETRY_TYPE_AABBS_KHR 1 + +#define TYPE(type, size) \ + layout(buffer_reference) buffer type##_ref \ + { \ + type value; \ + }; \ + const uint32_t type##_size = size + +#define REF(type) type##_ref +#define VOID_REF uint64_t +#define NULL 0 +#define DEREF(var) var.value + +#define SIZEOF(type) type##_size + +#define OFFSET(ptr, offset) (uint64_t(ptr) + offset) + +#define INFINITY (1.0 / 0.0) +#define NAN (0.0 / 0.0) + +#define INDEX(type, ptr, index) REF(type)(OFFSET(ptr, (index)*SIZEOF(type))) + +TYPE(int8_t, 1); +TYPE(uint8_t, 1); +TYPE(int16_t, 2); +TYPE(uint16_t, 2); +TYPE(int32_t, 4); +TYPE(uint32_t, 4); +TYPE(int64_t, 8); +TYPE(uint64_t, 8); + +TYPE(float, 4); + +TYPE(vec2, 8); +TYPE(vec3, 12); +TYPE(vec4, 16); + +TYPE(VOID_REF, 8); + +void +min_float_emulated(REF(int32_t) addr, float f) +{ + int32_t bits = floatBitsToInt(f); + atomicMin(DEREF(addr), f < 0 ? -2147483648 - bits : bits); +} + +void +max_float_emulated(REF(int32_t) addr, float f) +{ + int32_t bits = floatBitsToInt(f); + atomicMax(DEREF(addr), f < 0 ? -2147483648 - bits : bits); +} + +float +load_minmax_float_emulated(VOID_REF addr) +{ + int32_t bits = DEREF(REF(int32_t)(addr)); + return intBitsToFloat(bits < 0 ? -2147483648 - bits : bits); +} + +struct AABB { + vec3 min; + vec3 max; +}; +TYPE(AABB, 24); + +struct key_id_pair { + uint32_t id; + uint32_t key; +}; +TYPE(key_id_pair, 8); + +TYPE(radv_accel_struct_serialization_header, 56); +TYPE(radv_accel_struct_header, 88); +TYPE(radv_bvh_triangle_node, 64); +TYPE(radv_bvh_aabb_node, 64); +TYPE(radv_bvh_instance_node, 128); +TYPE(radv_bvh_box16_node, 64); +TYPE(radv_bvh_box32_node, 128); + +struct bvh_node { + uint8_t reserved[128]; +}; +TYPE(bvh_node, 128); + +uint32_t +id_to_offset(uint32_t id) +{ + return (id & (~7u)) << 3; +} + +uint32_t +id_to_type(uint32_t id) +{ + return id & 7u; +} + +uint32_t +pack_node_id(uint32_t offset, uint32_t type) +{ + return (offset >> 3) | type; +} + +AABB +calculate_node_bounds(VOID_REF bvh, uint32_t id) +{ + AABB aabb; + + VOID_REF node = OFFSET(bvh, id_to_offset(id)); + switch (id_to_type(id)) { + case radv_bvh_node_triangle: { + radv_bvh_triangle_node triangle = DEREF(REF(radv_bvh_triangle_node)(node)); + + vec3 v0 = vec3(triangle.coords[0][0], triangle.coords[0][1], triangle.coords[0][2]); + vec3 v1 = vec3(triangle.coords[1][0], triangle.coords[1][1], triangle.coords[1][2]); + vec3 v2 = vec3(triangle.coords[2][0], triangle.coords[2][1], triangle.coords[2][2]); + + aabb.min = min(min(v0, v1), v2); + aabb.max = max(max(v0, v1), v2); + break; + } + case radv_bvh_node_internal: { + radv_bvh_box32_node internal = DEREF(REF(radv_bvh_box32_node)(node)); + aabb.min = vec3(INFINITY); + aabb.max = vec3(-INFINITY); + for (uint32_t i = 0; i < 4; i++) { + aabb.min.x = min(aabb.min.x, internal.coords[i][0][0]); + aabb.min.y = min(aabb.min.y, internal.coords[i][0][1]); + aabb.min.z = min(aabb.min.z, internal.coords[i][0][2]); + + aabb.max.x = max(aabb.max.x, internal.coords[i][1][0]); + aabb.max.y = max(aabb.max.y, internal.coords[i][1][1]); + aabb.max.z = max(aabb.max.z, internal.coords[i][1][2]); + } + break; + } + case radv_bvh_node_instance: { + radv_bvh_instance_node instance = DEREF(REF(radv_bvh_instance_node)(node)); + + aabb.min.x = instance.aabb[0][0]; + aabb.min.y = instance.aabb[0][1]; + aabb.min.z = instance.aabb[0][2]; + + aabb.max.x = instance.aabb[1][0]; + aabb.max.y = instance.aabb[1][1]; + aabb.max.z = instance.aabb[1][2]; + break; + } + case radv_bvh_node_aabb: { + radv_bvh_aabb_node custom = DEREF(REF(radv_bvh_aabb_node)(node)); + + aabb.min.x = custom.aabb[0][0]; + aabb.min.y = custom.aabb[0][1]; + aabb.min.z = custom.aabb[0][2]; + + aabb.max.x = custom.aabb[1][0]; + aabb.max.y = custom.aabb[1][1]; + aabb.max.z = custom.aabb[1][2]; + break; + } + } + + return aabb; +} + +#endif diff --git a/src/amd/vulkan/bvh/meson.build b/src/amd/vulkan/bvh/meson.build new file mode 100644 index 00000000000..dfa62d7d8e4 --- /dev/null +++ b/src/amd/vulkan/bvh/meson.build @@ -0,0 +1,42 @@ +# Copyright © 2022 Konstantin Seurer + +# 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 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. + +bvh_shaders = [ +] + +bvh_include_dir = meson.source_root() + '/src/amd/vulkan/bvh' + +bvh_includes = files( + 'build_helpers.h', + 'bvh.h', +) + +bvh_spv = [] +foreach s : bvh_shaders + bvh_spv += custom_target( + s + '.spv.h', + input : s, + output : s + '.spv.h', + command : [ + prog_glslang, '-V', '-I' + bvh_include_dir, '--target-env', 'spirv1.4', '-x', '-o', '@OUTPUT@', '@INPUT@' + ] + glslang_quiet, + depend_files: bvh_includes + ) +endforeach diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index da36ff52167..0074b323cac 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -126,6 +126,8 @@ endif subdir('radix_sort') libradv_files += radix_sort_files +subdir('bvh') + radv_deps = [] radv_flags = cc.get_supported_arguments(['-Wimplicit-fallthrough', '-Wshadow']) @@ -162,7 +164,7 @@ endif libvulkan_radeon = shared_library( 'vulkan_radeon', - [libradv_files, radv_entrypoints, sha1_h, radix_sort_spv], + [libradv_files, radv_entrypoints, sha1_h, radix_sort_spv, bvh_spv], vs_module_defs : vulkan_api_def, include_directories : [ inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_amd, inc_amd_common, inc_amd_common_llvm, inc_compiler, inc_util,