Skip to content

Commit 28f32e4

Browse files
committed
feat: add device support probe ABI
Expose a baseline-safe capability query for AArch32 NEON/VFPv4 requirements, bump the compatible ABI minor version, and cover HWCAP combinations plus package usage.
1 parent ce42641 commit 28f32e4

11 files changed

Lines changed: 157 additions & 6 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ endif()
3333

3434
project(
3535
soc
36-
VERSION 3.0.0
36+
VERSION 3.1.0
3737
DESCRIPTION "CPU software rasterization and occlusion culling library"
3838
LANGUAGES C
3939
)

include/soc/soc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ extern "C" {
3434

3535
SOC_API uint32_t SOC_CALL soc_get_abi_version(void);
3636

37+
/*
38+
* Safe to call immediately after loading the library, before any other SOC
39+
* operation. Returns SOC_TRUE when this library's ISA requirements are
40+
* available to the current process. If it returns SOC_FALSE, only this
41+
* function and soc_get_abi_version() may be called; all other SOC operations
42+
* are unsupported.
43+
*/
44+
SOC_API soc_bool SOC_CALL soc_device_is_supported(void);
45+
3746
/*
3847
* config->worker_count is the total execution lane count, including the
3948
* thread which calls build. Zero selects the online logical CPU count (clamped

include/soc/soc_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <stdint.h>
66

77
#define SOC_ABI_VERSION_MAJOR 3u
8-
#define SOC_ABI_VERSION_MINOR 0u
8+
#define SOC_ABI_VERSION_MINOR 1u
99
#define SOC_ABI_VERSION \
1010
((SOC_ABI_VERSION_MAJOR << 16u) | SOC_ABI_VERSION_MINOR)
1111

src/CMakeLists.txt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,50 @@ if(_soc_build_aarch32_neon_fma)
2222
)
2323
endif()
2424

25+
add_library(
26+
soc_device_support
27+
OBJECT
28+
abi/soc_device_support.c
29+
)
30+
target_include_directories(
31+
soc_device_support
32+
PRIVATE
33+
"${PROJECT_SOURCE_DIR}/include"
34+
"${CMAKE_CURRENT_SOURCE_DIR}"
35+
)
36+
target_compile_features(soc_device_support PRIVATE c_std_17)
37+
set_target_properties(
38+
soc_device_support
39+
PROPERTIES
40+
C_VISIBILITY_PRESET hidden
41+
INTERPROCEDURAL_OPTIMIZATION FALSE
42+
POSITION_INDEPENDENT_CODE ON
43+
)
44+
soc_enable_warnings(soc_device_support)
45+
if(SOC_BUILD_SHARED)
46+
target_compile_definitions(
47+
soc_device_support
48+
PRIVATE SOC_BUILDING_LIBRARY
49+
)
50+
else()
51+
target_compile_definitions(soc_device_support PRIVATE SOC_STATIC)
52+
endif()
53+
if(_soc_build_aarch32_neon_fma)
54+
target_compile_definitions(
55+
soc_device_support
56+
PRIVATE
57+
$<$<CONFIG:Release>:SOC_ABI_REQUIRES_ARM32_NEON_VFPV4=1>
58+
)
59+
target_compile_options(
60+
soc_device_support
61+
PRIVATE
62+
$<$<CONFIG:Release>:-march=armv7-a>
63+
$<$<CONFIG:Release>:-mfpu=vfpv3-d16>
64+
$<$<CONFIG:Release>:-mfloat-abi=softfp>
65+
$<$<CONFIG:Release>:-fno-lto>
66+
)
67+
endif()
68+
2569
add_library(
2670
soc_core
2771
OBJECT
@@ -123,6 +167,7 @@ if(SOC_BUILD_SHARED)
123167
soc
124168
SHARED
125169
abi/soc_api.c
170+
$<TARGET_OBJECTS:soc_device_support>
126171
$<TARGET_OBJECTS:soc_core>
127172
)
128173
target_compile_definitions(soc PRIVATE SOC_BUILDING_LIBRARY)
@@ -131,6 +176,7 @@ else()
131176
soc
132177
STATIC
133178
abi/soc_api.c
179+
$<TARGET_OBJECTS:soc_device_support>
134180
$<TARGET_OBJECTS:soc_core>
135181
)
136182
target_compile_definitions(soc PUBLIC SOC_STATIC)

src/abi/soc_device_support.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <soc/soc.h>
2+
3+
#include "abi/soc_device_support.h"
4+
5+
#if defined(SOC_ABI_REQUIRES_ARM32_NEON_VFPV4)
6+
#if !defined(__ANDROID__) || !defined(__arm__)
7+
#error "ARM32 NEON/VFPv4 support probe requires Android AArch32"
8+
#endif
9+
#include <sys/auxv.h>
10+
#endif
11+
12+
soc_bool SOC_CALL soc_device_is_supported(void)
13+
{
14+
#if defined(SOC_ABI_REQUIRES_ARM32_NEON_VFPV4)
15+
return soc_arm32_neon_vfpv4_is_supported(getauxval(AT_HWCAP));
16+
#else
17+
return SOC_TRUE;
18+
#endif
19+
}

src/abi/soc_device_support.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef SOC_DEVICE_SUPPORT_H_INCLUDED
2+
#define SOC_DEVICE_SUPPORT_H_INCLUDED
3+
4+
#include <soc/soc.h>
5+
6+
#define SOC_ARM32_HWCAP_NEON (1ul << 12u)
7+
#define SOC_ARM32_HWCAP_VFPV4 (1ul << 16u)
8+
9+
static inline soc_bool soc_arm32_neon_vfpv4_is_supported(
10+
unsigned long hwcap
11+
)
12+
{
13+
const unsigned long required =
14+
SOC_ARM32_HWCAP_NEON | SOC_ARM32_HWCAP_VFPV4;
15+
16+
return (hwcap & required) == required ? SOC_TRUE : SOC_FALSE;
17+
}
18+
19+
#endif

tests/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ soc_enable_warnings(soc_test_abi)
55

66
add_test(NAME soc.abi COMMAND soc_test_abi)
77

8+
add_executable(soc_test_device_support test_device_support.c)
9+
target_link_libraries(soc_test_device_support PRIVATE soc::soc)
10+
target_include_directories(
11+
soc_test_device_support
12+
PRIVATE "${PROJECT_SOURCE_DIR}/src"
13+
)
14+
target_compile_features(soc_test_device_support PRIVATE c_std_17)
15+
soc_enable_warnings(soc_test_device_support)
16+
17+
add_test(NAME soc.device_support COMMAND soc_test_device_support)
18+
819
add_executable(soc_test_types test_types.c)
920
target_link_libraries(soc_test_types PRIVATE soc::soc)
1021
target_compile_features(soc_test_types PRIVATE c_std_17)

tests/package-consumer/main.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ int main(void)
88
soc_build_stats build_stats = {0};
99
soc_query_stats query_stats = {0};
1010
soc_snapshot* snapshot = NULL;
11+
const soc_bool device_supported = soc_device_is_supported();
12+
13+
if (soc_get_abi_version() != SOC_ABI_VERSION ||
14+
SOC_ABI_VERSION_MAJOR != 3u) {
15+
return 1;
16+
}
17+
if (device_supported == SOC_FALSE) {
18+
return 0;
19+
}
20+
if (device_supported != SOC_TRUE) {
21+
return 1;
22+
}
1123

1224
group.flags = SOC_OCCLUDER_GROUP_FLAG_NONE;
1325
build.struct_size = sizeof(build);
@@ -22,9 +34,7 @@ int main(void)
2234

2335
soc_snapshot_destroy(snapshot);
2436

25-
return soc_get_abi_version() == SOC_ABI_VERSION &&
26-
SOC_ABI_VERSION_MAJOR == 3u &&
27-
SOC_OCCLUDER_GROUP_SIZE_V1 <= sizeof(group) &&
37+
return SOC_OCCLUDER_GROUP_SIZE_V1 <= sizeof(group) &&
2838
SOC_OCCLUSION_BUILD_DESC_SIZE_V1 <= sizeof(build) &&
2939
SOC_BUILD_STATS_SIZE_V1 <= sizeof(build_stats) &&
3040
SOC_QUERY_STATS_SIZE_V1 <= sizeof(query_stats)

tests/test_abi.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,17 @@ static int test_invalid_arguments(void)
228228

229229
int main(void)
230230
{
231+
const soc_bool device_supported = soc_device_is_supported();
232+
231233
if (test_version() != 0) {
232234
return 1;
233235
}
236+
if (device_supported == SOC_FALSE) {
237+
return 0;
238+
}
239+
if (device_supported != SOC_TRUE) {
240+
return 1;
241+
}
234242
if (test_context_lifetime() != 0) {
235243
return 1;
236244
}

tests/test_device_support.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <soc/soc.h>
2+
3+
#include "abi/soc_device_support.h"
4+
5+
#define CHECK(condition) \
6+
do { \
7+
if (!(condition)) { \
8+
return 1; \
9+
} \
10+
} while (0)
11+
12+
int main(void)
13+
{
14+
CHECK(soc_arm32_neon_vfpv4_is_supported(0ul) == SOC_FALSE);
15+
CHECK(soc_arm32_neon_vfpv4_is_supported(
16+
SOC_ARM32_HWCAP_NEON
17+
) == SOC_FALSE);
18+
CHECK(soc_arm32_neon_vfpv4_is_supported(
19+
SOC_ARM32_HWCAP_VFPV4
20+
) == SOC_FALSE);
21+
CHECK(soc_arm32_neon_vfpv4_is_supported(
22+
SOC_ARM32_HWCAP_NEON | SOC_ARM32_HWCAP_VFPV4
23+
) == SOC_TRUE);
24+
CHECK(soc_arm32_neon_vfpv4_is_supported(~0ul) == SOC_TRUE);
25+
26+
const soc_bool supported = soc_device_is_supported();
27+
CHECK(supported == SOC_FALSE || supported == SOC_TRUE);
28+
return 0;
29+
}

0 commit comments

Comments
 (0)