@@ -1238,6 +1238,8 @@ function(NBL_PARSE_REQUIRED PREFIX)
1238
1238
endforeach ()
1239
1239
endfunction ()
1240
1240
1241
+ # TODO: could create them in the function as <TARGET>_<PROPERTY> properties
1242
+
1241
1243
define_property (SOURCE PROPERTY NBL_SPIRV_REGISTERED_INPUT
1242
1244
BRIEF_DOCS "Absolute path to input shader which will be glued with device permutation config caps auto-gen file using #include directive, used as part of NSC compile rule to produce SPIRV output"
1243
1245
)
@@ -1247,13 +1249,30 @@ define_property(SOURCE PROPERTY NBL_SPIRV_PERMUTATION_CONFIG
1247
1249
FULL_DOCS "The file is auto-generated at configuration time, contains DeviceConfigCaps struct with permuted device caps after which #include directive glues it with an input shader"
1248
1250
)
1249
1251
1252
+ define_property (SOURCE PROPERTY NBL_SPIRV_BINARY_DIR
1253
+ BRIEF_DOCS "a <SPIRV output> = NBL_SPIRV_BINARY_DIR/NBL_SPIRV_ACCESS_KEY"
1254
+ )
1255
+ define_property (SOURCE PROPERTY NBL_SPIRV_ACCESS_KEY
1256
+ BRIEF_DOCS "a <SPIRV output> = NBL_SPIRV_BINARY_DIR/NBL_SPIRV_ACCESS_KEY"
1257
+ )
1258
+
1259
+ define_property (TARGET PROPERTY NBL_CANONICAL_IDENTIFIERS
1260
+ BRIEF_DOCS "List of identifiers composed as NBL_SPIRV_BINARY_DIR/KEY"
1261
+ FULL_DOCS "For a given NBL_SPIRV_BINARY_DIR we define a set of canonical KEYs, each unique given which at runtime one can get SPIRV key to access <SPIRV output> by the canonical key which may contain special permutation part in character of <key>(.<name>=<value>)(.<name>=<value>)(...)"
1262
+ )
1263
+
1250
1264
define_property (TARGET PROPERTY NBL_SPIRV_OUTPUTS
1251
- BRIEF_DOCS "Absolute paths to SPIRV outputs, part of NSC compile rules"
1265
+ BRIEF_DOCS "Absolute paths to all < SPIRV output>s which are part of NSC compile rules"
1252
1266
)
1253
1267
1254
- # NBL_SPIRV_OUTPUT = NBL_SPIRV_BINARY_DIR/NBL_SPIRV_ACCESS_KEY
1255
- define_property (SOURCE PROPERTY NBL_SPIRV_BINARY_DIR )
1256
- define_property (SOURCE PROPERTY NBL_SPIRV_ACCESS_KEY )
1268
+ define_property (TARGET PROPERTY NBL_HEADER_PATH
1269
+ BRIEF_DOCS "Relative path for auto-gen include file with key getters"
1270
+ )
1271
+ define_property (TARGET PROPERTY NBL_HEADER_GENERATED_RULE )
1272
+
1273
+ define_property (TARGET PROPERTY NBL_HEADER_CONTENT
1274
+ BRIEF_DOCS "Contains NBL_HEADER_PATH's content"
1275
+ )
1257
1276
1258
1277
function (NBL_CREATE_NSC_COMPILE_RULES )
1259
1278
set (COMMENT "this code has been autogenerated with Nabla CMake NBL_CREATE_HLSL_COMPILE_RULES utility" )
@@ -1301,14 +1320,67 @@ struct DeviceConfigCaps
1301
1320
)
1302
1321
endif ()
1303
1322
1304
- set (REQUIRED_SINGLE_ARGS TARGET BINARY_DIR OUTPUT_VAR INPUTS )
1323
+ set (REQUIRED_SINGLE_ARGS TARGET BINARY_DIR OUTPUT_VAR INPUTS INCLUDE NAMESPACE )
1305
1324
cmake_parse_arguments (IMPL "" "${REQUIRED_SINGLE_ARGS} " "COMMON_OPTIONS" ${ARGV} )
1306
1325
NBL_PARSE_REQUIRED (IMPL ${REQUIRED_SINGLE_ARGS} )
1307
1326
1308
1327
if (NOT TARGET ${IMPL_TARGET} )
1309
1328
add_library (${IMPL_TARGET} INTERFACE )
1310
1329
endif ()
1311
1330
1331
+ if (IS_ABSOLUTE "${IMPL_INCLUDE} " )
1332
+ message (FATAL_ERROR "INCLUDE argument must be relative path" )
1333
+ endif ()
1334
+
1335
+ set_target_properties (${IMPL_TARGET} PROPERTIES NBL_HEADER_PATH "${IMPL_INCLUDE} " )
1336
+
1337
+ get_target_property (HEADER_RULE_GENERATED ${IMPL_TARGET} NBL_HEADER_GENERATED_RULE )
1338
+ if (NOT HEADER_RULE_GENERATED )
1339
+ set (INCLUDE_DIR "$<TARGET_PROPERTY:${IMPL_TARGET} ,BINARY_DIR>/${IMPL_TARGET} /.cmake/include" )
1340
+ set (INCLUDE_FILE "${INCLUDE_DIR} /$<TARGET_PROPERTY:${IMPL_TARGET} ,NBL_HEADER_PATH>" )
1341
+ set (INCLUDE_CONTENT $< TARGET_PROPERTY:${IMPL_TARGET} ,NBL_HEADER_CONTENT> )
1342
+
1343
+ file (GENERATE OUTPUT ${INCLUDE_FILE}
1344
+ CONTENT ${INCLUDE_CONTENT}
1345
+ TARGET ${IMPL_TARGET}
1346
+ )
1347
+
1348
+ target_include_directories (${IMPL_TARGET} INTERFACE ${INCLUDE_DIR} )
1349
+ set_target_properties (${IMPL_TARGET} PROPERTIES NBL_HEADER_GENERATED_RULE ON )
1350
+
1351
+ set (HEADER_ITEM_VIEW [=[
1352
+ #include "nabla.h"
1353
+
1354
+ ]=] )
1355
+ set_property (TARGET ${IMPL_TARGET} APPEND_STRING PROPERTY NBL_HEADER_CONTENT "${HEADER_ITEM_VIEW} " )
1356
+ endif ()
1357
+
1358
+ string (MAKE_C_IDENTIFIER "${IMPL_TARGET} _${IMPL_NAMESPACE} " NS_IMPL_KEYS_PROPERTY )
1359
+ get_property (NS_IMPL_KEYS_PROPERTY_DEFINED
1360
+ TARGET ${IMPL_TARGET}
1361
+ PROPERTY "${NS_IMPL_KEYS_PROPERTY} "
1362
+ DEFINED
1363
+ )
1364
+ if (NOT NS_IMPL_KEYS_PROPERTY_DEFINED )
1365
+ set (HEADER_ITEM_VIEW [=[
1366
+ namespace @IMPL_NAMESPACE@ {
1367
+ template<nbl::core::StringLiteral Key>
1368
+ inline const nbl::core::string get_spirv_key(const nbl::video::SPhysicalDeviceLimits& limits, const nbl::video::SPhysicalDeviceFeatures& features);
1369
+
1370
+ template<nbl::core::StringLiteral Key>
1371
+ inline const nbl::core::string get_spirv_key(const nbl::video::ILogicalDevice* device)
1372
+ {
1373
+ return get_spirv_key<Key>(device->getPhysicalDevice()->getLimits(), device->getEnabledFeatures());
1374
+ }
1375
+ }
1376
+
1377
+ ]=] )
1378
+ string (CONFIGURE "${HEADER_ITEM_VIEW} " HEADER_ITEM_EVAL @ONLY )
1379
+ set_property (TARGET ${IMPL_TARGET} APPEND_STRING PROPERTY NBL_HEADER_CONTENT "${HEADER_ITEM_EVAL} " )
1380
+ define_property (TARGET PROPERTY "${NS_IMPL_KEYS_PROPERTY} " )
1381
+ endif ()
1382
+
1383
+
1312
1384
string (JSON JSON_LENGTH LENGTH "${IMPL_INPUTS} " )
1313
1385
math (EXPR LAST_INDEX "${JSON_LENGTH} - 1" )
1314
1386
@@ -1349,21 +1421,55 @@ struct DeviceConfigCaps
1349
1421
endif ()
1350
1422
endif ()
1351
1423
1424
+ function (ERROR_WHILE_PARSING_ITEM )
1425
+ string (JSON ITEM GET "${IMPL_INPUTS} " ${INDEX} )
1426
+ message (FATAL_ERROR
1427
+ "While parsing ${IMPL_TARGET} 's NSC compile rule\n ${ITEM} \n "
1428
+ ${ARGV}
1429
+ )
1430
+ endfunction ()
1431
+
1352
1432
set (CAP_NAMES "" )
1353
1433
set (CAP_TYPES "" )
1354
1434
if (HAS_CAPS )
1355
1435
math (EXPR LAST_CAP "${CAPS_LENGTH} - 1" )
1356
1436
foreach (CAP_IDX RANGE 0 ${LAST_CAP} )
1357
1437
string (JSON CAP_NAME GET "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} name )
1358
1438
string (JSON CAP_TYPE GET "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} type )
1359
- string (JSON CAP_VALUES_LENGTH LENGTH "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} values )
1360
1439
1361
- set (VALUES "" )
1362
- math (EXPR LAST_VAL "${CAP_VALUES_LENGTH} - 1" )
1363
- foreach (VAL_IDX RANGE 0 ${LAST_VAL} )
1364
- string (JSON VALUE GET "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} values ${VAL_IDX} )
1365
- list (APPEND VALUES "${VALUE} " )
1366
- endforeach ()
1440
+ if (NOT CAP_TYPE MATCHES "^(bool|uint16_t|uint32_t|uint64_t)$" )
1441
+ ERROR_WHILE_PARSING_ITEM (
1442
+ "Invalid CAP type \" ${CAP_TYPE} \" for ${CAP_NAME} \n "
1443
+ "Allowed types are: bool, uint16_t, uint32_t, uint64_t"
1444
+ )
1445
+ endif ()
1446
+
1447
+ string (JSON CAP_VALUES_LENGTH LENGTH "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} values )
1448
+
1449
+ set (VALUES "" )
1450
+ math (EXPR LAST_VAL "${CAP_VALUES_LENGTH} - 1" )
1451
+ foreach (VAL_IDX RANGE 0 ${LAST_VAL} )
1452
+ string (JSON VALUE GET "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} values ${VAL_IDX} )
1453
+ string (JSON VAL_TYPE TYPE "${IMPL_INPUTS} " ${INDEX} CAPS ${CAP_IDX} values ${VAL_IDX} )
1454
+
1455
+ if (NOT VAL_TYPE STREQUAL "NUMBER" )
1456
+ ERROR_WHILE_PARSING_ITEM (
1457
+ "Invalid CAP value \" ${VALUE} \" for CAP \" ${CAP_NAME} \" of type ${CAP_TYPE} \n "
1458
+ "Use numbers for uint*_t and 0/1 for bools."
1459
+ )
1460
+ endif ()
1461
+
1462
+ if (CAP_TYPE STREQUAL "bool" )
1463
+ if (NOT VALUE MATCHES "^[01]$" )
1464
+ ERROR_WHILE_PARSING_ITEM (
1465
+ "Invalid bool value \" ${VALUE} \" for ${CAP_NAME} \n "
1466
+ "Boolean CAPs can only have values 0 or 1."
1467
+ )
1468
+ endif ()
1469
+ endif ()
1470
+
1471
+ list (APPEND VALUES "${VALUE} " )
1472
+ endforeach ()
1367
1473
1368
1474
set (CAP_VALUES_${CAP_IDX} "${VALUES} " )
1369
1475
list (APPEND CAP_NAMES "${CAP_NAME} " )
@@ -1378,9 +1484,47 @@ struct DeviceConfigCaps
1378
1484
set (TARGET_INPUT "${CMAKE_CURRENT_SOURCE_DIR} /${TARGET_INPUT} " )
1379
1485
endif ()
1380
1486
1487
+ get_target_property (CANONICAL_IDENTIFIERS ${IMPL_TARGET} NBL_CANONICAL_IDENTIFIERS )
1488
+
1489
+ set (NEW_CANONICAL_IDENTIFIER "${IMPL_BINARY_DIR} /${BASE_KEY} " )
1490
+ if (CANONICAL_IDENTIFIERS )
1491
+ list (FIND CANONICAL_IDENTIFIERS "${NEW_CANONICAL_IDENTIFIER} " FOUND )
1492
+
1493
+ if (NOT FOUND STREQUAL -1 )
1494
+ string (JSON ITEM GET "${IMPL_INPUTS} " ${INDEX} )
1495
+ message (FATAL_ERROR "While parsing ${IMPL_TARGET} 's NSC compile rule\n ${ITEM} \n with binary directory \" ${IMPL_BINARY_DIR} \" ,\n canonical key \" ${BASE_KEY} \" already defined!" )
1496
+ endif ()
1497
+ endif ()
1498
+
1499
+ set_property (TARGET ${IMPL_TARGET} APPEND PROPERTY NBL_CANONICAL_IDENTIFIERS "${NEW_CANONICAL_IDENTIFIER} " )
1500
+
1501
+ set (HEADER_ITEM_VIEW [=[
1502
+ namespace @IMPL_NAMESPACE@ {
1503
+ template<>
1504
+ inline const nbl::core::string get_spirv_key<NBL_CORE_UNIQUE_STRING_LITERAL_TYPE("@BASE_KEY@")>
1505
+ (const nbl::video::SPhysicalDeviceLimits& limits, const nbl::video::SPhysicalDeviceFeatures& features)
1506
+ {
1507
+ nbl::core::string retval = "@BASE_KEY@";
1508
+ @RETVAL_EVAL@
1509
+ retval += ".spv";
1510
+ return retval;
1511
+ }
1512
+ }
1513
+
1514
+ ]=] )
1515
+ unset (RETVAL_EVAL )
1516
+ foreach (CAP ${CAP_NAMES} )
1517
+ string (CONFIGURE [=[
1518
+ retval += ".@CAP@_" + std::to_string(limits.@CAP@);
1519
+ ]=] RETVALUE_VIEW @ONLY )
1520
+ string (APPEND RETVAL_EVAL "${RETVALUE_VIEW} " )
1521
+ endforeach (CAP )
1522
+ string (CONFIGURE "${HEADER_ITEM_VIEW} " HEADER_ITEM_EVAL @ONLY )
1523
+ set_property (TARGET ${IMPL_TARGET} APPEND_STRING PROPERTY NBL_HEADER_CONTENT "${HEADER_ITEM_EVAL} " )
1524
+
1381
1525
function (GENERATE_KEYS PREFIX CAP_INDEX CAPS_EVAL_PART )
1382
1526
if (NUM_CAPS EQUAL 0 OR CAP_INDEX EQUAL ${NUM_CAPS} )
1383
- set (FINAL_KEY "${BASE_KEY}${PREFIX} " )
1527
+ set (FINAL_KEY "${BASE_KEY}${PREFIX} .spv" ) # always add ext even if its already there to make sure asset loader always is able to load as IShader
1384
1528
1385
1529
set (TARGET_OUTPUT "${IMPL_BINARY_DIR} /${FINAL_KEY} " )
1386
1530
set (CONFIG_FILE "${TARGET_OUTPUT} .config" )
@@ -1420,7 +1564,6 @@ struct DeviceConfigCaps
1420
1564
)
1421
1565
1422
1566
set_property (TARGET ${IMPL_TARGET} APPEND PROPERTY NBL_SPIRV_OUTPUTS "${TARGET_OUTPUT} " )
1423
-
1424
1567
return ()
1425
1568
endif ()
1426
1569
@@ -1430,7 +1573,7 @@ struct DeviceConfigCaps
1430
1573
set (VALUES "${${VAR_NAME} }" )
1431
1574
1432
1575
foreach (V IN LISTS VALUES )
1433
- set (NEW_PREFIX "${PREFIX} .${CURRENT_CAP} = ${V} " )
1576
+ set (NEW_PREFIX "${PREFIX} .${CURRENT_CAP} _ ${V} " )
1434
1577
set (NEW_EVAL "${CAPS_EVAL_PART} NBL_CONSTEXPR_STATIC_INLINE ${CURRENT_TYPE} ${CURRENT_CAP} = (${CURRENT_TYPE} ) ${V} ; // got permuted\n " )
1435
1578
math (EXPR NEXT_INDEX "${CAP_INDEX} + 1" )
1436
1579
GENERATE_KEYS ("${NEW_PREFIX} " "${NEXT_INDEX} " "${NEW_EVAL} " )
@@ -1440,6 +1583,7 @@ struct DeviceConfigCaps
1440
1583
GENERATE_KEYS ("" 0 "" )
1441
1584
endforeach ()
1442
1585
1586
+ unset (KEYS )
1443
1587
get_target_property (SPIRVs ${IMPL_TARGET} NBL_SPIRV_OUTPUTS )
1444
1588
foreach (SPIRV ${SPIRVs} )
1445
1589
get_source_file_property (CONFIG ${SPIRV} NBL_SPIRV_PERMUTATION_CONFIG )
@@ -1449,15 +1593,6 @@ struct DeviceConfigCaps
1449
1593
list (APPEND CONFIGS ${CONFIG} )
1450
1594
list (APPEND INPUTS ${INPUT} )
1451
1595
list (APPEND KEYS ${ACCESS_KEY} )
1452
-
1453
- if (NBL_LOG_VERBOSE )
1454
- get_source_file_property (BINARY_DIR ${SPIRV} NBL_SPIRV_BINARY_DIR )
1455
- message (STATUS "[${IMPL_TARGET} 's SPIRV]: ${SPIRV} " )
1456
- message (STATUS "-- BINARY_DIR: ${BINARY_DIR} " )
1457
- message (STATUS "-- ACCESS_KEY: ${ACCESS_KEY} " )
1458
- message (STATUS "-- CONFIG: ${CONFIG} " )
1459
- message (STATUS "-- INPUT: ${INPUT} " )
1460
- endif ()
1461
1596
endforeach ()
1462
1597
1463
1598
set (RTE "NSC Rules" )
@@ -1499,8 +1634,9 @@ function(NBL_CREATE_RESOURCE_ARCHIVE)
1499
1634
1500
1635
ADD_CUSTOM_BUILTIN_RESOURCES (${IMPL_TARGET} NBL_RESOURCES_TO_EMBED "${_BUNDLE_SEARCH_DIRECTORY_} " "${_BUNDLE_ARCHIVE_ABSOLUTE_PATH_} " "${_BUILTIN_RESOURCES_NAMESPACE_} " "${_OUTPUT_DIRECTORY_HEADER_} " "${_OUTPUT_DIRECTORY_SOURCE_} " "${_LINK_MODE_} " )
1501
1636
else ()
1502
- add_library (${IMPL_TARGET} INTERFACE )
1637
+ add_library (${IMPL_TARGET} INTERFACE ) # (***)
1503
1638
endif ()
1504
1639
1640
+ # TODO (***): actually I better have this in meta target created by NBL_CREATE_NSC_COMPILE_RULES, then I kill its INTERFACE when builtins are off
1505
1641
target_compile_definitions (${IMPL_TARGET} INTERFACE ${IMPL_MOUNT_POINT_DEFINE} = "${_BUNDLE_SEARCH_DIRECTORY_} " )
1506
1642
endfunction ()
0 commit comments