Merge upstream & update dependencies
This commit is contained in:
commit
0bd776df12
|
@ -9,3 +9,4 @@
|
|||
*.wgsl eol=lf
|
||||
*.h eol=lf
|
||||
*.cpp eol=lf
|
||||
*.bat eol=crlf
|
||||
|
|
|
@ -4,17 +4,20 @@
|
|||
/.cipd
|
||||
/.gclient
|
||||
/.gclient_entries
|
||||
/.gclient_previous_custom_vars
|
||||
/.gclient_previous_sync_commits
|
||||
/build
|
||||
/buildtools
|
||||
/testing
|
||||
/tools/bin
|
||||
/tools/clang
|
||||
/tools/cmake*
|
||||
/tools/golang
|
||||
/tools/memory
|
||||
/out
|
||||
|
||||
# Tint test validation cache file
|
||||
/test/tint/validation.cache
|
||||
|
||||
# Modified from https://www.gitignore.io/api/vim,macos,linux,emacs,windows,sublimetext,visualstudio,visualstudiocode,intellij
|
||||
|
||||
### Emacs ###
|
||||
|
@ -86,9 +89,6 @@ $RECYCLE.BIN/
|
|||
### Intellij ###
|
||||
.idea
|
||||
|
||||
### Dawn node tools binaries
|
||||
src/dawn/node/tools/bin/
|
||||
|
||||
### Cached node transpiled tools
|
||||
/.node_transpile_work_dir
|
||||
|
||||
|
@ -104,3 +104,4 @@ lcov.info
|
|||
### Clang-Tidy files
|
||||
all_findings.json
|
||||
|
||||
tint.dot
|
||||
|
|
|
@ -73,66 +73,14 @@
|
|||
// A symbolic link to this build directory is created at 'out/active'
|
||||
// which is used to track the active build directory.
|
||||
{
|
||||
"label": "gn gen",
|
||||
"label": "setup build",
|
||||
"type": "shell",
|
||||
"linux": {
|
||||
"command": "./tools/setup-build",
|
||||
"args": [
|
||||
"gn",
|
||||
"${input:buildType}",
|
||||
],
|
||||
},
|
||||
"osx": {
|
||||
"command": "./tools/setup-build",
|
||||
"args": [
|
||||
"gn",
|
||||
"${input:buildType}",
|
||||
],
|
||||
},
|
||||
"windows": {
|
||||
"command": "/C",
|
||||
"args": [
|
||||
"(IF \"${input:buildType}\" == \"Debug\" ( gn gen \"out\\${input:buildType}\" --args=is_debug=true ) ELSE ( gn gen \"out\\${input:buildType}\" --args=is_debug=false )) && (IF EXIST \"out\\active\" rmdir \"out\\active\" /q /s) && (mklink /j \"out\\active\" \"out\\${input:buildType}\")",
|
||||
],
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "cmd"
|
||||
},
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
},
|
||||
{
|
||||
"label": "cmake gen",
|
||||
"type": "shell",
|
||||
"linux": {
|
||||
"command": "./tools/setup-build",
|
||||
"args": [
|
||||
"cmake",
|
||||
"${input:buildType}",
|
||||
],
|
||||
},
|
||||
"osx": {
|
||||
"command": "./tools/setup-build",
|
||||
"args": [
|
||||
"cmake",
|
||||
"${input:buildType}",
|
||||
],
|
||||
},
|
||||
"windows": {
|
||||
"command": "/C",
|
||||
"args": [
|
||||
"echo TODO",
|
||||
],
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "cmd"
|
||||
},
|
||||
}
|
||||
},
|
||||
"command": "./tools/setup-build",
|
||||
"args": [
|
||||
"${input:buildSystem}",
|
||||
"${input:buildType}",
|
||||
"${input:buildArch}",
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
|
@ -177,19 +125,24 @@
|
|||
{
|
||||
"label": "push",
|
||||
"type": "shell",
|
||||
"command": "git",
|
||||
"args": [
|
||||
"push",
|
||||
"origin",
|
||||
"HEAD:refs/for/main"
|
||||
],
|
||||
"command": "./tools/push-to-gerrit",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
}
|
||||
},
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "buildSystem",
|
||||
"type": "pickString",
|
||||
"options": [
|
||||
"cmake",
|
||||
"gn",
|
||||
],
|
||||
"default": "gn",
|
||||
"description": "The build system",
|
||||
},
|
||||
{
|
||||
"id": "buildType",
|
||||
"type": "pickString",
|
||||
|
@ -200,5 +153,15 @@
|
|||
"default": "Debug",
|
||||
"description": "The type of build",
|
||||
},
|
||||
{
|
||||
"id": "buildArch",
|
||||
"type": "pickString",
|
||||
"options": [
|
||||
"native",
|
||||
"x86",
|
||||
],
|
||||
"default": "native",
|
||||
"description": "The build architecture",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
114
CMakeLists.txt
114
CMakeLists.txt
|
@ -77,6 +77,7 @@ function (set_if_not_defined name value description)
|
|||
endfunction()
|
||||
|
||||
# Default values for the backend-enabling options
|
||||
set(ENABLE_D3D11 OFF)
|
||||
set(ENABLE_D3D12 OFF)
|
||||
set(ENABLE_METAL OFF)
|
||||
set(ENABLE_OPENGLES OFF)
|
||||
|
@ -86,6 +87,7 @@ set(USE_WAYLAND OFF)
|
|||
set(USE_X11 OFF)
|
||||
set(BUILD_SAMPLES OFF)
|
||||
if (WIN32)
|
||||
set(ENABLE_D3D11 ON)
|
||||
set(ENABLE_D3D12 ON)
|
||||
if (NOT WINDOWS_STORE)
|
||||
# Enable Vulkan in win32 compilation only
|
||||
|
@ -119,6 +121,7 @@ option_if_not_defined(DAWN_ENABLE_TSAN "Enable thread sanitizer" OFF)
|
|||
option_if_not_defined(DAWN_ENABLE_MSAN "Enable memory sanitizer" OFF)
|
||||
option_if_not_defined(DAWN_ENABLE_UBSAN "Enable undefined behaviour sanitizer" OFF)
|
||||
|
||||
option_if_not_defined(DAWN_ENABLE_D3D11 "Enable compilation of the D3D11 backend" ${ENABLE_D3D11})
|
||||
option_if_not_defined(DAWN_ENABLE_D3D12 "Enable compilation of the D3D12 backend" ${ENABLE_D3D12})
|
||||
option_if_not_defined(DAWN_ENABLE_METAL "Enable compilation of the Metal backend" ${ENABLE_METAL})
|
||||
option_if_not_defined(DAWN_ENABLE_NULL "Enable compilation of the Null backend" ON)
|
||||
|
@ -133,9 +136,13 @@ option_if_not_defined(DAWN_USE_X11 "Enable support for X11 surface" ${USE_X11})
|
|||
option_if_not_defined(DAWN_BUILD_SAMPLES "Enables building Dawn's samples" ${BUILD_SAMPLES})
|
||||
option_if_not_defined(DAWN_BUILD_NODE_BINDINGS "Enables building Dawn's NodeJS bindings" OFF)
|
||||
option_if_not_defined(DAWN_ENABLE_SWIFTSHADER "Enables building Swiftshader as part of the build and Vulkan adapter discovery" OFF)
|
||||
option_if_not_defined(DAWN_BUILD_BENCHMARKS "Build Dawn benchmarks" OFF)
|
||||
|
||||
option_if_not_defined(DAWN_ENABLE_PIC "Build with Position-Independent-Code enabled" OFF)
|
||||
|
||||
option_if_not_defined(DAWN_EMIT_COVERAGE "Emit code coverage information" OFF)
|
||||
set_if_not_defined(LLVM_SOURCE_DIR "${Dawn_LLVM_SOURCE_DIR}" "Directory to an LLVM source checkout. Required to build turbo-cov")
|
||||
|
||||
if (DAWN_ENABLE_OPENGLES OR DAWN_ENABLE_DESKTOP_GL)
|
||||
set(TINT_DEFAULT_GLSL ON)
|
||||
else()
|
||||
|
@ -154,33 +161,39 @@ option_if_not_defined(TINT_BUILD_MSL_WRITER "Build the MSL output writer" ${DAWN
|
|||
option_if_not_defined(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" ${DAWN_ENABLE_VULKAN})
|
||||
option_if_not_defined(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON)
|
||||
|
||||
option_if_not_defined(TINT_BUILD_SYNTAX_TREE_WRITER "Build the syntax tree writer" OFF)
|
||||
option_if_not_defined(TINT_BUILD_IR "Build the IR" ON)
|
||||
|
||||
option_if_not_defined(TINT_BUILD_FUZZERS "Build fuzzers" OFF)
|
||||
option_if_not_defined(TINT_BUILD_SPIRV_TOOLS_FUZZER "Build SPIRV-Tools fuzzer" OFF)
|
||||
option_if_not_defined(TINT_BUILD_AST_FUZZER "Build AST fuzzer" OFF)
|
||||
option_if_not_defined(TINT_BUILD_REGEX_FUZZER "Build regex fuzzer" OFF)
|
||||
option_if_not_defined(TINT_BUILD_BENCHMARKS "Build benchmarks" OFF)
|
||||
option_if_not_defined(TINT_BUILD_BENCHMARKS "Build Tint benchmarks" OFF)
|
||||
option_if_not_defined(TINT_BUILD_TESTS "Build tests" OFF)
|
||||
option_if_not_defined(TINT_BUILD_AS_OTHER_OS "Override OS detection to force building of *_other.cc files" OFF)
|
||||
option_if_not_defined(TINT_BUILD_REMOTE_COMPILE "Build the remote-compile tool for validating shaders on a remote machine" OFF)
|
||||
|
||||
set_if_not_defined(TINT_EXTERNAL_BENCHMARK_CORPUS_DIR "" "Directory that holds a corpus of external shaders to benchmark.")
|
||||
|
||||
option_if_not_defined(TINT_ENABLE_BREAK_IN_DEBUGGER "Enable tint::debugger::Break()" OFF)
|
||||
option_if_not_defined(TINT_EMIT_COVERAGE "Emit code coverage information" OFF)
|
||||
option_if_not_defined(TINT_CHECK_CHROMIUM_STYLE "Check for [chromium-style] issues during build" OFF)
|
||||
option_if_not_defined(TINT_SYMBOL_STORE_DEBUG_NAME "Enable storing of name in tint::ast::Symbol to help debugging the AST" OFF)
|
||||
option_if_not_defined(TINT_RANDOMIZE_HASHES "Randomize the hash seed value to detect non-deterministic output" OFF)
|
||||
|
||||
# Recommended setting for compability with future abseil releases.
|
||||
set(ABSL_PROPAGATE_CXX_STD ON)
|
||||
|
||||
set_if_not_defined(DAWN_THIRD_PARTY_DIR "${Dawn_SOURCE_DIR}/third_party" "Directory in which to find third-party dependencies.")
|
||||
set_if_not_defined(DAWN_VULKAN_DEPS_DIR "${DAWN_THIRD_PARTY_DIR}/vulkan-deps" "Directory in which to find vulkan-deps")
|
||||
|
||||
set_if_not_defined(DAWN_ABSEIL_DIR "${DAWN_THIRD_PARTY_DIR}/abseil-cpp" "Directory in which to find Abseil")
|
||||
set_if_not_defined(DAWN_GLFW_DIR "${DAWN_THIRD_PARTY_DIR}/glfw" "Directory in which to find GLFW")
|
||||
set_if_not_defined(DAWN_JINJA2_DIR "${DAWN_THIRD_PARTY_DIR}/jinja2" "Directory in which to find Jinja2")
|
||||
set_if_not_defined(DAWN_MARKUPSAFE_DIR "${DAWN_THIRD_PARTY_DIR}/markupsafe" "Directory in which to find MarkupSafe")
|
||||
set_if_not_defined(DAWN_KHRONOS_DIR "${DAWN_THIRD_PARTY_DIR}/khronos" "Directory in which to find Khronos GL headers")
|
||||
set_if_not_defined(DAWN_SPIRV_HEADERS_DIR "${DAWN_THIRD_PARTY_DIR}/vulkan-deps/spirv-headers/src" "Directory in which to find SPIRV-Headers")
|
||||
set_if_not_defined(DAWN_SPIRV_TOOLS_DIR "${DAWN_THIRD_PARTY_DIR}/vulkan-deps/spirv-tools/src" "Directory in which to find SPIRV-Tools")
|
||||
set_if_not_defined(DAWN_SWIFTSHADER_DIR "${DAWN_THIRD_PARTY_DIR}/swiftshader" "Directory in which to find swiftshader")
|
||||
set_if_not_defined(DAWN_TINT_DIR "${Dawn_SOURCE_DIR}" "Directory in which to find Tint")
|
||||
set_if_not_defined(DAWN_VULKAN_DEPS_DIR "${DAWN_THIRD_PARTY_DIR}/vulkan-deps" "Directory in which to find vulkan-deps")
|
||||
|
||||
set_if_not_defined(DAWN_SPIRV_TOOLS_DIR "${DAWN_VULKAN_DEPS_DIR}/spirv-tools/src" "Directory in which to find SPIRV-Tools")
|
||||
set_if_not_defined(DAWN_SPIRV_HEADERS_DIR "${DAWN_VULKAN_DEPS_DIR}/spirv-headers/src" "Directory in which to find SPIRV-Headers")
|
||||
set_if_not_defined(DAWN_VULKAN_HEADERS_DIR "${DAWN_VULKAN_DEPS_DIR}/vulkan-headers/src" "Directory in which to find Vulkan-Headers")
|
||||
set_if_not_defined(DAWN_VULKAN_TOOLS_DIR "${DAWN_VULKAN_DEPS_DIR}/vulkan-tools/src" "Directory in which to find Vulkan-Tools")
|
||||
|
||||
|
@ -190,6 +203,8 @@ set_if_not_defined(NODE_API_HEADERS_DIR "${DAWN_THIRD_PARTY_DIR}/node-api-header
|
|||
set_if_not_defined(WEBGPU_IDL_PATH "${DAWN_THIRD_PARTY_DIR}/gpuweb/webgpu.idl" "Path to the webgpu.idl definition file")
|
||||
set_if_not_defined(GO_EXECUTABLE "go" "Golang executable for running the IDL generator")
|
||||
|
||||
option_if_not_defined(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" OFF)
|
||||
|
||||
# Much of the backend code is shared among desktop OpenGL and OpenGL ES
|
||||
if (${DAWN_ENABLE_DESKTOP_GL} OR ${DAWN_ENABLE_OPENGLES})
|
||||
set(DAWN_ENABLE_OPENGL ON)
|
||||
|
@ -255,6 +270,7 @@ if (${TINT_BUILD_REGEX_FUZZER})
|
|||
set(TINT_BUILD_HLSL_WRITER ON CACHE BOOL "Build HLSL writer" FORCE)
|
||||
endif()
|
||||
|
||||
message(STATUS "Dawn build D3D11 backend: ${DAWN_ENABLE_D3D11}")
|
||||
message(STATUS "Dawn build D3D12 backend: ${DAWN_ENABLE_D3D12}")
|
||||
message(STATUS "Dawn build Metal backend: ${DAWN_ENABLE_METAL}")
|
||||
message(STATUS "Dawn build Vulkan backend: ${DAWN_ENABLE_VULKAN}")
|
||||
|
@ -269,6 +285,7 @@ message(STATUS "Dawn build X11 support: ${DAWN_USE_X11}")
|
|||
message(STATUS "Dawn build samples: ${DAWN_BUILD_SAMPLES}")
|
||||
message(STATUS "Dawn build Node bindings: ${DAWN_BUILD_NODE_BINDINGS}")
|
||||
message(STATUS "Dawn build Swiftshader: ${DAWN_ENABLE_SWIFTSHADER}")
|
||||
message(STATUS "Dawn build benchmarks: ${DAWN_BUILD_BENCHMARKS}")
|
||||
|
||||
message(STATUS "Dawn build PIC: ${DAWN_ENABLE_PIC}")
|
||||
|
||||
|
@ -287,6 +304,8 @@ message(STATUS "Tint build HLSL writer: ${TINT_BUILD_HLSL_WRITER}")
|
|||
message(STATUS "Tint build MSL writer: ${TINT_BUILD_MSL_WRITER}")
|
||||
message(STATUS "Tint build SPIR-V writer: ${TINT_BUILD_SPV_WRITER}")
|
||||
message(STATUS "Tint build WGSL writer: ${TINT_BUILD_WGSL_WRITER}")
|
||||
message(STATUS "Tint build Syntax Tree writer: ${TINT_BUILD_SYNTAX_TREE_WRITER}")
|
||||
message(STATUS "Tint build IR: ${TINT_BUILD_IR}")
|
||||
message(STATUS "Tint build fuzzers: ${TINT_BUILD_FUZZERS}")
|
||||
message(STATUS "Tint build SPIRV-Tools fuzzer: ${TINT_BUILD_SPIRV_TOOLS_FUZZER}")
|
||||
message(STATUS "Tint build AST fuzzer: ${TINT_BUILD_AST_FUZZER}")
|
||||
|
@ -295,6 +314,8 @@ message(STATUS "Tint build benchmarks: ${TINT_BUILD_BENCHMARKS}")
|
|||
message(STATUS "Tint build tests: ${TINT_BUILD_TESTS}")
|
||||
message(STATUS "Tint build checking [chromium-style]: ${TINT_CHECK_CHROMIUM_STYLE}")
|
||||
message(STATUS "Tint build remote-compile tool: ${TINT_BUILD_REMOTE_COMPILE}")
|
||||
message(STATUS "Tint external benchmark corpus dir: ${TINT_EXTERNAL_BENCHMARK_CORPUS_DIR}")
|
||||
|
||||
|
||||
if (NOT ${TINT_LIB_FUZZING_ENGINE_LINK_OPTIONS} STREQUAL "")
|
||||
message(STATUS "Using provided LIB_FUZZING_ENGINE options: ${TINT_LIB_FUZZING_ENGINE_LINK_OPTIONS}")
|
||||
|
@ -303,7 +324,6 @@ endif()
|
|||
message(STATUS "Using python3")
|
||||
find_package(PythonInterp 3 REQUIRED)
|
||||
|
||||
|
||||
################################################################################
|
||||
# common_compile_options - sets compiler and linker options common for dawn and
|
||||
# tint on the given target
|
||||
|
@ -313,7 +333,9 @@ function(common_compile_options TARGET)
|
|||
target_compile_options(${TARGET} PRIVATE
|
||||
-fno-exceptions
|
||||
-fno-rtti
|
||||
-fvisibility-inlines-hidden
|
||||
|
||||
-Wno-deprecated-builtins
|
||||
-Wno-unknown-warning-option
|
||||
)
|
||||
|
||||
if (${DAWN_ENABLE_MSAN})
|
||||
|
@ -326,10 +348,27 @@ function(common_compile_options TARGET)
|
|||
target_compile_options(${TARGET} PUBLIC -fsanitize=thread)
|
||||
target_link_options(${TARGET} PUBLIC -fsanitize=thread)
|
||||
elseif (${DAWN_ENABLE_UBSAN})
|
||||
target_compile_options(${TARGET} PUBLIC -fsanitize=undefined)
|
||||
target_link_options(${TARGET} PUBLIC -fsanitize=undefined)
|
||||
target_compile_options(${TARGET} PUBLIC -fsanitize=undefined -fsanitize=float-divide-by-zero)
|
||||
target_link_options(${TARGET} PUBLIC -fsanitize=undefined -fsanitize=float-divide-by-zero)
|
||||
endif()
|
||||
endif(COMPILER_IS_LIKE_GNU)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(${TARGET} PUBLIC /utf-8)
|
||||
endif()
|
||||
|
||||
if (DAWN_EMIT_COVERAGE)
|
||||
target_compile_definitions(${TARGET} PRIVATE "DAWN_EMIT_COVERAGE")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
target_compile_options(${TARGET} PRIVATE "--coverage")
|
||||
target_link_options(${TARGET} PRIVATE "gcov")
|
||||
elseif(COMPILER_IS_CLANG OR COMPILER_IS_CLANG_CL)
|
||||
target_compile_options(${TARGET} PRIVATE "-fprofile-instr-generate" "-fcoverage-mapping")
|
||||
target_link_options(${TARGET} PRIVATE "-fprofile-instr-generate" "-fcoverage-mapping")
|
||||
else()
|
||||
message(FATAL_ERROR "Coverage generation not supported for the ${CMAKE_CXX_COMPILER_ID} toolchain")
|
||||
endif()
|
||||
endif(DAWN_EMIT_COVERAGE)
|
||||
endfunction()
|
||||
|
||||
if (${DAWN_ENABLE_TSAN})
|
||||
|
@ -341,6 +380,12 @@ endif()
|
|||
# Dawn's public and internal "configs"
|
||||
################################################################################
|
||||
|
||||
set(IS_DEBUG_BUILD 0)
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
|
||||
if ((NOT ${build_type} STREQUAL "RELEASE") AND (NOT ${build_type} STREQUAL "RELWITHDEBINFO"))
|
||||
set(IS_DEBUG_BUILD 1)
|
||||
endif()
|
||||
|
||||
# The public config contains only the include paths for the Dawn headers.
|
||||
add_library(dawn_public_config INTERFACE)
|
||||
target_include_directories(dawn_public_config INTERFACE
|
||||
|
@ -357,9 +402,12 @@ target_include_directories(dawn_internal_config INTERFACE
|
|||
target_link_libraries(dawn_internal_config INTERFACE dawn_public_config)
|
||||
|
||||
# Compile definitions for the internal config
|
||||
if (DAWN_ALWAYS_ASSERT OR CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
if (DAWN_ALWAYS_ASSERT OR IS_DEBUG_BUILD)
|
||||
target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_ASSERTS")
|
||||
endif()
|
||||
if (DAWN_ENABLE_D3D11)
|
||||
target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_BACKEND_D3D11")
|
||||
endif()
|
||||
if (DAWN_ENABLE_D3D12)
|
||||
target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_BACKEND_D3D12")
|
||||
endif()
|
||||
|
@ -421,10 +469,13 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_SIMULATE_ID STREQUAL
|
|||
set(COMPILER_IS_CLANG_CL TRUE)
|
||||
endif()
|
||||
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") OR
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") OR
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND
|
||||
(NOT COMPILER_IS_CLANG_CL)))
|
||||
set(COMPILER_IS_CLANG TRUE)
|
||||
endif()
|
||||
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR COMPILER_IS_CLANG)
|
||||
set(COMPILER_IS_LIKE_GNU TRUE)
|
||||
endif()
|
||||
|
||||
|
@ -488,20 +539,11 @@ function(tint_core_compile_options TARGET)
|
|||
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_MSL_WRITER=$<BOOL:${TINT_BUILD_MSL_WRITER}>)
|
||||
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_SPV_WRITER=$<BOOL:${TINT_BUILD_SPV_WRITER}>)
|
||||
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_WGSL_WRITER=$<BOOL:${TINT_BUILD_WGSL_WRITER}>)
|
||||
target_compile_definitions(${TARGET} PUBLIC
|
||||
-DTINT_BUILD_SYNTAX_TREE_WRITER=$<BOOL:${TINT_BUILD_SYNTAX_TREE_WRITER}>)
|
||||
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_IR=$<BOOL:${TINT_BUILD_IR}>)
|
||||
|
||||
common_compile_options(${TARGET})
|
||||
|
||||
if (TINT_EMIT_COVERAGE)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
target_compile_options(${TARGET} PRIVATE "--coverage")
|
||||
target_link_options(${TARGET} PRIVATE "gcov")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
target_compile_options(${TARGET} PRIVATE "-fprofile-instr-generate" "-fcoverage-mapping")
|
||||
target_link_options(${TARGET} PRIVATE "-fprofile-instr-generate" "-fcoverage-mapping")
|
||||
else()
|
||||
message(FATAL_ERROR "Coverage generation not supported for the ${CMAKE_CXX_COMPILER_ID} toolchain")
|
||||
endif()
|
||||
endif(TINT_EMIT_COVERAGE)
|
||||
endfunction()
|
||||
|
||||
function(tint_default_compile_options TARGET)
|
||||
|
@ -521,9 +563,11 @@ function(tint_default_compile_options TARGET)
|
|||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-format-pedantic
|
||||
-Wno-poison-system-directories
|
||||
-Wno-return-std-move-in-c++11
|
||||
-Wno-unknown-warning-option
|
||||
-Wno-undefined-var-template
|
||||
-Wno-unsafe-buffer-usage
|
||||
-Wno-used-but-marked-unused
|
||||
-Weverything
|
||||
)
|
||||
|
@ -534,8 +578,7 @@ function(tint_default_compile_options TARGET)
|
|||
${COMMON_GNU_OPTIONS}
|
||||
)
|
||||
|
||||
if (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR
|
||||
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang"))
|
||||
if (COMPILER_IS_CLANG)
|
||||
target_compile_options(${TARGET} PRIVATE
|
||||
${COMMON_CLANG_OPTIONS}
|
||||
)
|
||||
|
@ -583,6 +626,15 @@ function(tint_default_compile_options TARGET)
|
|||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (TINT_RANDOMIZE_HASHES)
|
||||
if(NOT DEFINED TINT_HASH_SEED)
|
||||
string(RANDOM LENGTH 16 ALPHABET "0123456789abcdef" seed)
|
||||
set(TINT_HASH_SEED "0x${seed}" CACHE STRING "Tint hash seed value")
|
||||
message("Using TINT_HASH_SEED: ${TINT_HASH_SEED}")
|
||||
endif()
|
||||
target_compile_definitions(${TARGET} PUBLIC "-DTINT_HASH_SEED=${TINT_HASH_SEED}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
|
@ -625,9 +677,11 @@ add_custom_target(tint-format
|
|||
COMMENT "Running formatter"
|
||||
VERBATIM)
|
||||
|
||||
if (DAWN_EMIT_COVERAGE)
|
||||
add_subdirectory(tools/src/cmd/turbo-cov)
|
||||
|
||||
if (TINT_EMIT_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# Generates a lcov.info file at the project root.
|
||||
# The tint-generate-coverage target generates a lcov.info file at the project
|
||||
# root, holding the code coverage for all the tint_unitests.
|
||||
# This can be used by tools such as VSCode's Coverage Gutters extension to
|
||||
# visualize code coverage in the editor.
|
||||
get_filename_component(CLANG_BIN_DIR ${CMAKE_C_COMPILER} DIRECTORY)
|
||||
|
|
73
DEPS
73
DEPS
|
@ -17,6 +17,9 @@ vars = {
|
|||
'dawn_cmake_version': 'version:2@3.23.3',
|
||||
'dawn_cmake_win32_sha1': 'b106d66bcdc8a71ea2cdf5446091327bfdb1bcd7',
|
||||
'dawn_gn_version': 'git_revision:bd99dbf98cbdefe18a4128189665c5761263bcfb',
|
||||
# ninja CIPD package version.
|
||||
# https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja
|
||||
'dawn_ninja_version': 'version:2@1.11.1.chromium.6',
|
||||
'dawn_go_version': 'version:2@1.18.4',
|
||||
|
||||
'node_darwin_arm64_sha': '31859fc1fa0994a95f44f09c367d6ff63607cfde',
|
||||
|
@ -34,14 +37,14 @@ vars = {
|
|||
deps = {
|
||||
# Dependencies required to use GN/Clang in standalone
|
||||
'build': {
|
||||
'url': '{chromium_git}/chromium/src/build@f14f6d206b9a0c81a0fefba487bcba0d90ddb5fe',
|
||||
'url': '{chromium_git}/chromium/src/build@1103ef535ca1e100db5d4e59781a4e59369a9818',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
'buildtools': {
|
||||
'url': '{chromium_git}/chromium/src/buildtools@fe57e98eeb2172d7517f6dec1072ca641a019893',
|
||||
'url': '{chromium_git}/chromium/src/buildtools@2ff42d2008f09f65de12e70c6ff0ad58ddb090ad',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
'buildtools/clang_format/script': {
|
||||
'third_party/clang-format/script': {
|
||||
'url': '{chromium_git}/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@8b525d2747f2584fc35d8c7e612e66f377858df7',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
@ -71,17 +74,17 @@ deps = {
|
|||
},
|
||||
|
||||
'buildtools/third_party/libc++/trunk': {
|
||||
'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxx.git@eb79671bfbedd77b747d01dee8c0479ff1693f88',
|
||||
'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxx.git@c1341b9a1a7de7c193a23bf003d5479c48957f7d',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
||||
'buildtools/third_party/libc++abi/trunk': {
|
||||
'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxxabi.git@b954e3e65634a9e2f7b595598a30c455f5f2eb26',
|
||||
'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxxabi.git@f7460fc60ab56553f0b3b0853f1ea60aa51b9478',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
||||
'tools/clang': {
|
||||
'url': '{chromium_git}/chromium/src/tools/clang@3d8d88e8bb600789ba3e798f38ff314521aac524',
|
||||
'url': '{chromium_git}/chromium/src/tools/clang@effd9257d456f2d42e9e22fa4f37a24d8cf0b5b5',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
'tools/clang/dsymutil': {
|
||||
|
@ -95,16 +98,20 @@ deps = {
|
|||
|
||||
# Testing, GTest and GMock
|
||||
'testing': {
|
||||
'url': '{chromium_git}/chromium/src/testing@1f497ac0b0afc242222780a4789d13fbf00073eb',
|
||||
'url': '{chromium_git}/chromium/src/testing@166db27fd0d53afc0c716b1ae9c15725e380871f',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
'third_party/googletest': {
|
||||
'url': '{chromium_git}/external/github.com/google/googletest@bda85449f48f2d80a494c8c07766b6aba3170f3b',
|
||||
'url': '{chromium_git}/external/github.com/google/googletest@7a7231c442484be389fdf01594310349ca0e42a8',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
# This is a dependency of //testing
|
||||
'third_party/catapult': {
|
||||
'url': '{chromium_git}/catapult.git@fa35beefb3429605035f98211ddb8750dee6a13d',
|
||||
'url': '{chromium_git}/catapult.git@c1e70d412ce01fb194f73f7abfdac710aae87dae',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
'third_party/google_benchmark/src': {
|
||||
'url': '{chromium_git}/external/github.com/google/benchmark.git' + '@' + 'efc89f0b524780b1994d5dddd83a92718e5be492',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
||||
|
@ -129,17 +136,17 @@ deps = {
|
|||
},
|
||||
|
||||
'third_party/angle': {
|
||||
'url': '{chromium_git}/angle/angle@5ef3960bc1f10d180331a8134b0d11139fa1f913',
|
||||
'url': '{chromium_git}/angle/angle@ff110417bb04e9bc13079eeed99940009d9c3ce1',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
||||
'third_party/swiftshader': {
|
||||
'url': '{swiftshader_git}/SwiftShader@476165cc7c0c7247869c13f7f80dd25ec1fd2b03',
|
||||
'url': '{swiftshader_git}/SwiftShader@f549d5e6c6635ec8b75fb544a6bdc9f48bfb1dd3',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
||||
'third_party/vulkan-deps': {
|
||||
'url': '{chromium_git}/vulkan-deps@c5f01bfc31ec5b7165eebf9f241890744edc7789',
|
||||
'url': '{chromium_git}/vulkan-deps@25c584aa4cec2d79706854dafbd52392389d8004',
|
||||
'condition': 'dawn_standalone',
|
||||
},
|
||||
|
||||
|
@ -155,7 +162,7 @@ deps = {
|
|||
|
||||
# WebGPU CTS - not used directly by Dawn, only transitively by Chromium.
|
||||
'third_party/webgpu-cts': {
|
||||
'url': '{chromium_git}/external/github.com/gpuweb/cts@27dc745ca167d1e9eb956947f2109441dca0b4f7',
|
||||
'url': '{chromium_git}/external/github.com/gpuweb/cts@b033a4f1ae4a0e19ae4d5563fae023001bbf570f',
|
||||
'condition': 'build_with_chromium',
|
||||
},
|
||||
|
||||
|
@ -169,12 +176,11 @@ deps = {
|
|||
'condition': 'dawn_node',
|
||||
},
|
||||
'third_party/gpuweb': {
|
||||
'url': '{github_git}/gpuweb/gpuweb.git@3c4734b09c68eb800b15da5e9ecefeca735fa7df',
|
||||
'url': '{github_git}/gpuweb/gpuweb.git@2e75d5e68e80e4c28575c7836ee00ca22cf4ca63',
|
||||
'condition': 'dawn_node',
|
||||
},
|
||||
|
||||
'tools/golang': {
|
||||
'condition': 'dawn_node',
|
||||
'packages': [{
|
||||
'package': 'infra/3pp/tools/go/${{platform}}',
|
||||
'version': Var('dawn_go_version'),
|
||||
|
@ -191,11 +197,17 @@ deps = {
|
|||
'dep_type': 'cipd',
|
||||
},
|
||||
|
||||
# Misc dependencies inherited from Tint
|
||||
'third_party/benchmark': {
|
||||
'url': '{chromium_git}/external/github.com/google/benchmark.git@e991355c02b93fe17713efe04cbc2e278e00fdbd',
|
||||
'condition': 'dawn_standalone',
|
||||
'third_party/ninja': {
|
||||
'packages': [
|
||||
{
|
||||
'package': 'infra/3pp/tools/ninja/${{platform}}',
|
||||
'version': Var('dawn_ninja_version'),
|
||||
}
|
||||
],
|
||||
'dep_type': 'cipd',
|
||||
},
|
||||
|
||||
# Misc dependencies inherited from Tint
|
||||
'third_party/protobuf': {
|
||||
'url': '{chromium_git}/external/github.com/protocolbuffers/protobuf.git@fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a',
|
||||
'condition': 'dawn_standalone',
|
||||
|
@ -226,6 +238,18 @@ hooks = [
|
|||
'condition': 'dawn_standalone and checkout_mac',
|
||||
'action': ['python3', 'build/mac_toolchain.py'],
|
||||
},
|
||||
{
|
||||
# Case-insensitivity for the Win SDK. Must run before win_toolchain below.
|
||||
'name': 'ciopfs_linux',
|
||||
'pattern': '.',
|
||||
'condition': 'dawn_standalone and checkout_win and host_os == "linux"',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-browser-clang/ciopfs',
|
||||
'-s', 'build/ciopfs.sha1',
|
||||
]
|
||||
},
|
||||
{
|
||||
# Update the Windows toolchain if necessary. Must run before 'clang' below.
|
||||
'name': 'win_toolchain',
|
||||
|
@ -261,6 +285,17 @@ hooks = [
|
|||
'-s', 'build/toolchain/win/rc/win/rc.exe.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'rc_linux',
|
||||
'pattern': '.',
|
||||
'condition': 'dawn_standalone and checkout_win and host_os == "linux"',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-browser-clang/rc',
|
||||
'-s', 'build/toolchain/win/rc/linux64/rc.sha1',
|
||||
]
|
||||
},
|
||||
# Pull clang-format binaries using checked-in hashes.
|
||||
{
|
||||
'name': 'clang_format_win',
|
||||
|
|
3
OWNERS
3
OWNERS
|
@ -7,7 +7,8 @@ dsinclair@chromium.org
|
|||
enga@chromium.org
|
||||
jiawei.shao@intel.com
|
||||
|
||||
# TODO(dawn:1337): Move this file in src/dawn.
|
||||
# TODO(crbug.com/dawn/1339): Move dawn.json into src/dawn.
|
||||
per-file dawn.json=file://src/dawn/OWNERS
|
||||
|
||||
per-file DEPS=*
|
||||
per-file README.md=file://docs/OWNERS
|
||||
|
|
36
PRESUBMIT.py
36
PRESUBMIT.py
|
@ -114,7 +114,7 @@ def _NonInclusiveFileFilter(file):
|
|||
"src/dawn/native/metal/BackendMTL.mm", # OSX Constant
|
||||
"src/dawn/native/vulkan/SamplerVk.cpp", # External URL
|
||||
"src/dawn/native/vulkan/TextureVk.cpp", # External URL
|
||||
"src/dawn/node/tools/src/cmd/run-cts/main.go", # Terminal type name
|
||||
"src/tools/src/cmd/run-cts/main.go", # Terminal type name
|
||||
"src/dawn/samples/ComputeBoids.cpp", # External URL
|
||||
"src/dawn/tests/end2end/DepthBiasTests.cpp", # External URL
|
||||
"src/tint/transform/canonicalize_entry_point_io.cc", # External URL
|
||||
|
@ -127,14 +127,42 @@ def _NonInclusiveFileFilter(file):
|
|||
return file.LocalPath() not in filter_list
|
||||
|
||||
|
||||
def _CheckNoStaleGen(input_api, output_api):
|
||||
results = []
|
||||
try:
|
||||
go = input_api.os_path.join(input_api.change.RepositoryRoot(), "tools",
|
||||
"golang", "bin", "go")
|
||||
if input_api.is_windows:
|
||||
go += '.exe'
|
||||
input_api.subprocess.check_call_out(
|
||||
[go, "run", "tools/src/cmd/gen/main.go", "--check-stale"],
|
||||
stdout=input_api.subprocess.PIPE,
|
||||
stderr=input_api.subprocess.PIPE,
|
||||
cwd=input_api.change.RepositoryRoot())
|
||||
except input_api.subprocess.CalledProcessError as e:
|
||||
if input_api.is_committing:
|
||||
results.append(output_api.PresubmitError('%s' % (e, )))
|
||||
else:
|
||||
results.append(output_api.PresubmitPromptWarning('%s' % (e, )))
|
||||
return results
|
||||
|
||||
|
||||
def _DoCommonChecks(input_api, output_api):
|
||||
results = []
|
||||
results.extend(_CheckNoStaleGen(input_api, output_api))
|
||||
results.extend(
|
||||
input_api.canned_checks.CheckChangedLUCIConfigs(input_api, output_api))
|
||||
|
||||
result_factory = output_api.PresubmitPromptWarning
|
||||
if input_api.is_committing:
|
||||
result_factory = output_api.PresubmitError
|
||||
|
||||
results.extend(
|
||||
input_api.canned_checks.CheckPatchFormatted(input_api,
|
||||
output_api,
|
||||
check_python=True))
|
||||
input_api.canned_checks.CheckPatchFormatted(
|
||||
input_api,
|
||||
output_api,
|
||||
check_python=True,
|
||||
result_factory=result_factory))
|
||||
results.extend(
|
||||
input_api.canned_checks.CheckChangeHasDescription(
|
||||
input_api, output_api))
|
||||
|
|
|
@ -17,6 +17,7 @@ import("//build_overrides/vulkan_common.gni")
|
|||
# These are variables that are overridable by projects that include Dawn.
|
||||
# The values in this file are the defaults for when we are building from
|
||||
# Dawn's repository.
|
||||
vvl_spirv_headers_dir = "//third_party/vulkan-deps/spirv-headers/src"
|
||||
vvl_spirv_tools_dir = "//third_party/vulkan-deps/spirv-tools/src"
|
||||
vvl_glslang_dir = "//third_party/vulkan-deps/glslang/src"
|
||||
|
||||
|
|
|
@ -15,5 +15,4 @@
|
|||
import("//build/config/ozone.gni")
|
||||
|
||||
# Dawn has no wayland third-party dir
|
||||
use_system_libwayland = true
|
||||
wayland_gn_dir = ""
|
||||
|
|
336
dawn.json
336
dawn.json
|
@ -53,7 +53,8 @@
|
|||
"members": [
|
||||
{"name": "compatible surface", "type": "surface", "optional": true},
|
||||
{"name": "power preference", "type": "power preference", "default": "undefined"},
|
||||
{"name": "force fallback adapter", "type": "bool", "default": "false"}
|
||||
{"name": "force fallback adapter", "type": "bool", "default": "false"},
|
||||
{"name": "compatibility mode", "type": "bool", "default": "false", "tags": ["dawn", "emscripten"]}
|
||||
]
|
||||
},
|
||||
"request adapter status": {
|
||||
|
@ -77,7 +78,13 @@
|
|||
},
|
||||
"adapter": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "get instance",
|
||||
"tags": ["dawn"],
|
||||
"returns": "instance"
|
||||
},
|
||||
{
|
||||
"name": "get limits",
|
||||
"returns": "bool",
|
||||
|
@ -134,7 +141,8 @@
|
|||
{"name": "name", "type": "char", "annotation": "const*", "length": "strlen"},
|
||||
{"name": "driver description", "type": "char", "annotation": "const*", "length": "strlen"},
|
||||
{"name": "adapter type", "type": "adapter type"},
|
||||
{"name": "backend type", "type": "backend type"}
|
||||
{"name": "backend type", "type": "backend type"},
|
||||
{"name": "compatibility mode", "type": "bool", "default": "false", "tags": ["dawn", "emscripten"]}
|
||||
]
|
||||
},
|
||||
"adapter type": {
|
||||
|
@ -155,19 +163,21 @@
|
|||
{"name": "required features count", "type": "uint32_t", "default": 0},
|
||||
{"name": "required features", "type": "feature name", "annotation": "const*", "length": "required features count", "default": "nullptr"},
|
||||
{"name": "required limits", "type": "required limits", "annotation": "const*", "optional": true},
|
||||
{"name": "default queue", "type": "queue descriptor"}
|
||||
{"name": "default queue", "type": "queue descriptor"},
|
||||
{"name": "device lost callback", "type": "device lost callback", "default": "nullptr"},
|
||||
{"name": "device lost userdata", "type": "void *", "default": "nullptr"}
|
||||
]
|
||||
},
|
||||
"dawn toggles device descriptor": {
|
||||
"dawn toggles descriptor": {
|
||||
"tags": ["dawn", "native"],
|
||||
"category": "structure",
|
||||
"chained": "in",
|
||||
"chain roots": ["device descriptor"],
|
||||
"chain roots": ["instance descriptor", "device descriptor"],
|
||||
"members": [
|
||||
{"name": "force enabled toggles count", "type": "uint32_t", "default": 0},
|
||||
{"name": "force enabled toggles", "type": "char", "annotation": "const*const*", "length": "force enabled toggles count"},
|
||||
{"name": "force disabled toggles count", "type": "uint32_t", "default": 0},
|
||||
{"name": "force disabled toggles", "type": "char", "annotation": "const*const*", "length": "force disabled toggles count"}
|
||||
{"name": "enabled toggles count", "type": "uint32_t", "default": 0},
|
||||
{"name": "enabled toggles", "type": "char", "annotation": "const*const*", "length": "enabled toggles count"},
|
||||
{"name": "disabled toggles count", "type": "uint32_t", "default": 0},
|
||||
{"name": "disabled toggles", "type": "char", "annotation": "const*const*", "length": "disabled toggles count"}
|
||||
]
|
||||
},
|
||||
"dawn cache device descriptor" : {
|
||||
|
@ -220,7 +230,7 @@
|
|||
{"name": "binding", "type": "uint32_t"},
|
||||
{"name": "buffer", "type": "buffer", "optional": true},
|
||||
{"name": "offset", "type": "uint64_t", "default": "0"},
|
||||
{"name": "size", "type": "uint64_t"},
|
||||
{"name": "size", "type": "uint64_t", "default": "WGPU_WHOLE_SIZE"},
|
||||
{"name": "sampler", "type": "sampler", "optional": true},
|
||||
{"name": "texture view", "type": "texture view", "optional": true}
|
||||
]
|
||||
|
@ -445,6 +455,10 @@
|
|||
"name": "get size",
|
||||
"returns": "uint64_t"
|
||||
},
|
||||
{
|
||||
"name": "get map state",
|
||||
"returns": "buffer map state"
|
||||
},
|
||||
{
|
||||
"name": "unmap"
|
||||
},
|
||||
|
@ -475,11 +489,22 @@
|
|||
"emscripten_no_enum_table": true,
|
||||
"values": [
|
||||
{"value": 0, "name": "success"},
|
||||
{"value": 1, "name": "error"},
|
||||
{"value": 1, "name": "validation error"},
|
||||
{"value": 2, "name": "unknown"},
|
||||
{"value": 3, "name": "device lost"},
|
||||
{"value": 4, "name": "destroyed before callback"},
|
||||
{"value": 5, "name": "unmapped before callback"}
|
||||
{"value": 5, "name": "unmapped before callback"},
|
||||
{"value": 6, "name": "mapping already pending"},
|
||||
{"value": 7, "name": "offset out of range"},
|
||||
{"value": 8, "name": "size out of range"}
|
||||
]
|
||||
},
|
||||
"buffer map state": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "unmapped"},
|
||||
{"value": 1, "name": "pending"},
|
||||
{"value": 2, "name": "mapped"}
|
||||
]
|
||||
},
|
||||
"buffer usage": {
|
||||
|
@ -550,6 +575,7 @@
|
|||
},
|
||||
"command encoder": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "finish",
|
||||
|
@ -737,7 +763,10 @@
|
|||
{"name": "line num", "type": "uint64_t"},
|
||||
{"name": "line pos", "type": "uint64_t"},
|
||||
{"name": "offset", "type": "uint64_t"},
|
||||
{"name": "length", "type": "uint64_t"}
|
||||
{"name": "length", "type": "uint64_t"},
|
||||
{"name": "utf16 line pos", "type": "uint64_t"},
|
||||
{"name": "utf16 offset", "type": "uint64_t"},
|
||||
{"name": "utf16 length", "type": "uint64_t"}
|
||||
]
|
||||
},
|
||||
"compilation message type": {
|
||||
|
@ -760,6 +789,7 @@
|
|||
},
|
||||
"compute pass encoder": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "insert debug marker",
|
||||
|
@ -808,15 +838,6 @@
|
|||
{"name": "query index", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dispatch",
|
||||
"tags": ["deprecated"],
|
||||
"args": [
|
||||
{"name": "workgroupCountX", "type": "uint32_t"},
|
||||
{"name": "workgroupCountY", "type": "uint32_t", "default": "1"},
|
||||
{"name": "workgroupCountZ", "type": "uint32_t", "default": "1"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dispatch workgroups",
|
||||
"args": [
|
||||
|
@ -825,14 +846,6 @@
|
|||
{"name": "workgroupCountZ", "type": "uint32_t", "default": "1"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dispatch indirect",
|
||||
"tags": ["deprecated"],
|
||||
"args": [
|
||||
{"name": "indirect buffer", "type": "buffer"},
|
||||
{"name": "indirect offset", "type": "uint64_t"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dispatch workgroups indirect",
|
||||
"args": [
|
||||
|
@ -843,10 +856,6 @@
|
|||
{
|
||||
"name": "end"
|
||||
},
|
||||
{
|
||||
"name": "end pass",
|
||||
"tags": ["deprecated"]
|
||||
},
|
||||
{
|
||||
"name": "end pipeline statistics query",
|
||||
"tags": ["upstream", "emscripten"]
|
||||
|
@ -916,7 +925,6 @@
|
|||
"category": "structure",
|
||||
"extensible": "in",
|
||||
"tags": ["dawn"],
|
||||
"_TODO": "support number as length input",
|
||||
"members": [
|
||||
{"name": "flip y", "type": "bool", "default": "false"},
|
||||
{"name": "needs color space conversion", "type": "bool", "default": "false"},
|
||||
|
@ -945,10 +953,11 @@
|
|||
"emscripten_no_enum_table": true,
|
||||
"values": [
|
||||
{"value": 0, "name": "success"},
|
||||
{"value": 1, "name": "error"},
|
||||
{"value": 2, "name": "device lost"},
|
||||
{"value": 3, "name": "device destroyed"},
|
||||
{"value": 4, "name": "unknown"}
|
||||
{"value": 1, "name": "validation error"},
|
||||
{"value": 2, "name": "internal error"},
|
||||
{"value": 3, "name": "device lost"},
|
||||
{"value": 4, "name": "device destroyed"},
|
||||
{"value": 5, "name": "unknown"}
|
||||
]
|
||||
},
|
||||
"create render pipeline async callback": {
|
||||
|
@ -995,7 +1004,10 @@
|
|||
{
|
||||
"name": "create error buffer",
|
||||
"returns": "buffer",
|
||||
"tags": ["dawn"]
|
||||
"tags": ["dawn"],
|
||||
"args": [
|
||||
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "create command encoder",
|
||||
|
@ -1085,17 +1097,15 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "create swap chain",
|
||||
"tags": ["dawn"],
|
||||
"returns": "swap chain",
|
||||
"name": "create error shader module",
|
||||
"returns": "shader module",
|
||||
"args": [
|
||||
{"name": "surface", "type": "surface", "optional": true},
|
||||
{"name": "descriptor", "type": "swap chain descriptor", "annotation": "const*"}
|
||||
{"name": "descriptor", "type": "shader module descriptor", "annotation": "const*"},
|
||||
{"name": "error message", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "create swap chain",
|
||||
"tags": ["upstream", "emscripten"],
|
||||
"returns": "swap chain",
|
||||
"args": [
|
||||
{"name": "surface", "type": "surface"},
|
||||
|
@ -1159,15 +1169,21 @@
|
|||
"tags": ["dawn"]
|
||||
},
|
||||
{
|
||||
"name": "lose for testing",
|
||||
"name": "force loss",
|
||||
"args": [
|
||||
{"name": "type", "type": "device lost reason"},
|
||||
{"name": "message", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
],
|
||||
"tags": ["dawn"]
|
||||
},
|
||||
{
|
||||
"name": "tick",
|
||||
"no autolock": true,
|
||||
"tags": ["dawn"]
|
||||
},
|
||||
{
|
||||
"name": "set uncaptured error callback",
|
||||
"no autolock": true,
|
||||
"args": [
|
||||
{"name": "callback", "type": "error callback"},
|
||||
{"name": "userdata", "type": "void", "annotation": "*"}
|
||||
|
@ -1175,6 +1191,7 @@
|
|||
},
|
||||
{
|
||||
"name": "set logging callback",
|
||||
"no autolock": true,
|
||||
"tags": ["dawn"],
|
||||
"args": [
|
||||
{"name": "callback", "type": "logging callback"},
|
||||
|
@ -1183,6 +1200,8 @@
|
|||
},
|
||||
{
|
||||
"name": "set device lost callback",
|
||||
"no autolock": true,
|
||||
"tags": ["deprecated"],
|
||||
"args": [
|
||||
{"name": "callback", "type": "device lost callback"},
|
||||
{"name": "userdata", "type": "void", "annotation": "*"}
|
||||
|
@ -1196,7 +1215,6 @@
|
|||
},
|
||||
{
|
||||
"name": "pop error scope",
|
||||
"returns": "bool",
|
||||
"args": [
|
||||
{"name": "callback", "type": "error callback"},
|
||||
{"name": "userdata", "type": "void", "annotation": "*"}
|
||||
|
@ -1208,6 +1226,21 @@
|
|||
"args": [
|
||||
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "validate texture descriptor",
|
||||
"tags": ["dawn"],
|
||||
"args": [
|
||||
{"name": "descriptor", "type": "texture descriptor", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get supported surface usage",
|
||||
"tags": ["dawn"],
|
||||
"returns": "texture usage",
|
||||
"args": [
|
||||
{"name": "surface", "type": "surface"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1246,6 +1279,7 @@
|
|||
{"name": "max texture dimension 3D", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max texture array layers", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max bind groups", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max bindings per bind group", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max dynamic uniform buffers per pipeline layout", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max dynamic storage buffers per pipeline layout", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max sampled textures per shader stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
|
@ -1258,11 +1292,13 @@
|
|||
{"name": "min uniform buffer offset alignment", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "min storage buffer offset alignment", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max vertex buffers", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max buffer size", "type": "uint64_t", "default": "WGPU_LIMIT_U64_UNDEFINED"},
|
||||
{"name": "max vertex attributes", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max vertex buffer array stride", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max inter stage shader components", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max inter stage shader variables", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max color attachments", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max color attachment bytes per sample", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max compute workgroup storage size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max compute invocations per workgroup", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
{"name": "max compute workgroup size x", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||
|
@ -1298,7 +1334,8 @@
|
|||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "validation"},
|
||||
{"value": 1, "name": "out of memory"}
|
||||
{"value": 1, "name": "out of memory"},
|
||||
{"value": 2, "name": "internal"}
|
||||
]
|
||||
},
|
||||
"error type": {
|
||||
|
@ -1308,8 +1345,9 @@
|
|||
{"value": 0, "name": "no error"},
|
||||
{"value": 1, "name": "validation"},
|
||||
{"value": 2, "name": "out of memory"},
|
||||
{"value": 3, "name": "unknown"},
|
||||
{"value": 4, "name": "device lost"}
|
||||
{"value": 3, "name": "internal"},
|
||||
{"value": 4, "name": "unknown"},
|
||||
{"value": 5, "name": "device lost"}
|
||||
]
|
||||
},
|
||||
"logging type": {
|
||||
|
@ -1322,6 +1360,15 @@
|
|||
{"value": 3, "name": "error"}
|
||||
]
|
||||
},
|
||||
"extent 2D": {
|
||||
"category": "structure",
|
||||
"tags": ["dawn"],
|
||||
"_TODO": "crbug.com/1316671: Remove default value of 'width' after chromium side chagnes landed",
|
||||
"members": [
|
||||
{"name": "width", "type": "uint32_t", "default": 0},
|
||||
{"name": "height", "type": "uint32_t", "default": 1}
|
||||
]
|
||||
},
|
||||
"extent 3D": {
|
||||
"category": "structure",
|
||||
"members": [
|
||||
|
@ -1344,9 +1391,27 @@
|
|||
{
|
||||
"name": "destroy",
|
||||
"returns": "void"
|
||||
},
|
||||
{
|
||||
"name": "expire",
|
||||
"returns": "void"
|
||||
},
|
||||
{
|
||||
"name": "refresh",
|
||||
"returns": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"external texture rotation":{
|
||||
"category": "enum",
|
||||
"tags": ["dawn"],
|
||||
"values": [
|
||||
{"value": 0, "name": "rotate 0 degrees"},
|
||||
{"value": 1, "name": "rotate 90 degrees"},
|
||||
{"value": 2, "name": "rotate 180 degrees"},
|
||||
{"value": 3, "name": "rotate 270 degrees"}
|
||||
]
|
||||
},
|
||||
"external texture descriptor": {
|
||||
"category": "structure",
|
||||
"extensible": "in",
|
||||
|
@ -1355,6 +1420,8 @@
|
|||
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
|
||||
{"name": "plane 0", "type": "texture view"},
|
||||
{"name": "plane 1", "type": "texture view", "optional": true},
|
||||
{"name": "visible origin", "type": "origin 2D"},
|
||||
{"name": "visible size", "type": "extent 2D"},
|
||||
{"name": "do yuv to rgb conversion only", "type": "bool", "default": "false"},
|
||||
{"name": "yuv to rgb conversion matrix", "type": "float", "annotation": "const*",
|
||||
"length": 12, "optional": true},
|
||||
|
@ -1363,7 +1430,9 @@
|
|||
{"name": "dst transfer function parameters", "type": "float", "annotation": "const*",
|
||||
"length": 7},
|
||||
{"name": "gamut conversion matrix", "type": "float", "annotation": "const*",
|
||||
"length": 9}
|
||||
"length": 9},
|
||||
{"name": "flip y", "type": "bool", "default": "false"},
|
||||
{"name": "rotation", "type": "external texture rotation", "default": "rotate 0 degrees"}
|
||||
]
|
||||
},
|
||||
"feature name": {
|
||||
|
@ -1378,11 +1447,19 @@
|
|||
{"value": 6, "name": "texture compression ETC2"},
|
||||
{"value": 7, "name": "texture compression ASTC"},
|
||||
{"value": 8, "name": "indirect first instance"},
|
||||
{"value": 9, "name": "shader f16"},
|
||||
{"value": 10, "name": "RG11B10 ufloat renderable"},
|
||||
{"value": 11, "name": "BGRA8 unorm storage"},
|
||||
{"value": 12, "name": "float32 filterable"},
|
||||
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
||||
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
||||
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
||||
{"value": 1004, "name": "dawn native", "tags": ["dawn", "native"]},
|
||||
{"value": 1005, "name": "chromium experimental dp4a", "tags": ["dawn"]}
|
||||
{"value": 1005, "name": "chromium experimental dp4a", "tags": ["dawn"]},
|
||||
{"value": 1006, "name": "timestamp query inside passes", "tags": ["dawn"]},
|
||||
{"value": 1007, "name": "implicit device synchronization", "tags": ["dawn", "native"]},
|
||||
{"value": 1008, "name": "surface capabilities", "tags": ["dawn"]},
|
||||
{"value": 1009, "name": "transient attachments", "tags": ["dawn"]}
|
||||
]
|
||||
},
|
||||
"filter mode": {
|
||||
|
@ -1420,6 +1497,16 @@
|
|||
{"name": "aspect", "type": "texture aspect", "default": "all"}
|
||||
]
|
||||
},
|
||||
"image copy external texture": {
|
||||
"category": "structure",
|
||||
"extensible": "in",
|
||||
"tags": ["dawn"],
|
||||
"members": [
|
||||
{"name": "external texture", "type": "external texture"},
|
||||
{"name": "origin", "type": "origin 3D"},
|
||||
{"name": "natural size", "type": "extent 2D"}
|
||||
]
|
||||
},
|
||||
"index format": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
|
@ -1430,6 +1517,7 @@
|
|||
},
|
||||
"instance": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "create surface",
|
||||
|
@ -1439,8 +1527,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "process events",
|
||||
"tags": ["upstream", "emscripten"]
|
||||
"name": "process events"
|
||||
},
|
||||
{
|
||||
"name": "request adapter",
|
||||
|
@ -1457,16 +1544,6 @@
|
|||
"extensible": "in",
|
||||
"members": []
|
||||
},
|
||||
"dawn instance descriptor": {
|
||||
"tags": ["dawn", "native"],
|
||||
"category": "structure",
|
||||
"chained": "in",
|
||||
"chain roots": ["instance descriptor"],
|
||||
"members": [
|
||||
{"name": "additional runtime search paths count", "type": "uint32_t", "default": 0},
|
||||
{"name": "additional runtime search paths", "type": "char", "annotation": "const*const*", "length": "additional runtime search paths count"}
|
||||
]
|
||||
},
|
||||
"vertex attribute": {
|
||||
"category": "structure",
|
||||
"extensible": false,
|
||||
|
@ -1512,7 +1589,6 @@
|
|||
},
|
||||
"mipmap filter mode": {
|
||||
"category": "enum",
|
||||
"tags": ["upstream"],
|
||||
"values": [
|
||||
{"value": 0, "name": "nearest"},
|
||||
{"value": 1, "name": "linear"}
|
||||
|
@ -1534,6 +1610,14 @@
|
|||
{"name": "z", "type": "uint32_t", "default": "0"}
|
||||
]
|
||||
},
|
||||
"origin 2D": {
|
||||
"category": "structure",
|
||||
"tags": ["dawn"],
|
||||
"members": [
|
||||
{"name": "x", "type": "uint32_t", "default": "0"},
|
||||
{"name": "y", "type": "uint32_t", "default": "0"}
|
||||
]
|
||||
},
|
||||
"pipeline layout": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
|
@ -1701,6 +1785,17 @@
|
|||
{"name": "options", "type": "copy texture for browser options", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "copy external texture for browser",
|
||||
"extensible": "in",
|
||||
"tags": ["dawn"],
|
||||
"args": [
|
||||
{"name": "source", "type": "image copy external texture", "annotation": "const*"},
|
||||
{"name": "destination", "type": "image copy texture", "annotation": "const*"},
|
||||
{"name": "copy size", "type": "extent 3D", "annotation": "const*"},
|
||||
{"name": "options", "type": "copy texture for browser options", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set label",
|
||||
"returns": "void",
|
||||
|
@ -1736,11 +1831,21 @@
|
|||
},
|
||||
|
||||
"render bundle": {
|
||||
"category": "object"
|
||||
"category": "object",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set label",
|
||||
"returns": "void",
|
||||
"args": [
|
||||
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"render bundle encoder": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "set pipeline",
|
||||
|
@ -1810,7 +1915,7 @@
|
|||
"name": "set vertex buffer",
|
||||
"args": [
|
||||
{"name": "slot", "type": "uint32_t"},
|
||||
{"name": "buffer", "type": "buffer"},
|
||||
{"name": "buffer", "type": "buffer", "optional": true},
|
||||
{"name": "offset", "type": "uint64_t", "default": "0"},
|
||||
{"name": "size", "type": "uint64_t", "default": "WGPU_WHOLE_SIZE"}
|
||||
]
|
||||
|
@ -1870,7 +1975,6 @@
|
|||
{"name": "resolve target", "type": "texture view", "optional": true},
|
||||
{"name": "load op", "type": "load op"},
|
||||
{"name": "store op", "type": "store op"},
|
||||
{"name": "clear color", "type": "color", "default": "{ NAN, NAN, NAN, NAN }", "tags": ["deprecated"]},
|
||||
{"name": "clear value", "type": "color"}
|
||||
]
|
||||
},
|
||||
|
@ -1881,12 +1985,10 @@
|
|||
{"name": "view", "type": "texture view"},
|
||||
{"name": "depth load op", "type": "load op", "default": "undefined"},
|
||||
{"name": "depth store op", "type": "store op", "default": "undefined"},
|
||||
{"name": "clear depth", "type": "float", "default": "NAN", "tags": ["deprecated"]},
|
||||
{"name": "depth clear value", "type": "float", "default": "0"},
|
||||
{"name": "depth clear value", "type": "float", "default": "NAN"},
|
||||
{"name": "depth read only", "type": "bool", "default": "false"},
|
||||
{"name": "stencil load op", "type": "load op", "default": "undefined"},
|
||||
{"name": "stencil store op", "type": "store op", "default": "undefined"},
|
||||
{"name": "clear stencil", "type": "uint32_t", "default": "0", "tags": ["deprecated"]},
|
||||
{"name": "stencil clear value", "type": "uint32_t", "default": "0"},
|
||||
{"name": "stencil read only", "type": "bool", "default": "false"}
|
||||
]
|
||||
|
@ -1915,6 +2017,7 @@
|
|||
},
|
||||
"render pass encoder": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "set pipeline",
|
||||
|
@ -1967,8 +2070,8 @@
|
|||
{
|
||||
"name": "execute bundles",
|
||||
"args": [
|
||||
{"name": "bundles count", "type": "uint32_t"},
|
||||
{"name": "bundles", "type": "render bundle", "annotation": "const*", "length": "bundles count"}
|
||||
{"name": "bundle count", "type": "uint32_t"},
|
||||
{"name": "bundles", "type": "render bundle", "annotation": "const*", "length": "bundle count"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2023,7 +2126,7 @@
|
|||
"name": "set vertex buffer",
|
||||
"args": [
|
||||
{"name": "slot", "type": "uint32_t"},
|
||||
{"name": "buffer", "type": "buffer"},
|
||||
{"name": "buffer", "type": "buffer", "optional": true},
|
||||
{"name": "offset", "type": "uint64_t", "default": "0"},
|
||||
{"name": "size", "type": "uint64_t", "default": "WGPU_WHOLE_SIZE"}
|
||||
]
|
||||
|
@ -2065,10 +2168,6 @@
|
|||
{
|
||||
"name": "end"
|
||||
},
|
||||
{
|
||||
"name": "end pass",
|
||||
"tags": ["deprecated"]
|
||||
},
|
||||
{
|
||||
"name": "end pipeline statistics query",
|
||||
"tags": ["upstream", "emscripten"]
|
||||
|
@ -2176,8 +2275,8 @@
|
|||
"extensible": "in",
|
||||
"members": [
|
||||
{"name": "format", "type": "texture format"},
|
||||
{"name": "depth write enabled", "type": "bool", "default": "false"},
|
||||
{"name": "depth compare", "type": "compare function", "default": "always"},
|
||||
{"name": "depth write enabled", "type": "bool"},
|
||||
{"name": "depth compare", "type": "compare function"},
|
||||
{"name": "stencil front", "type": "stencil face state"},
|
||||
{"name": "stencil back", "type": "stencil face state"},
|
||||
{"name": "stencil read mask", "type": "uint32_t", "default": "0xFFFFFFFF"},
|
||||
|
@ -2264,8 +2363,7 @@
|
|||
{"name": "address mode w", "type": "address mode", "default": "clamp to edge"},
|
||||
{"name": "mag filter", "type": "filter mode", "default": "nearest"},
|
||||
{"name": "min filter", "type": "filter mode", "default": "nearest"},
|
||||
{"name": "mipmap filter", "type": "filter mode", "default": "nearest", "tags": ["dawn", "emscripten"]},
|
||||
{"name": "mipmap filter", "type": "mipmap filter mode", "default": "nearest", "tags": ["upstream"]},
|
||||
{"name": "mipmap filter", "type": "mipmap filter mode", "default": "nearest"},
|
||||
{"name": "lod min clamp", "type": "float", "default": "0.0f"},
|
||||
{"name": "lod max clamp", "type": "float", "default": "1000.0f"},
|
||||
{"name": "compare", "type": "compare function", "default": "undefined"},
|
||||
|
@ -2323,8 +2421,18 @@
|
|||
"chained": "in",
|
||||
"chain roots": ["shader module descriptor"],
|
||||
"members": [
|
||||
{"name": "source", "type": "char", "annotation": "const*", "length": "strlen", "tags": ["dawn", "emscripten"]},
|
||||
{"name": "code", "type": "char", "annotation": "const*", "length": "strlen", "tags": ["upstream"]}
|
||||
{"name": "source", "type": "char", "annotation": "const*", "length": "strlen", "default": "nullptr", "optional": true, "tags": ["dawn", "emscripten"]},
|
||||
{"name": "code", "type": "char", "annotation": "const*", "length": "strlen", "default": "nullptr", "optional": true, "tags": ["dawn", "emscripten"]},
|
||||
{"name": "code", "type": "char", "annotation": "const*", "length": "strlen", "default": "nullptr", "tags": ["upstream"]}
|
||||
]
|
||||
},
|
||||
"dawn shader module SPIRV options descriptor": {
|
||||
"category": "structure",
|
||||
"chained": "in",
|
||||
"chain roots": ["shader module descriptor"],
|
||||
"tags": ["dawn"],
|
||||
"members": [
|
||||
{"name": "allow non uniform derivatives", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"shader stage": {
|
||||
|
@ -2361,6 +2469,7 @@
|
|||
},
|
||||
"surface": {
|
||||
"category": "object",
|
||||
"no autolock": true,
|
||||
"methods": [
|
||||
{
|
||||
"name": "get preferred format",
|
||||
|
@ -2466,17 +2575,8 @@
|
|||
"swap chain": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
{
|
||||
"name": "configure",
|
||||
"tags": ["dawn"],
|
||||
"args": [
|
||||
{"name": "format", "type": "texture format"},
|
||||
{"name": "allowed usage", "type": "texture usage"},
|
||||
{"name": "width", "type": "uint32_t"},
|
||||
{"name": "height", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
{"name": "get current texture view", "returns": "texture view"},
|
||||
{"name": "get current texture", "returns": "texture"},
|
||||
{"name": "present"}
|
||||
]
|
||||
},
|
||||
|
@ -2489,8 +2589,7 @@
|
|||
{"name": "format", "type": "texture format"},
|
||||
{"name": "width", "type": "uint32_t"},
|
||||
{"name": "height", "type": "uint32_t"},
|
||||
{"name": "present mode", "type": "present mode"},
|
||||
{"name": "implementation", "type": "uint64_t", "default": 0, "tags": ["deprecated"]}
|
||||
{"name": "present mode", "type": "present mode"}
|
||||
]
|
||||
},
|
||||
"s type": {
|
||||
|
@ -2514,10 +2613,13 @@
|
|||
{"value": 14, "name": "surface descriptor from windows swap chain panel", "tags": ["dawn"]},
|
||||
{"value": 15, "name": "render pass descriptor max draw count"},
|
||||
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
|
||||
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]},
|
||||
{"value": 1003, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]},
|
||||
{"value": 1004, "name": "dawn instance descriptor", "tags": ["dawn", "native"]},
|
||||
{"value": 1005, "name": "dawn cache device descriptor", "tags": ["dawn", "native"]}
|
||||
{"value": 1005, "name": "dawn cache device descriptor", "tags": ["dawn", "native"]},
|
||||
{"value": 1006, "name": "dawn adapter properties power preference", "tags": ["dawn", "native"]},
|
||||
{"value": 1007, "name": "dawn buffer descriptor error info from wire client", "tags": ["dawn"]},
|
||||
{"value": 1008, "name": "dawn toggles descriptor", "tags": ["dawn", "native"]},
|
||||
{"value": 1009, "name": "dawn shader module SPIRV options descriptor", "tags": ["dawn"]}
|
||||
]
|
||||
},
|
||||
"texture": {
|
||||
|
@ -2584,15 +2686,6 @@
|
|||
{"value": 4, "name": "plane 1 only", "tags": ["dawn"]}
|
||||
]
|
||||
},
|
||||
"texture component type": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "float"},
|
||||
{"value": 1, "name": "sint"},
|
||||
{"value": 2, "name": "uint"},
|
||||
{"value": 3, "name": "depth comparison"}
|
||||
]
|
||||
},
|
||||
"texture data layout": {
|
||||
"category": "structure",
|
||||
"extensible": "in",
|
||||
|
@ -2745,7 +2838,7 @@
|
|||
{"value": 4, "name": "texture binding"},
|
||||
{"value": 8, "name": "storage binding"},
|
||||
{"value": 16, "name": "render attachment"},
|
||||
{"value": 32, "name": "present", "tags": ["dawn"]}
|
||||
{"value": 32, "name": "transient attachment", "tags": ["dawn"]}
|
||||
]
|
||||
},
|
||||
"texture view descriptor": {
|
||||
|
@ -2832,13 +2925,6 @@
|
|||
"type": "size_t",
|
||||
"value": "SIZE_MAX"
|
||||
},
|
||||
"stride undefined" : {
|
||||
"category": "constant",
|
||||
"tags": ["deprecated"],
|
||||
"_TODO": "crbug.com/dawn/520: Remove WGPU_STRIDE_UNDEFINED in favor of WGPU_COPY_STRIDE_UNDEFINED.",
|
||||
"type": "uint32_t",
|
||||
"value": "(0xffffffffUL)"
|
||||
},
|
||||
"copy stride undefined" : {
|
||||
"category": "constant",
|
||||
"type": "uint32_t",
|
||||
|
@ -2920,5 +3006,23 @@
|
|||
"members": [
|
||||
{"name": "use internal usages", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"dawn adapter properties power preference": {
|
||||
"category": "structure",
|
||||
"chained": "out",
|
||||
"chain roots": ["adapter properties"],
|
||||
"tags": ["dawn"],
|
||||
"members": [
|
||||
{"name": "power preference", "type": "power preference", "default": "undefined"}
|
||||
]
|
||||
},
|
||||
"dawn buffer descriptor error info from wire client": {
|
||||
"category": "structure",
|
||||
"chained": "in",
|
||||
"chain roots": ["buffer descriptor"],
|
||||
"tags": ["dawn"],
|
||||
"members": [
|
||||
{"name": "out of memory", "type": "bool", "default": "false"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,21 +19,21 @@
|
|||
|
||||
"commands": {
|
||||
"buffer map async": [
|
||||
{ "name": "buffer id", "type": "ObjectId" },
|
||||
{ "name": "buffer id", "type": "ObjectId", "id_type": "buffer" },
|
||||
{ "name": "request serial", "type": "uint64_t" },
|
||||
{ "name": "mode", "type": "map mode" },
|
||||
{ "name": "offset", "type": "uint64_t"},
|
||||
{ "name": "size", "type": "uint64_t"}
|
||||
],
|
||||
"buffer update mapped data": [
|
||||
{ "name": "buffer id", "type": "ObjectId" },
|
||||
{ "name": "buffer id", "type": "ObjectId", "id_type": "buffer" },
|
||||
{ "name": "write data update info length", "type": "uint64_t" },
|
||||
{ "name": "write data update info", "type": "uint8_t", "annotation": "const*", "length": "write data update info length", "skip_serialize": true},
|
||||
{ "name": "offset", "type": "uint64_t"},
|
||||
{ "name": "size", "type": "uint64_t"}
|
||||
],
|
||||
"device create buffer": [
|
||||
{ "name": "device id", "type": "ObjectId" },
|
||||
{ "name": "device id", "type": "ObjectId", "id_type": "device" },
|
||||
{ "name": "descriptor", "type": "buffer descriptor", "annotation": "const*" },
|
||||
{ "name": "result", "type": "ObjectHandle", "handle_type": "buffer" },
|
||||
{ "name": "read handle create info length", "type": "uint64_t" },
|
||||
|
@ -42,19 +42,19 @@
|
|||
{ "name": "write handle create info", "type": "uint8_t", "annotation": "const*", "length": "write handle create info length", "skip_serialize": true}
|
||||
],
|
||||
"device create compute pipeline async": [
|
||||
{ "name": "device id", "type": "ObjectId" },
|
||||
{ "name": "device id", "type": "ObjectId", "id_type": "device"},
|
||||
{ "name": "request serial", "type": "uint64_t" },
|
||||
{ "name": "pipeline object handle", "type": "ObjectHandle", "handle_type": "compute pipeline"},
|
||||
{ "name": "descriptor", "type": "compute pipeline descriptor", "annotation": "const*"}
|
||||
],
|
||||
"device create render pipeline async": [
|
||||
{ "name": "device id", "type": "ObjectId" },
|
||||
{ "name": "device id", "type": "ObjectId", "id_type": "device" },
|
||||
{ "name": "request serial", "type": "uint64_t" },
|
||||
{ "name": "pipeline object handle", "type": "ObjectHandle", "handle_type": "render pipeline"},
|
||||
{ "name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}
|
||||
],
|
||||
"device pop error scope": [
|
||||
{ "name": "device id", "type": "ObjectId" },
|
||||
{ "name": "device id", "type": "ObjectId", "id_type": "device" },
|
||||
{ "name": "request serial", "type": "uint64_t" }
|
||||
],
|
||||
"destroy object": [
|
||||
|
@ -62,19 +62,19 @@
|
|||
{ "name": "object id", "type": "ObjectId" }
|
||||
],
|
||||
"queue on submitted work done": [
|
||||
{ "name": "queue id", "type": "ObjectId" },
|
||||
{ "name": "queue id", "type": "ObjectId", "id_type": "queue" },
|
||||
{ "name": "signal value", "type": "uint64_t" },
|
||||
{ "name": "request serial", "type": "uint64_t" }
|
||||
],
|
||||
"queue write buffer": [
|
||||
{"name": "queue id", "type": "ObjectId" },
|
||||
{"name": "buffer id", "type": "ObjectId" },
|
||||
{"name": "queue id", "type": "ObjectId", "id_type": "queue" },
|
||||
{"name": "buffer id", "type": "ObjectId", "id_type": "buffer" },
|
||||
{"name": "buffer offset", "type": "uint64_t"},
|
||||
{"name": "data", "type": "uint8_t", "annotation": "const*", "length": "size", "wire_is_data_only": true},
|
||||
{"name": "size", "type": "uint64_t"}
|
||||
],
|
||||
"queue write texture": [
|
||||
{"name": "queue id", "type": "ObjectId" },
|
||||
{"name": "queue id", "type": "ObjectId", "id_type": "queue" },
|
||||
{"name": "destination", "type": "image copy texture", "annotation": "const*"},
|
||||
{"name": "data", "type": "uint8_t", "annotation": "const*", "length": "data size", "wire_is_data_only": true},
|
||||
{"name": "data size", "type": "uint64_t"},
|
||||
|
@ -82,17 +82,17 @@
|
|||
{"name": "writeSize", "type": "extent 3D", "annotation": "const*"}
|
||||
],
|
||||
"shader module get compilation info": [
|
||||
{ "name": "shader module id", "type": "ObjectId" },
|
||||
{ "name": "shader module id", "type": "ObjectId", "id_type": "shader module" },
|
||||
{ "name": "request serial", "type": "uint64_t" }
|
||||
],
|
||||
"instance request adapter": [
|
||||
{ "name": "instance id", "type": "ObjectId" },
|
||||
{ "name": "instance id", "type": "ObjectId", "id_type": "instance" },
|
||||
{ "name": "request serial", "type": "uint64_t" },
|
||||
{ "name": "adapter object handle", "type": "ObjectHandle", "handle_type": "adapter"},
|
||||
{ "name": "options", "type": "request adapter options", "annotation": "const*" }
|
||||
{ "name": "options", "type": "request adapter options", "annotation": "const*", "optional": true }
|
||||
],
|
||||
"adapter request device": [
|
||||
{ "name": "adapter id", "type": "ObjectId" },
|
||||
{ "name": "adapter id", "type": "ObjectId", "id_type": "adapter" },
|
||||
{ "name": "request serial", "type": "uint64_t" },
|
||||
{ "name": "device object handle", "type": "ObjectHandle", "handle_type": "device"},
|
||||
{ "name": "descriptor", "type": "device descriptor", "annotation": "const*" }
|
||||
|
@ -189,6 +189,7 @@
|
|||
"BufferMapAsync",
|
||||
"BufferGetConstMappedRange",
|
||||
"BufferGetMappedRange",
|
||||
"BufferGetMapState",
|
||||
"BufferGetSize",
|
||||
"BufferGetUsage",
|
||||
"DeviceCreateBuffer",
|
||||
|
@ -218,15 +219,19 @@
|
|||
"TextureGetUsage"
|
||||
],
|
||||
"client_handwritten_commands": [
|
||||
"AdapterGetInstance",
|
||||
"BufferDestroy",
|
||||
"BufferUnmap",
|
||||
"DeviceCreateErrorBuffer",
|
||||
"DeviceCreateQuerySet",
|
||||
"DeviceCreateSwapChain",
|
||||
"DeviceCreateTexture",
|
||||
"DeviceCreateErrorTexture",
|
||||
"DeviceGetAdapter",
|
||||
"DeviceGetQueue",
|
||||
"DeviceInjectError"
|
||||
"DeviceGetSupportedSurfaceUsage",
|
||||
"DeviceInjectError",
|
||||
"SwapChainGetCurrentTexture"
|
||||
],
|
||||
"client_special_objects": [
|
||||
"Adapter",
|
||||
|
@ -236,6 +241,7 @@
|
|||
"QuerySet",
|
||||
"Queue",
|
||||
"ShaderModule",
|
||||
"SwapChain",
|
||||
"Texture"
|
||||
],
|
||||
"server_custom_pre_handler_commands": [
|
||||
|
|
|
@ -73,6 +73,9 @@ The most common GN build option is `is_debug=true/false`; otherwise
|
|||
On macOS you'll want to add the `use_system_xcode=true` in most cases.
|
||||
(and if you're a googler please get XCode from go/xcode).
|
||||
|
||||
To generate a Microsoft Visual Studio solution, add `ide=vs2022` and
|
||||
`ninja-executable=<dawn parent directory>\dawn\third_party\ninja\ninja.exe`.
|
||||
The .sln file will be created in the output directory specified.
|
||||
|
||||
### Fuzzers on MacOS
|
||||
If you are attempting fuzz, using `TINT_BUILD_FUZZERS=ON`, the version of llvm
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
Dawn relies on a lot of code generation to produce boilerplate code, especially webgpu.h-related code. They start by reading some JSON files (and sometimes XML too), process the data into an in-memory representation that's then used by some [Jinja2](https://jinja.palletsprojects.com/) templates to generate the code. This is similar to the model/view separation in Web development.
|
||||
|
||||
Generators are based on [generator_lib.py](../generator/generator_lib.py) which provides facilities for integrating in build systems and using Jinja2. Templates can be found in [`generator/templates`](../generator/templates) and the generated files are in `out/<Debug/Release/foo>/gen/src` when building Dawn in standalone. Generated files can also be found in [Chromium's code search](https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/src/).
|
||||
Generators are based on [generator_lib.py](../../generator/generator_lib.py) which provides facilities for integrating in build systems and using Jinja2. Templates can be found in [`generator/templates`](../../generator/templates) and the generated files are in `out/<Debug/Release/foo>/gen/src` when building Dawn in standalone. Generated files can also be found in [Chromium's code search](https://source.chromium.org/chromium/chromium/src/+/main:out/Debug/gen/third_party/dawn/src/).
|
||||
|
||||
## Dawn "JSON API" generators
|
||||
|
||||
Most of the code generation is done from [`dawn.json`](../dawn.json) which is a JSON description of the WebGPU API with extra annotation used by some of the generators. The code for all the "Dawn JSON" generators is in [`dawn_json_generator.py`](../generator/dawn_json_generator.py) (with templates in the regular template dir).
|
||||
Most of the code generation is done from [`dawn.json`](../../dawn.json) which is a JSON description of the WebGPU API with extra annotation used by some of the generators. The code for all the "Dawn JSON" generators is in [`dawn_json_generator.py`](../../generator/dawn_json_generator.py) (with templates in the regular template dir).
|
||||
|
||||
At this time it is used to generate:
|
||||
|
||||
|
@ -76,6 +76,8 @@ A **record** is a list of **record members**, each of which is a dictionary with
|
|||
- `"name"` a string
|
||||
- `"return_type"` (default to no return type) a string that's the name of the return type.
|
||||
- `"arguments"` a **record**, so an array of **record members**
|
||||
- `"no autolock"`: a boolean flag (default is false) indicates that the method's generated code won't automatically do thread synchronization. This flag can only be true on device or device child objects currently.
|
||||
- `"no autolock"`: a boolean flag (default is false) to indicate that the object's generated code won't automatically do thread synchronization. This will override individual method's `"no autolock"` flag. This flag can only be true on device or device child objects currently.
|
||||
|
||||
**`"constant"`**
|
||||
- `"type"`: a string, the name of the base data type
|
||||
|
@ -87,7 +89,7 @@ A **record** is a list of **record members**, each of which is a dictionary with
|
|||
|
||||
## Dawn "wire" generators
|
||||
|
||||
The generator for the pieces of dawn_wire need additional data which is found in [`dawn_wire_json`](../dawn_wire.json). Examples of pieces that are generated are:
|
||||
The generator for the pieces of dawn_wire need additional data which is found in [`dawn_wire_json`](../../dawn_wire.json). Examples of pieces that are generated are:
|
||||
|
||||
- `WireCmd.cpp/.h` the most important piece: the meat of the serialization / deserialization code for WebGPU structures and commands
|
||||
- `ServerHandlers/Doers.cpp` that does the complete handling of all regular WebGPU methods in the server
|
||||
|
@ -110,4 +112,13 @@ The schema of `dawn_wire.json` is a dictionary with the following keys:
|
|||
|
||||
## OpenGL loader generator
|
||||
|
||||
The code to load OpenGL entrypoints from a `GetProcAddress` function is generated from [`gl.xml`](../third_party/khronos/gl.xml) and the [list of extensions](../src/dawn/native/opengl/supported_extensions.json) it supports.
|
||||
The code to load OpenGL entrypoints from a `GetProcAddress` function is generated from [`gl.xml`](../../third_party/khronos/gl.xml) and the [list of extensions](../../src/dawn/native/opengl/supported_extensions.json) it supports.
|
||||
|
||||
|
||||
## Dawn lpmfuzz generator
|
||||
One of Dawn's Fuzzers utilizes the information in [`dawn.json`, `dawn_wire.json`, `dawn_lpm.json`] to generate the `.proto` and `.cpp` files required for a [libprotobuf-mutator fuzzer](https://github.com/google/libprotobuf-mutator) that fuzzes Dawn Wire Server's stack with more effectiveness in some areas than plain libfuzzer.
|
||||
|
||||
At this time it is used to generate:
|
||||
|
||||
- the `dawn_lpm.proto` file used to describe the grammar for the fuzzer
|
||||
- the serializer `DawnLPMSerializer.cpp` that takes an arbitrary number of protobuf structures that were defined in `dawn_lpm.proto` and serializes them to be passed to `DawnWireServer::HandleCommands`.
|
||||
|
|
|
@ -1,3 +1,49 @@
|
|||
# Debugging Dawn
|
||||
|
||||
(TODO)
|
||||
## Toggles
|
||||
There are various debug-related Toggles that can help diagnose issues. Useful debug toggles:
|
||||
- `dump_shaders`: Log input WGSL shaders and translated backend shaders (MSL/ HLSL/DXBC/DXIL / SPIR-V).
|
||||
- `disable_symbol_renaming`: As much as possible, disable renaming of symbols (variables, function names, etc.). This can make dumped shaders more readable.
|
||||
- `emit_hlsl_debug_symbols`: Sets the D3DCOMPILE_SKIP_OPTIMIZATION and D3DCOMPILE_DEBUG compilation flags when compiling HLSL code.
|
||||
- `use_user_defined_labels_in_backend`: Forward object labels to the backend so that they can be seen in native debugging tools like RenderDoc, PIX, or Mac Instruments.
|
||||
|
||||
Toggles may be enabled/disabled in different ways.
|
||||
|
||||
- **In code:**
|
||||
|
||||
Use extension struct `DawnTogglesDescriptor` chained on `DeviceDescriptor`.
|
||||
|
||||
For example:
|
||||
```c++
|
||||
const char* const enabledToggles[] = {"dump_shaders", "disable_symbol_renaming"};
|
||||
|
||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
||||
deviceTogglesDesc.enabledToggles = enabledToggles;
|
||||
deviceTogglesDesc.enabledTogglesCount = 2;
|
||||
|
||||
wgpu::DeviceDescriptor deviceDescriptor;
|
||||
deviceDescriptor.nextInChain = &deviceTogglesDesc;
|
||||
```
|
||||
|
||||
- **Command-line for Chrome**
|
||||
|
||||
Run Chrome with command line flags`--enable-dawn-features` and/or `--disable-dawn-features` to force enable/disable toggles. Toggles should be comma-delimited.
|
||||
|
||||
For example:
|
||||
`--enable-dawn-features=dump_shaders,disable_symbol_renaming`
|
||||
|
||||
- **Command-line for dawn_end2end_tests/dawn_unittests**
|
||||
|
||||
Run Dawn test binaries with command line flags`--enable-toggles` and/or `--disable-toggles` to force enable/disable toggles. Toggles should be comma-delimited.
|
||||
|
||||
For example:
|
||||
`dawn_end2end_tests --enable-toggles=dump_shaders,disable_symbol_renaming`
|
||||
|
||||
## Environment Variables
|
||||
|
||||
- `DAWN_DEBUG_BREAK_ON_ERROR`
|
||||
|
||||
Errors in WebGPU are reported asynchronously which may make debugging difficult because at the time an error is reported, you can't easily create a breakpoint to inspect the callstack in your application.
|
||||
|
||||
Setting `DAWN_DEBUG_BREAK_ON_ERROR` to a non-empty, non-zero value will execute a debug breakpoint
|
||||
instruction ([`dawn::Breakpoint()`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/src/dawn/common/Assert.cpp?q=dawn::Breakpoint)) as soon as any type of error is generated.
|
||||
|
|
|
@ -9,11 +9,11 @@ Example of backend facilities are GPU memory allocators or the backing API funct
|
|||
|
||||
### Error Handling
|
||||
|
||||
Dawn (dawn_native) uses the [Error.h](../src/dawn/native/Error.h) error handling to robustly handle errors.
|
||||
Dawn (dawn_native) uses the [Error.h](../../src/dawn/native/Error.h) error handling to robustly handle errors.
|
||||
With `DAWN_TRY` errors bubble up all the way to, and are "consumed" by the entry-point that was called by the application.
|
||||
Error consumption uses `Device::ConsumeError` that expose them via the WebGPU "error scopes" and can also influence the device lifecycle by notifying of a device loss, or triggering a device loss..
|
||||
|
||||
See [Error.h](../src/dawn/native/Error.h) for more information about using errors.
|
||||
See [Error.h](../../src/dawn/native/Error.h) for more information about using errors.
|
||||
|
||||
### Device Lifecycle
|
||||
|
||||
|
@ -26,7 +26,7 @@ The device lifecycle is a bit more complicated than other objects in Dawn for mu
|
|||
- A device can become "disconnected" when a TDR or hot-unplug happens.
|
||||
In this case, destruction of the device doesn't need to wait on GPU commands to finish because they just disappeared.
|
||||
|
||||
There is a state machine `State` defined in [Device.h](../src/dawn/native/Device.h) that controls all of the above.
|
||||
There is a state machine `State` defined in [Device.h](../../src/dawn/native/Device.h) that controls all of the above.
|
||||
The most common state is `Alive` when there are potentially GPU commands executing.
|
||||
|
||||
Initialization of a device looks like the following:
|
||||
|
@ -62,24 +62,24 @@ Toggles can be queried using `DeviceBase::IsToggleEnabled`:
|
|||
bool useRenderPass = device->IsToggleEnabled(Toggle::UseD3D12RenderPass);
|
||||
```
|
||||
|
||||
Toggles are defined in a table in [Toggles.cpp](../src/dawn/native/Toggles.cpp) that also includes their name and description.
|
||||
The name can be used to force enabling of a toggle or, at the contrary, force the disabling of a toogle.
|
||||
Toggles are defined in a table in [Toggles.cpp](../../src/dawn/native/Toggles.cpp) that also includes their name and description.
|
||||
The name can be used to require enabling of a toggle or, at the contrary, require the disabling of a toogle.
|
||||
This is particularly useful in tests so that the two sides of a code path can be tested (for example using D3D12 render passes and not).
|
||||
|
||||
Here's an example of a test that is run in the D3D12 backend both with the D3D12 render passes forcibly disabled, and in the default configuration.
|
||||
Here's an example of a test that is run in the D3D12 backend both with the D3D12 render passes required to be disabled, and in the default configuration.
|
||||
```
|
||||
DAWN_INSTANTIATE_TEST(RenderPassTest,
|
||||
D3D12Backend(),
|
||||
D3D12Backend({}, {"use_d3d12_render_pass"}));
|
||||
// The {} is the list of force enabled toggles, {"..."} the force disabled ones.
|
||||
// The {} is the list of required enabled toggles, {"..."} the required disabled ones.
|
||||
```
|
||||
|
||||
The initialization order of toggles looks as follows:
|
||||
The toggles state of a device is decided by the adapter when creating it. The steps of device toggles state decision looks as follows:
|
||||
|
||||
- The toggles overrides from the device descriptor are applied.
|
||||
- The frontend device default toggles are applied (unless already overriden).
|
||||
- The backend device default toggles are applied (unless already overriden) using `DeviceBase::SetToggle`
|
||||
- The backend device can ignore overriden toggles if it can't support them by using `DeviceBase::ForceSetToggle`
|
||||
- The device toggles state initialized to required device toggles from the DawnTogglesDescriptor chained in device descriptor.
|
||||
- The frontend (i.e. not backend-specific) default toggles are set (unless already required) using `TogglesState::Default`.
|
||||
- Any backend device toggle that not supported is forced set to a proper state in `Adapter::SetupBackendDeviceToggles` using `TogglesState::ForceSet`.
|
||||
- The backend device default toggles are applied (unless already set) in `Adapter::SetupBackendDeviceToggles` using `TogglesState::Default`.
|
||||
|
||||
Forcing toggles should only be done when there is no "safe" option for the toggle.
|
||||
This is to avoid crashes during testing when the tests try to use both sides of a toggle.
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Surface Capabilities
|
||||
|
||||
The `surface-capabilities` feature allows querying a surface's capabilities and creating a swap chain with additional usage flags.
|
||||
|
||||
Additional functionality:
|
||||
- Adds `wgpu::Device::GetSupportedSurfaceUsage(wgpu::Surface)` method for querying the surface's supported usage flags. One or the combination of these flags can be used to create a swap chain.
|
||||
|
||||
Example Usage:
|
||||
```
|
||||
wgpu::TextureUsage supportedUsage = device.GetSupportedSurfaceUsage(surface);
|
||||
|
||||
wgpu::SwapChainDescriptor desc = {};
|
||||
// set usage flags.
|
||||
desc.usage = supportedUsage;
|
||||
|
||||
device.CreateSwapChain(surface, &desc);
|
||||
```
|
||||
|
||||
Notes:
|
||||
- If this feature is not enabled, only `wgpu::TextureUsage::RenderAttachment` flag is allowed to be used in `wgpu::SwapChainDescriptor::usage`.
|
|
@ -0,0 +1,24 @@
|
|||
# Transient Attachments
|
||||
|
||||
The `transient-attachments` feature allows creation of attachments that allow
|
||||
render pass operations to stay in tile memory, avoiding VRAM traffic and
|
||||
potentially avoiding VRAM allocation for the textures.
|
||||
|
||||
Example Usage:
|
||||
```
|
||||
wgpu::TextureDescriptor desc;
|
||||
desc.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
desc.size = {1, 1, 1};
|
||||
desc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TransientAttachment;
|
||||
|
||||
auto transientTexture = device.CreateTexture(&desc);
|
||||
|
||||
// Can now create views from the texture to serve as transient attachments, e.g.
|
||||
// as color attachments in a render pipeline.
|
||||
```
|
||||
|
||||
Notes:
|
||||
- Only supported usage is wgpu::TextureUsage::RenderAttachment |
|
||||
wgpu::TextureUsage::TransientAttachment
|
||||
- It is not possible to load from or store to TextureViews that are used as
|
||||
transient attachments
|
|
@ -9,7 +9,7 @@ Dawn uses Chromium's continuous integration (CI) infrastructure to continually r
|
|||
For additional information on GPU testing in Chromium, please see [[chromium/src]//docs/gpu/gpu_testing_bot_details.md](https://chromium.googlesource.com/chromium/src.git/+/main/docs/gpu/gpu_testing_bot_details.md).
|
||||
|
||||
## Dawn CI/Try Builders
|
||||
Dawn builders are specified in [[dawn]//infra/config/global/cr-buildbucket.cfg](../infra/config/global/cr-buildbucket.cfg). This file contains a few mixins such as `clang`, `no_clang`, `x64`, `x86`, `debug`, `release` which are used to specify the bot dimensions and build properties (builder_mixins.recipe.properties). At the time of writing, we have the following builders:
|
||||
Dawn builders are specified in [[dawn]//infra/config/global/cr-buildbucket.cfg](../../infra/config/global/generated/cr-buildbucket.cfg). This file contains a few mixins such as `clang`, `no_clang`, `x64`, `x86`, `debug`, `release` which are used to specify the bot dimensions and build properties (builder_mixins.recipe.properties). At the time of writing, we have the following builders:
|
||||
- [dawn/try/presubmit](https://ci.chromium.org/p/dawn/builders/try/presubmit)
|
||||
- [dawn/try/linux-clang-dbg-x64](https://ci.chromium.org/p/dawn/builders/try/linux-clang-dbg-x64)
|
||||
- [dawn/try/linux-clang-dbg-x86](https://ci.chromium.org/p/dawn/builders/try/linux-clang-dbg-x86)
|
||||
|
@ -23,16 +23,16 @@ Dawn builders are specified in [[dawn]//infra/config/global/cr-buildbucket.cfg](
|
|||
|
||||
There are additional `chromium/try` builders, but those are described later in this document.
|
||||
|
||||
These bots are defined in both buckets luci.dawn.ci and luci.dawn.try, though their ACL permissions differ. luci.dawn.ci bots will be scheduled regularly based on [[dawn]//infra/config/global/luci-scheduler.cfg](../infra/config/global/luci-scheduler.cfg). luci.dawn.try bots will be triggered on the CQ based on [[dawn]//infra/config/global/commit-queue.cfg](../infra/config/global/commit-queue.cfg).
|
||||
These bots are defined in both buckets luci.dawn.ci and luci.dawn.try, though their ACL permissions differ. luci.dawn.ci bots will be scheduled regularly based on [[dawn]//infra/config/global/luci-scheduler.cfg](../../infra/config/global/generated/luci-scheduler.cfg). luci.dawn.try bots will be triggered on the CQ based on [[dawn]//infra/config/global/commit-queue.cfg](../../infra/config/global/generated/commit-queue.cfg).
|
||||
|
||||
One particular note is `buckets.swarming.builder_defaults.recipe.name: "dawn"` which specifies these use the [`dawn.py`](https://source.chromium.org/search/?q=file:recipes/dawn.py) build recipe.
|
||||
|
||||
Build status for both CI and Try builders can be seen at this [console](https://ci.chromium.org/p/dawn) which is generated from [[dawn]//infra/config/global/luci-milo.cfg](../infra/config/global/luci-milo.cfg).
|
||||
Build status for both CI and Try builders can be seen at this [console](https://ci.chromium.org/p/dawn) which is generated from [[dawn]//infra/config/global/luci-milo.cfg](../../infra/config/global/generated/luci-milo.cfg).
|
||||
|
||||
## Dawn Build Recipe
|
||||
The [`dawn.py`](https://cs.chromium.org/search/?q=file:recipes/dawn.py) build recipe is simple and intended only for testing compilation and unit tests. It does the following:
|
||||
1. Checks out Dawn standalone and dependencies
|
||||
2. Builds based on the `builder_mixins.recipe.properties` coming from the builder config in [[dawn]//infra/config/global/cr-buildbucket.cfg](../infra/config/global/cr-buildbucket.cfg).
|
||||
2. Builds based on the `builder_mixins.recipe.properties` coming from the builder config in [[dawn]//infra/config/global/cr-buildbucket.cfg](../../infra/config/global/generated/cr-buildbucket.cfg).
|
||||
3. Runs the `dawn_unittests` on that same bot.
|
||||
|
||||
## Dawn Chromium-Based CI Waterfall Bots
|
||||
|
@ -48,7 +48,7 @@ The Builder and Tester bots are additionally configured at [[chromium/tools/buil
|
|||
Finally, builds on these waterfall bots are automatically scheduled based on the configuration in [[chromium/src]//infra/config/buckets/ci.star](https://source.chromium.org/search?q=file:ci.star%20%22Dawn%20Linux%20x64%20Builder%22). Note that the Tester bots are `triggered_by` the Builder bots.
|
||||
|
||||
## Dawn Chromium-Based Tryjobs
|
||||
[[dawn]//infra/config/global/commit-queue.cfg](../infra/config/global/commit-queue.cfg) declares additional tryjob builders which are defined in the Chromium workspace. The reason for this separation is that jobs sent to these bots rely on the Chromium infrastructure for doing builds and triggering jobs on bots with GPU hardware in swarming.
|
||||
[[dawn]//infra/config/global/commit-queue.cfg](../../infra/config/global/generated/commit-queue.cfg) declares additional tryjob builders which are defined in the Chromium workspace. The reason for this separation is that jobs sent to these bots rely on the Chromium infrastructure for doing builds and triggering jobs on bots with GPU hardware in swarming.
|
||||
|
||||
At the time of writing, the bots for Dawn CLs are:
|
||||
- [chromium/try/linux-dawn-rel](https://ci.chromium.org/p/chromium/builders/try/linux-dawn-rel)
|
||||
|
|
|
@ -4,31 +4,32 @@ This repository contains the implementation of Dawn, which is itself composed of
|
|||
|
||||
## Directory structure
|
||||
|
||||
- [`dawn.json`](../dawn.json): contains a description of the native WebGPU in JSON form. It is the data model that's used by the code generators.
|
||||
- [`dawn_wire.json`](../dawn_wire.json): contains additional information used to generate `dawn_wire` files, such as commands in addition to regular WebGPU commands.
|
||||
- [`examples`](../examples): a small collection of samples using the native WebGPU API. They were mostly used when bringing up Dawn for the first time, and to test the `WGPUSwapChain` object.
|
||||
- [`generator`](../generator): directory containg the code generators and their templates. Generators are based on Jinja2 and parse data-models from JSON files.
|
||||
- [`dawn_json_generator.py`](../generator/dawn_json_generator.py): the main code generator that outputs the WebGPU headers, C++ wrapper, client-server implementation, etc.
|
||||
- [`templates`](../generator/templates): Jinja2 templates for the generator, with subdirectories for groups of templates that are all used in the same library.
|
||||
- [`infra`](../infra): configuration file for the commit-queue infrastructure.
|
||||
- [`scripts`](../scripts): contains a grab-bag of files that are used for building Dawn, in testing, etc.
|
||||
- [`src`](../src):
|
||||
- [`dawn`](../src/dawn): root directory for Dawn code
|
||||
- [`common`](../src/dawn/common): helper code that is allowed to be used by Dawn's core libraries, `dawn_native` and `dawn_wire`. Also allowed for use in all other Dawn targets.
|
||||
- [`fuzzers`](../src/dawn/fuzzers): various fuzzers for Dawn that are running in [Clusterfuzz](https://google.github.io/clusterfuzz/).
|
||||
- [`native`](../src/dawn/native): code for the implementation of WebGPU on top of graphics APIs. Files in this folder are the "frontend" while subdirectories are "backends".
|
||||
- [`dawn.json`](../../dawn.json): contains a description of the native WebGPU in JSON form. It is the data model that's used by the code generators.
|
||||
- [`dawn_wire.json`](../../dawn_wire.json): contains additional information used to generate `dawn_wire` files, such as commands in addition to regular WebGPU commands.
|
||||
- [`generator`](../../generator): directory containg the code generators and their templates. Generators are based on Jinja2 and parse data-models from JSON files.
|
||||
- [`dawn_json_generator.py`](../../generator/dawn_json_generator.py): the main code generator that outputs the WebGPU headers, C++ wrapper, client-server implementation, etc.
|
||||
- [`templates`](../../generator/templates): Jinja2 templates for the generator, with subdirectories for groups of templates that are all used in the same library.
|
||||
- [`include`](../../include):
|
||||
- [`dawn`](../../include/dawn): public headers with subdirectories for each library. Note that some headers are auto-generated and not present directly in the directory.
|
||||
- [`infra`](../../infra): configuration file for the commit-queue infrastructure.
|
||||
- [`scripts`](../../scripts): contains a grab-bag of files that are used for building Dawn, in testing, etc.
|
||||
- [`src`](../../src):
|
||||
- [`dawn`](../../src/dawn): root directory for Dawn code
|
||||
- [`common`](../../src/dawn/common): helper code that is allowed to be used by Dawn's core libraries, `dawn_native` and `dawn_wire`. Also allowed for use in all other Dawn targets.
|
||||
- [`fuzzers`](../../src/dawn/fuzzers): various fuzzers for Dawn that are running in [Clusterfuzz](https://google.github.io/clusterfuzz/).
|
||||
- [`native`](../../src/dawn/native): code for the implementation of WebGPU on top of graphics APIs. Files in this folder are the "frontend" while subdirectories are "backends".
|
||||
- `<backend>`: code for the implementation of the backend on a specific graphics API, for example `d3d12`, `metal` or `vulkan`.
|
||||
- [`tests`](../src/dawn/tests):
|
||||
- [`end2end`](../src/dawn/tests/end2end): tests for the execution of the WebGPU API and require a GPU to run.
|
||||
- [`perf_tests`](../src/dawn/tests/perf_tests): benchmarks for various aspects of Dawn.
|
||||
- [`unittests`](../src/dawn/tests/unittests): code unittests of internal classes, but also by extension WebGPU API tests that don't require a GPU to run.
|
||||
- [`validation`](../src/dawn/tests/unittests/validation): WebGPU validation tests not using the GPU (frontend tests)
|
||||
- [`white_box`](../src/dawn/tests/white_box): tests using the GPU that need to access the internals of `dawn_native` or `dawn_wire`.
|
||||
- [`wire`](../src/dawn/wire): code for an implementation of WebGPU as a client-server architecture.
|
||||
- [`utils`](../src/dawn/utils): helper code to use Dawn used by tests and samples but disallowed for `dawn_native` and `dawn_wire`.
|
||||
- [`platform`](../src/dawn/platform): definition of interfaces for dependency injection in `dawn_native` or `dawn_wire`.
|
||||
- [`include`](../src/include): public headers with subdirectories for each library. Note that some headers are auto-generated and not present directly in the directory.
|
||||
- [`third_party`](../third_party): directory where dependencies live as well as their buildfiles.
|
||||
- [`samples`](../../src/dawn/samples): a small collection of samples using the native WebGPU API. They were mostly used when bringing up Dawn for the first time, and to test the `WGPUSwapChain` object.
|
||||
- [`tests`](../../src/dawn/tests):
|
||||
- [`end2end`](../../src/dawn/tests/end2end): tests for the execution of the WebGPU API and require a GPU to run.
|
||||
- [`perf_tests`](../../src/dawn/tests/perf_tests): benchmarks for various aspects of Dawn.
|
||||
- [`unittests`](../../src/dawn/tests/unittests): code unittests of internal classes, but also by extension WebGPU API tests that don't require a GPU to run.
|
||||
- [`validation`](../../src/dawn/tests/unittests/validation): WebGPU validation tests not using the GPU (frontend tests)
|
||||
- [`white_box`](../../src/dawn/tests/white_box): tests using the GPU that need to access the internals of `dawn_native` or `dawn_wire`.
|
||||
- [`wire`](../../src/dawn/wire): code for an implementation of WebGPU as a client-server architecture.
|
||||
- [`utils`](../../src/dawn/utils): helper code to use Dawn used by tests and samples but disallowed for `dawn_native` and `dawn_wire`.
|
||||
- [`platform`](../../src/dawn/platform): definition of interfaces for dependency injection in `dawn_native` or `dawn_wire`.
|
||||
- [`third_party`](../../third_party): directory where dependencies live as well as their buildfiles.
|
||||
|
||||
## Dawn Native (`dawn_native`)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use_dawn = true # Required to build Dawn
|
|||
use_cfi_icall=false # Required because Dawn dynamically loads function pointers, and we don't sanitize them yet.
|
||||
```
|
||||
|
||||
A Chromium checkout is required for the highest optimization flags. It is possible to build and run `dawn_perf_tests` from a standalone Dawn checkout as well, only using GN arg `is_debug=false`. For more information on building, please see [building.md](./building.md).
|
||||
A Chromium checkout is required for the highest optimization flags. It is possible to build and run `dawn_perf_tests` from a standalone Dawn checkout as well, only using GN arg `is_debug=false`. For more information on building, please see [building.md](../building.md).
|
||||
|
||||
### Terminology
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ Vulkan is supported as best effort on other platforms (e.g. Windows and macOS).
|
|||
|
||||
**Required features**: `depthBiasClamp`, `fragmentStoresAndAtomics`, `fullDrawIndexUint32`, `imageCubeArray`, `independentBlend`, `sampleRateShading`, and either `textureCompressionBC` or both of `textureCompressionETC` and `textureCompressionASTC_LDR`.
|
||||
|
||||
**Required limites**: they are too detailed to describe here, but in general should be wildly supported.
|
||||
**Required limits**: they are too detailed to describe here, but in general should be wildly supported.
|
||||
See the [WebGPU limits](https://gpuweb.github.io/gpuweb/#limits) that mostly correspond to Vulkan limits.
|
||||
|
||||
**Operating system support**:
|
||||
|
|
|
@ -7,7 +7,7 @@ Requirements:
|
|||
|
||||
## Building Tint with coverage generation enabled
|
||||
|
||||
Follow the steps [to build Tint with CMake](../README.md), but include the additional `-DTINT_EMIT_COVERAGE=1` CMake flag.
|
||||
Follow the steps [to build Tint with CMake](../building.md), but include the additional `-DDAWN_EMIT_COVERAGE=1` CMake flag.
|
||||
|
||||
## Generate coverage information
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ Quoting single word identifiers or keywords from the source is not discouraged.
|
|||
**Don't:**
|
||||
|
||||
```
|
||||
shader.wgsl:5:11 error: type cannot be used in storage class 'storage' as it is non-host-shareable
|
||||
shader.wgsl:5:11 error: type cannot be used in address space 'storage' as it is non-host-shareable
|
||||
|
||||
cond : bool;
|
||||
^^^^
|
||||
|
@ -72,7 +72,7 @@ shader.wgsl:5:11 error: type cannot be used in storage class 'storage' as it is
|
|||
**Do:**
|
||||
|
||||
```
|
||||
shader.wgsl:5:11 error: type cannot be used in storage class 'storage' as it is non-host-shareable
|
||||
shader.wgsl:5:11 error: type cannot be used in address space 'storage' as it is non-host-shareable
|
||||
|
||||
cond : bool;
|
||||
^^^^
|
||||
|
|
|
@ -12,7 +12,7 @@ Specification work in the WebGPU group hasn't started.
|
|||
|
||||
## Pseudo-specification
|
||||
|
||||
This extension adds a new `push_constant` storage class that's only allowed on global variable declarations.
|
||||
This extension adds a new `push_constant` address space that's only allowed on global variable declarations.
|
||||
Push constant variables must only contain 32bit data types (or aggregates of such types).
|
||||
Push constant variable declarations must not have an initializer.
|
||||
It is an error for a entry point to statically use more than one `push_constant` variable.
|
||||
|
|
|
@ -0,0 +1,411 @@
|
|||
# Intermediate Representation
|
||||
|
||||
As Tint has grown the number of transforms on the AST has grown. This
|
||||
growth has lead to several issues:
|
||||
|
||||
1. Transforms rebuild the AST and SEM which causes slowness
|
||||
1. Transforming in AST can be difficult as the AST is hard to work with
|
||||
|
||||
In order to address these goals, an IR is being introduced into Tint.
|
||||
The IR is mutable, it holds the needed state in order to be transformed.
|
||||
The IR is also translatable back into AST. It will be possible to
|
||||
generate an AST, convert to IR, transform, and then rebuild a new AST.
|
||||
This round-trip ability provides a few features:
|
||||
|
||||
1. Easy to integrate into current system by replacing AST transforms
|
||||
piecemeal
|
||||
1. Easier to test as the resulting AST can be emitted as WGSL and
|
||||
compared.
|
||||
|
||||
The IR helps with the complexity of the AST transforms by limiting the
|
||||
representations seen in the IR form. For example, instead of `for`,
|
||||
`while` and `loop` constructs there is a single `loop` construct.
|
||||
`alias` and `const_assert` nodes are not emitted into IR. Dead code is
|
||||
eliminated during the IR construction.
|
||||
|
||||
As the IR can convert into AST, we could potentially simplify the
|
||||
SPIRV-Reader by generating IR directly. The IR is closer to what SPIR-V
|
||||
looks like, so maybe a simpler transform.
|
||||
|
||||
## Design
|
||||
|
||||
The IR breaks down into two fundamental pieces, the control flow and the
|
||||
expression lists. While these can be thought of as separate pieces they
|
||||
are linked in that the control flow blocks contain the expression lists.
|
||||
A control flow block may use the result of an expression as the
|
||||
condition.
|
||||
|
||||
The IR works together with the AST/SEM. There is an underlying
|
||||
assumption that the source `Program` will live as long as the IR. The IR
|
||||
holds pointers to data from the `Program`. This includes things like SEM
|
||||
types, variables, statements, etc.
|
||||
|
||||
Transforming from AST to IR and back to AST is a lossy operation.
|
||||
The resulting AST when converting back will not be the same as the
|
||||
AST being provided. (e.g. all `for`, `while` and `loop` constructs coming
|
||||
in will become `while` loops going out). This is intentional as it
|
||||
greatly simplifies the number of things to consider in the IR. For
|
||||
instance:
|
||||
|
||||
* No `alias` nodes
|
||||
* No `const_assert` nodes
|
||||
* All loops become `while` loops
|
||||
* `if` statements may all become `if/else`
|
||||
|
||||
### Code Structure
|
||||
The code is contained in the `src/tint/ir` folder and is broken down
|
||||
into several classes. Note, the IR is a Tint _internal_ representation
|
||||
and these files should _never_ appear in the public API.
|
||||
|
||||
#### Builder
|
||||
The `Builder` class provides useful helper routines for creating IR
|
||||
content. The Builder owns an `ir::Module`, it can be created with an
|
||||
existing Module by moving it into the builder. The Module is moved from
|
||||
the builder when it is complete.
|
||||
|
||||
#### Module
|
||||
The top level of the IR is the `Module`. The module stores a list of
|
||||
`functions`, `entry_points`, allocators and various other bits of
|
||||
information needed by the IR. The `Module` also contains a pointer to
|
||||
the `Program` which the IR was created from. The `Program` must outlive
|
||||
the `Module`.
|
||||
|
||||
The `Module` provides two methods from moving two and from a `Program`.
|
||||
The `Module::FromProgram` static method will take a `Program` and
|
||||
construct an `ir::Module` from the contents. The resulting module class
|
||||
then has a `ToProgram` method which will construct a new `Program` from
|
||||
the `Module` contents.
|
||||
|
||||
#### BuilderImpl
|
||||
The `BuilderImpl` is internally used by the `Module` to do the
|
||||
conversion from a `Program` to a `Module`. This class should not be used
|
||||
outside the `src/tint/ir` folder.
|
||||
|
||||
### Transforms
|
||||
Similar to the AST a transform system is available for IR. The transform
|
||||
has the same setup as the AST (and inherits from the same base transform
|
||||
class.)
|
||||
|
||||
Note, not written yet.
|
||||
|
||||
### Scoping
|
||||
The IR flattens scopes. This also means that the IR will rename shadow
|
||||
variables to be uniquely named in the larger scoped block.
|
||||
|
||||
For an example of flattening:
|
||||
|
||||
```
|
||||
{
|
||||
var x = 1;
|
||||
{
|
||||
var y = 2;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
{
|
||||
var x = 1;
|
||||
var y = 2;
|
||||
}
|
||||
```
|
||||
|
||||
For an example of shadowing:
|
||||
|
||||
```
|
||||
{
|
||||
var x = 1;
|
||||
if (true) {
|
||||
var x = 2;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
{
|
||||
var x = 1;
|
||||
if true {
|
||||
var x_1 = 2;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Control Flow Blocks
|
||||
|
||||
At the top level, the AST is broken into a series of control flow nodes.
|
||||
There are a limited set of flow nodes as compared to AST:
|
||||
|
||||
1. Block
|
||||
1. Function
|
||||
1. If statement
|
||||
1. Loop statement
|
||||
1. Switch statement
|
||||
1. Terminator
|
||||
|
||||
As the IR is built a stack of control flow blocks is maintained. The
|
||||
stack contains `function`, `loop`, `if` and `switch` control flow
|
||||
blocks. A `function` is always the bottom element in the flow control
|
||||
stack.
|
||||
|
||||
The current instruction block is tracked. The tracking is reset to
|
||||
`nullptr` when a branch happens. This is used in the statement processing
|
||||
in order to eliminate dead code. If the current block does not exist, or
|
||||
has a branch target, then no further instructions can be added, which
|
||||
means all control flow has branched and any subsequent statements can be
|
||||
disregarded.
|
||||
|
||||
Note, this does have the effect that the inspector _must_ be run to
|
||||
retrieve the module interface before converting to IR. This is because
|
||||
phony assignments in dead code add variables into the interface.
|
||||
|
||||
```
|
||||
var<storage> b;
|
||||
|
||||
fn a() {
|
||||
return;
|
||||
_ = b; // This pulls b into the module interface but would be
|
||||
// dropped due to dead code removal.
|
||||
}
|
||||
```
|
||||
|
||||
#### Control Flow Block
|
||||
A block is the simplest control flow node. It contains the instruction
|
||||
lists for a given linear section of codes. A block only has one branch
|
||||
statement which always happens at the end of the block. Note, the branch
|
||||
statement is implicit, it doesn't show up in the expression list but is
|
||||
encoded in the `branch_target`.
|
||||
|
||||
In almost every case a block does not branch to another block. It will
|
||||
always branch to another control flow node. The exception to this rule
|
||||
is blocks branching to the function end block.
|
||||
|
||||
#### Control Flow Function
|
||||
A function control flow block has two targets associated with it, the
|
||||
`start_target` and the `end_target`. Function flow starts at the
|
||||
`start_target` and ends just before the `end_target`. The `end_target`
|
||||
is always a terminator, it just marks the end of the function
|
||||
(a return is a branch to the function `end_target`).
|
||||
|
||||
#### Control Flow If
|
||||
The if flow node is an `if-else` structure. There are no `else-if`
|
||||
entries, they get moved into the `else` of the `if`. The if control flow
|
||||
node has three targets, the `true_target`, `false_target` and possibly a
|
||||
`merge_target`.
|
||||
|
||||
The `merge_target` is possibly `nullptr`. This can happen if both
|
||||
branches of the `if` call `return` for instance as the internal branches
|
||||
would jump to the function `end_target`.
|
||||
|
||||
In all cases, the if node will have a `true_target` and a
|
||||
`false_target`, the target block maybe just a branch to the
|
||||
`merge_target` in the case where that branch of the if was empty.
|
||||
|
||||
#### Control Flow Loop
|
||||
All of the loop structures in AST merge down to a single loop control
|
||||
flow node. The loop contains the `start_target`, `continuing_target` and
|
||||
a `merge_target`.
|
||||
|
||||
In the case of a loop, the `merge_target` always exists, but may
|
||||
actually not exist in the control flow. The target is created in order
|
||||
to have a branch for `continue` to branch too, but if the loop body does
|
||||
a `return` then control flow may jump over that block completely.
|
||||
|
||||
The chain of blocks from the `start_target`, as long as it does not
|
||||
`break` or `return` will branch to the `continuing_target`. The
|
||||
`continuing_target` will possibly branch to the `merge_target` and will
|
||||
branch to the `start_target` for the loop.
|
||||
|
||||
A while loop is decomposed as listed in the WGSL spec:
|
||||
|
||||
```
|
||||
while (a < b) {
|
||||
c += 1;
|
||||
}
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
loop {
|
||||
if (!(a < b)) {
|
||||
break;
|
||||
}
|
||||
c += 1;
|
||||
}
|
||||
```
|
||||
|
||||
A for loop is decomposed as listed in the WGSL spec:
|
||||
```
|
||||
for (var i = 0; i < 10; i++) {
|
||||
c += 1;
|
||||
}
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
var i = 0;
|
||||
loop {
|
||||
if (!(i < 10)) {
|
||||
break;
|
||||
}
|
||||
|
||||
c += 1;
|
||||
|
||||
continuing {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Control Flow Switch
|
||||
The switch control flow has a target block for each of the
|
||||
`case/default` labels along with a `merge_target`. The `merge_target`
|
||||
while existing, maybe outside the control flow if all of the `case`
|
||||
branches `return`. The target exists in order to provide a `break`
|
||||
target.
|
||||
|
||||
#### Control Flow Terminator
|
||||
The terminator control flow is only used as the `end_target` of a
|
||||
function. It does not contain instructions and is only used as a marker
|
||||
for the exit of a function.
|
||||
|
||||
### Expression Lists.
|
||||
Note, this section isn't fully formed as this has not been written at
|
||||
this point.
|
||||
|
||||
The expression lists are all in SSA form. The SSA variables will keep
|
||||
pointers back to the source AST variables in order for us to not require
|
||||
PHI nodes and to make it easier to move back out of SSA form.
|
||||
|
||||
#### Expressions
|
||||
All expressions in IR are single operations. There are no complex
|
||||
expressions. Any complex expression in the AST is broke apart into the
|
||||
simpler single operation components.
|
||||
|
||||
```
|
||||
var a = b + c - (4 * k);
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
%t0 = b + c
|
||||
%t1 = 4 * k
|
||||
%v0 = %t0 - %t1
|
||||
```
|
||||
|
||||
This also means that many of the short forms `i += 1`, `i++` get
|
||||
expanded into the longer form of `i = i + 1`.
|
||||
|
||||
##### Short-Circuit Expressions
|
||||
The short-circuit expressions (e.g. `a && b`) will be convert into an
|
||||
`if` structure control flow.
|
||||
|
||||
```
|
||||
let c = a() && b()
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```
|
||||
let c = a();
|
||||
if (c) {
|
||||
c = b();
|
||||
}
|
||||
```
|
||||
|
||||
#### Registers
|
||||
There are several types of registers used in the SSA form.
|
||||
|
||||
1. Constant Register
|
||||
1. Temporary Register
|
||||
1. Variable Register
|
||||
1. Return Register
|
||||
1. Function Argument Register
|
||||
|
||||
##### Constant Register
|
||||
The constant register `%c` holds a constant value. All values in IR are
|
||||
concrete, there are no abstract values as materialization has already
|
||||
happened. Each constant register holds a single constant value (e.g.
|
||||
`3.14`) and a pointee to the type (maybe? If needed.)
|
||||
|
||||
##### Temporary Register
|
||||
The temporary register `%t` hold the results of a simple operation. The
|
||||
temporaries are created as complex expressions are broken down into
|
||||
pieces. The temporary register tracks the usage count for the register.
|
||||
This allows a portion of a calculation to be pulled out when rebuilding
|
||||
AST as a common calculation. If the temporary is used once it can be
|
||||
re-combine back into a large expression.
|
||||
|
||||
##### Variable Register
|
||||
The variable register `%v` potentially holds a pointer back to source
|
||||
variables. So, while each value is written only once, if the pointer
|
||||
back to an AST variable exists we can rebuild the variable that value
|
||||
was originally created from and can assign back when converting to AST.
|
||||
|
||||
##### Return Register
|
||||
Each function has a return register `%r` where the return value will be
|
||||
stored before the final block branches to the `end_target`.
|
||||
|
||||
##### Function Argument Register
|
||||
The function argument registers `%a` are used to store the values being
|
||||
passed into a function call.
|
||||
|
||||
#### Type Information
|
||||
The IR shares type information with the SEM. The types are the same, but
|
||||
they may exist in different block allocations. The SEM types will be
|
||||
re-used if they exist, but if the IR needs to create a new type it will
|
||||
be created in the IRs type block allocator.
|
||||
|
||||
#### Loads / Stores and Deref
|
||||
Note, have not thought about this. We should probably have explicit
|
||||
load/store operations injected in the right spot, but don't know yet.
|
||||
|
||||
## Alternatives
|
||||
Instead of going to a custom IR there are several possible other roads
|
||||
that could be travelled.
|
||||
|
||||
### Mutable AST
|
||||
Tint originally contained a mutable AST. This was converted to immutable
|
||||
in order to allow processing over multiple threads and for safety
|
||||
properties. Those desires still hold, the AST is public API, and we want
|
||||
it to be as safe as possible, so keeping it immutable provides that
|
||||
guarantee.
|
||||
|
||||
### Multiple Transforms With One Program Builder
|
||||
Instead of generating an immutable AST after each transform, running
|
||||
multiple transforms on the single program builder would remove some of
|
||||
the performance penalties of going to and from immutable AST. While this
|
||||
is true, the transforms use a combination of AST and SEM information.
|
||||
When they transform they _do not_ create new SEM information. That
|
||||
means, after a given transform, the SEM is out of date. In order to
|
||||
re-generate the SEM the resolver needs to be rerun. Supporting this
|
||||
would require being very careful on what transforms run together and
|
||||
how they modify the AST.
|
||||
|
||||
### Adopt An Existing IR
|
||||
There are already several IRs in the while, Mesa has NIR, LLVM has
|
||||
LLVM IR. There are others, adopting one of those would remove the
|
||||
requirements of writing and maintaining our own IR. While that is true,
|
||||
there are several downsides to this re-use. The IRs are internal to the
|
||||
library, so the API isn't public, LLVM IR changes with each iteration of
|
||||
LLVM. This would require us to adapt the AST -> IR -> AST transform for
|
||||
each modification of the IR.
|
||||
|
||||
They also end up being lower level then is strictly useful for us. While
|
||||
the IR in Tint is a simplified form, we still have to be able to go back
|
||||
to the high level structured form in order to emit the resulting HLSL,
|
||||
MSL, GLSL, etc. (Only SPIR-V is a good match for the lowered IR form).
|
||||
This transformation back is not a direction other IRs maybe interested
|
||||
in so may have lost information, or require re-determining (determining
|
||||
variables from SSA and PHI nodes for example).
|
||||
|
||||
Other technical reasons are the maintenance of BUILD.gn and CMake files
|
||||
in order to integrate into our build systems, along with resulting
|
||||
binary size questions from pulling in external systems.
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# Tint Source Layering
|
||||
|
||||
The `BUILD.gn` is setup with small source units for various components
|
||||
in Tint. The hierarchy of sources almost matches to folder structure in
|
||||
tint (except for `base` which is a mix of things in `src/tint` and
|
||||
`src/tint/util`.
|
||||
|
||||
|
||||
```
|
||||
+-----------------------------------------+
|
||||
| Readers | Writers |
|
||||
+-----------------------------------------+
|
||||
|
|
||||
V
|
||||
+-----------------------------------------+
|
||||
| Val | Inspector | Transform |
|
||||
+-----------------------------------------+
|
||||
| |
|
||||
+--------------+------------------------------+
|
||||
| |
|
||||
V V
|
||||
+-----------------------------------------+ +-----------+
|
||||
| AST | | Utils IO |
|
||||
+-----------------------------------------+ +-----------+
|
||||
| |
|
||||
V |
|
||||
+-----------------------------------------+ |
|
||||
| Program | Sem | |
|
||||
+-----------------------------------------+ |
|
||||
| |
|
||||
V |
|
||||
+-----------------------------------------+ |
|
||||
| AST Hdrs | |
|
||||
| (program and sem cause a cycle) | |
|
||||
+-----------------------------------------+ |
|
||||
| |
|
||||
V |
|
||||
+-----------------------------------------+ |
|
||||
| Clone Context Hdrs | |
|
||||
| (program and sem cause a cycle) | |
|
||||
+-----------------------------------------+ |
|
||||
| |
|
||||
V |
|
||||
+-----------------------------------------+ |
|
||||
| Constant | |
|
||||
+-----------------------------------------+ |
|
||||
| |
|
||||
V |
|
||||
+-----------------------------------------+ |
|
||||
| Types | |
|
||||
+-----------------------------------------+ |
|
||||
| |
|
||||
|------------------------------+
|
||||
V
|
||||
+-----------------------------------------+
|
||||
| Symbols |
|
||||
+-----------------------------------------+
|
||||
|
|
||||
V
|
||||
+-----------------------------------------+
|
||||
| Builtin |
|
||||
+-----------------------------------------+
|
||||
|
|
||||
V
|
||||
+-----------------------------------------+ +-------------+
|
||||
| Utils | | Initializer |
|
||||
+-----------------------------------------+ +-------------+
|
||||
```
|
|
@ -1,5 +1,87 @@
|
|||
# Tint changes during Origin Trial
|
||||
|
||||
## Changes for M112
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Most builtin functions that return a value can no longer be used as a call statement. [tint:1844](crbug.com/tint/1844)
|
||||
* The `sig` member of the return type of `frexp()` has been renamed to `fract`. [tint:1766](crbug.com/tint/1766)
|
||||
* Calling a function with multiple pointer arguments that alias each other is now a error. [tint:1675](crbug.com/tint/1675)
|
||||
* `type` deprecation has been removed. `alias` must be used now. [tint:1812](crbug.com/tint/1812)
|
||||
* `static_assert` deprecation has been removed. `const_assert` must now be used. [tint:1807](crbug.com/tint/1807)
|
||||
|
||||
## Changes for M111
|
||||
|
||||
### New features
|
||||
|
||||
* The `workgroupUniformLoad` builtin function is now supported. [tint:1780](crbug.com/tint/1780)
|
||||
* The `diagnostic` directive and `@diagnostic` attribute are now supported. [tint:1809](crbug.com/tint/1809)
|
||||
* The attribute is currently only supported on function declarations.
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* You may need to add parentheses to less-than or greater-than binary expressions that now parse as template lists. For example `a(b<c, d>e)` will need parentheses around `b<c` or `d>e`. [tint:1810](crbug.com/tint/1810).
|
||||
* Uniformity analysis failures are now an error [tint:880](crbug.com/tint/880)
|
||||
* The `derivative_uniformity` diagnostic filter can be used to modify the severity if needed.
|
||||
|
||||
## Deprecated Features
|
||||
|
||||
* The keyword to alias a type has been renamed from `type` to `alias`. [tint:1812](crbug.com/tint/1812)
|
||||
* `static_assert` has been renamed to `const_assert`. [tint:1807](crbug.com/tint/1807)
|
||||
|
||||
## Changes for M110
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* The `textureSampleLevel()` overload for `texture_external` has been removed. Use `textureSampleBaseClampToEdge()`. [tint:1671](crbug.com/tint/1671)
|
||||
|
||||
### Deprecated Features
|
||||
|
||||
* The `sig` member of the return type of `frexp()` has been renamed to `fract`. [tint:1757](crbug.com/tint/1757)
|
||||
* Calling a function with multiple pointer arguments that alias each other is now a warning, and
|
||||
will become an error in a future release. [tint:1675](crbug.com/tint/1675)
|
||||
|
||||
## Changes for M109
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* `textureDimensions()`, `textureNumLayers()` and `textureNumLevels()` now return unsigned integers / vectors. [tint:1526](crbug.com/tint/1526)
|
||||
* The `@stage` attribute has been removed. The short forms should be used
|
||||
instead (`@vertex`, `@fragment`, or `@compute`). [tint:1503](crbug.com/tint/1503)
|
||||
* Module-scope `let` is now an error. Use module-scope `const` instead. [tint:1580](crbug.com/tint/1584)
|
||||
* Reserved words are now an error instead of a deprecation. [tint:1463](crbug.com/tint/1463)
|
||||
* You may no longer use pointer parameters in `workgroup` address space. [tint:1721](crbug.com/tint/1721)
|
||||
|
||||
### New features
|
||||
|
||||
* Uniformity analysis failures are warnings again [tint:1728](crbug.com/tint/1728)
|
||||
* You can now call texture builtins with a mix of signed and unsigned integer arguments. [tint:1733](crbug.com/tint/1733)
|
||||
|
||||
## Changes for M108
|
||||
|
||||
### New features
|
||||
|
||||
* `textureSampleBaseClampToEdge()` has been implemented. [tint:1671](crbug.com/tint/1671)
|
||||
|
||||
### Deprecated Features
|
||||
|
||||
* The `external_texture` overload of `textureSampleLevel()` has been deprecated. Use `textureSampleBaseClampToEdge()` instead. [tint:1671](crbug.com/tint/1671)
|
||||
|
||||
### Fixes
|
||||
|
||||
* Constant evaluation of type conversions where the value exceeds the limits of the target type have been fixed. [tint:1707](crbug.com/tint/1707)
|
||||
|
||||
## Changes for M107
|
||||
|
||||
### New features
|
||||
|
||||
* `saturate()` has been implemented. [tint:1591](crbug.com/tint/1591)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Uniformity analysis failures are now an error [tint:880](crbug.com/tint/880)
|
||||
* Indexing an array, vector or matrix with a compile-time expression that's out-of-bounds is now an error [tint:1665](crbug.com/tint/1665)
|
||||
|
||||
## Changes for M106
|
||||
|
||||
### New features
|
||||
|
|
|
@ -15,7 +15,7 @@ as variables at module scope.
|
|||
## Vulkan SPIR-V today
|
||||
|
||||
SPIR-V for Vulkan models inputs and outputs as module-scope variables in
|
||||
the Input and Output storage classes, respectively.
|
||||
the Input and Output address spaces, respectively.
|
||||
|
||||
The `OpEntryPoint` instruction has a list of module-scope variables that must
|
||||
be a superset of all the input and output variables that are statically
|
||||
|
|
|
@ -0,0 +1,558 @@
|
|||
# Converting SPIR-V to WGSL
|
||||
|
||||
This document describes the challenges in converting SPIR-V into WGSL.
|
||||
|
||||
Note: Unless otherwise specified, the namespace for C++ code is
|
||||
`tint::reader::spirv::`.
|
||||
|
||||
## Overall flow
|
||||
|
||||
1. Validate the SPIR-V input.
|
||||
|
||||
The SPIR-V module (binary blob) is validated against rules for
|
||||
Vulkan 1.1, using the SPIRV-Tools validator.
|
||||
|
||||
This allows the rest of the flow to ignore invalid inputs.
|
||||
However, the SPIR-V might still be rejected in a later step because:
|
||||
|
||||
- it uses features unavailable in WGSL, or
|
||||
- the SPIR-V Reader is insufficiently smart, or
|
||||
- the translated program tries to do something rejected by WGSL's rules
|
||||
(which are checked by Tint's Resolver).
|
||||
|
||||
2. Load the SPIR-V binary into an in-memory representation.
|
||||
|
||||
The SPIR-V reader uses the in-memory representation of the SPIR-V
|
||||
module defined by the SPIRV-Tools optimizer. That provides
|
||||
convenient representation of basic structures such as:
|
||||
|
||||
- instructions
|
||||
- types
|
||||
- constants
|
||||
- functions
|
||||
- basic blocks
|
||||
|
||||
and provides analyses for:
|
||||
|
||||
- relating definitions to uses (spvtools::opt::analysis::DefUseMgr)
|
||||
- types (spvtools::opt::analysis:TypeManager)
|
||||
- constants (spvtools::opt::analysis:ConstantManager)
|
||||
|
||||
Note: The SPIR-V is not modified by the SPIR-V Reader.
|
||||
|
||||
3. Translate the SPIR-V module into Tint's AST.
|
||||
|
||||
The AST is valid for WGSL except for some small exceptions which are
|
||||
cleaned up by transformations.
|
||||
|
||||
4. Post-process the AST to make it valid for WGSL.
|
||||
|
||||
Example:
|
||||
- Rewrite strided arrays and matrices (remove `@stride` attribute)
|
||||
- Rewrite atomic functions
|
||||
- Remove unreachable statements, to satisfy WGSL's behaviour analysis.
|
||||
|
||||
|
||||
## Overcoming mismatches between SPIR-V and WGSL
|
||||
|
||||
### Remapping builtin inputs and outputs
|
||||
|
||||
SPIR-V for Vulkan models builtin inputs and outputs as variables
|
||||
in Input and Output storage classes.
|
||||
|
||||
WGSL builtin inputs are parameters to the entry point, and
|
||||
builtin outputs are result values of the entry point.
|
||||
|
||||
See [spirv-input-output-variables.md](spirv-input-output-variables.md)
|
||||
|
||||
### We only care about `gl_Position` from `gl_PerVertex`
|
||||
|
||||
Glslang SPIR-V output for a vertex shader has a `gl_PerVertex`
|
||||
output variable with four members:
|
||||
|
||||
- `gl_Position`
|
||||
- `gl_PointSize`
|
||||
- `gl_ClipDistance`
|
||||
- `gl_CullDistance`
|
||||
|
||||
WGSL only supports the `position` builtin variable.
|
||||
|
||||
The SPIR-V Reader has a bunch of carveouts so it only generates the
|
||||
position variable. In partcular, it tracks which expressions are actually
|
||||
accesses into the per-vertex variable, and ignores accesses to other
|
||||
parts of the structure, and remaps accesses of the position member.
|
||||
|
||||
### `gl_PointSize` must be 1.0
|
||||
|
||||
It's a WGSL rule. SPIR-V is more flexible, and the SPIR-V Reader
|
||||
checks that any assignment to (the equivalent of) `gl_PointSize`
|
||||
must the constant value 1.0.
|
||||
|
||||
### Remapping sample mask inputs and outputs
|
||||
|
||||
There's some shenanigans here I don't recall.
|
||||
See the SkipReason enum.
|
||||
|
||||
### Integer signedness
|
||||
|
||||
In SPIR-V, the instruction determines the signedness of an operation,
|
||||
not the types of its operands.
|
||||
|
||||
For example:
|
||||
|
||||
%uint = OpTypeInt 32 0 ; u32 type
|
||||
%int = OpTypeInt 32 1 ; i32 type
|
||||
|
||||
%int_1 = OpConstant %int 1 ; WGSL 1i
|
||||
%uint_2 = OpConstant %uint 2 ; WGSL 2u
|
||||
|
||||
; You can mix signs of an operand, and the instruction
|
||||
; tells you the result type.
|
||||
%sum_uint = OpIAdd %uint %int %int_1 %uint_2
|
||||
%sum_int = OpIAdd %int %int %int_1 %uint_2
|
||||
|
||||
However, WGSL arithmetic tends to require the operands and
|
||||
result type for an operation to all have the same signedness.
|
||||
|
||||
So the above might translate to WGSL as:
|
||||
|
||||
let sum_uint: u32 = bitcast<u32>(1i) + 2u;
|
||||
let sum_int: i32 = 1i + bitcast<i32>(2u);
|
||||
|
||||
See:
|
||||
* ParserImpl::RectifyOperandSignedness
|
||||
* ParserImpl::RectifySecondOperandSignedness
|
||||
* ParserImpl::RectifyForcedResultType
|
||||
|
||||
### Translating textures and samplers
|
||||
|
||||
SPIR-V textures and samplers are module-scope variables
|
||||
in UniformConstant storage class.
|
||||
These map directly to WGSL variables.
|
||||
|
||||
For a sampled-image operation, SPIR-V will:
|
||||
- load the image value from a texture variable
|
||||
- load the sampler value from a sampler variable
|
||||
- form a "sampled image" value using `SpvOpSampledImage`
|
||||
- then use that sampled image value in a image operation
|
||||
such as `SpvOpImageSampleImplicitLod`
|
||||
|
||||
For an image operation that is not a sampled-image operation
|
||||
(e.g. OpImageLoad or OpImageWrite), then the steps are similar
|
||||
except without a sampler (clearly), and without invoking
|
||||
`OpSampledImage`.
|
||||
|
||||
In contrast to the SPIR-V code pattern, the WGSL builtin requires
|
||||
the texture and sampler value to be passed in as separate parameters.
|
||||
Secondly, they are passed in by value, by naming the variables
|
||||
themselves and relying on WGSL's "Load Rule" to pass the handle
|
||||
value into the callee.
|
||||
|
||||
When the SPIR-V Reader translates a texture builtin, it traces
|
||||
backward through the `OpSampledImage` operation (if any),
|
||||
back through the load, and all the way back to the `OpVariable`
|
||||
declaration. It does this for both the image/texture variable and
|
||||
the sampler variable (if applicable). It then uses the names
|
||||
of those variables as the corresponding arguments to the WGSL
|
||||
texture builtin.
|
||||
|
||||
### Passing textures and samplers into helper functions
|
||||
|
||||
Glslang generates SPIR-V where texture and sampler formal parameters
|
||||
are as pointer-to-UniformConstant.
|
||||
|
||||
WGSL models them as passing texture and sampler values themselves,
|
||||
conceptually as opaque handles. This is similar to GLSL, but unlike
|
||||
SPIR-V.
|
||||
|
||||
To support textures and samplers as arguments to user-defined functions,
|
||||
we extend the tracing logic so it knows to bottom out at OpFunctionParameter.
|
||||
|
||||
Also, code that generates function declarations now understands formal
|
||||
parameters declared as a pointer to uniform-constant as
|
||||
well as direct image and sampler values.
|
||||
|
||||
Example GLSL compute shader:
|
||||
|
||||
#version 450
|
||||
|
||||
layout(set=0,binding=0) uniform texture2D im;
|
||||
layout(set=0,binding=1) uniform sampler s;
|
||||
|
||||
vec4 helper(texture2D imparam, sampler sparam) {
|
||||
return texture(sampler2D(imparam,sparam),vec2(0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 v = helper(im,s);
|
||||
}
|
||||
|
||||
SPIR-V generated by Glslang (Shaderc's glslc):
|
||||
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Google Shaderc over Glslang; 10
|
||||
; Bound: 32
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpSource GLSL 450
|
||||
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
|
||||
OpSourceExtension "GL_GOOGLE_include_directive"
|
||||
OpName %main "main"
|
||||
OpName %helper_t21_p1_ "helper(t21;p1;"
|
||||
OpName %imparam "imparam"
|
||||
OpName %sparam "sparam"
|
||||
OpName %v "v"
|
||||
OpName %im "im"
|
||||
OpName %s "s"
|
||||
OpDecorate %im DescriptorSet 0
|
||||
OpDecorate %im Binding 0
|
||||
OpDecorate %s DescriptorSet 0
|
||||
OpDecorate %s Binding 1
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%7 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
|
||||
%9 = OpTypeSampler
|
||||
%_ptr_UniformConstant_9 = OpTypePointer UniformConstant %9
|
||||
%v4float = OpTypeVector %float 4
|
||||
%12 = OpTypeFunction %v4float %_ptr_UniformConstant_7 %_ptr_UniformConstant_9
|
||||
%19 = OpTypeSampledImage %7
|
||||
%v2float = OpTypeVector %float 2
|
||||
%float_0 = OpConstant %float 0
|
||||
%23 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%im = OpVariable %_ptr_UniformConstant_7 UniformConstant
|
||||
%s = OpVariable %_ptr_UniformConstant_9 UniformConstant
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_v4float Function
|
||||
%31 = OpFunctionCall %v4float %helper_t21_p1_ %im %s
|
||||
OpStore %v %31
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%helper_t21_p1_ = OpFunction %v4float None %12
|
||||
%imparam = OpFunctionParameter %_ptr_UniformConstant_7
|
||||
%sparam = OpFunctionParameter %_ptr_UniformConstant_9
|
||||
%16 = OpLabel
|
||||
%17 = OpLoad %7 %imparam
|
||||
%18 = OpLoad %9 %sparam
|
||||
%20 = OpSampledImage %19 %17 %18
|
||||
%24 = OpImageSampleExplicitLod %v4float %20 %23 Lod %float_0
|
||||
OpReturnValue %24
|
||||
OpFunctionEnd
|
||||
|
||||
What the SPIR-V Reader currently generates:
|
||||
|
||||
@group(0) @binding(0) var im : texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1) var s : sampler;
|
||||
|
||||
fn helper_t21_p1_(imparam : texture_2d<f32>, sparam : sampler) -> vec4<f32> {
|
||||
let x_24 : vec4<f32> = textureSampleLevel(imparam, sparam, vec2<f32>(0.0f, 0.0f), 0.0f);
|
||||
return x_24;
|
||||
}
|
||||
|
||||
fn main_1() {
|
||||
var v : vec4<f32>;
|
||||
let x_31 : vec4<f32> = helper_t21_p1_(im, s);
|
||||
v = x_31;
|
||||
return;
|
||||
}
|
||||
|
||||
@compute @workgroup_size(1i, 1i, 1i)
|
||||
fn main() {
|
||||
main_1();
|
||||
}
|
||||
|
||||
### Dimensionality mismatch in texture builtins
|
||||
|
||||
Vulkan SPIR-V is fairly forgiving in the dimensionality
|
||||
of input coordinates and result values of texturing operations.
|
||||
There is some localized rewriting of values to satisfy the overloads
|
||||
of WGSL's texture builtin functions.
|
||||
|
||||
### Reconstructing structured control flow
|
||||
|
||||
This is subtle.
|
||||
|
||||
- Use structural dominance (but we didn't have the name at the time).
|
||||
See SPIR-V 1.6 Rev 2 for updated definitions.
|
||||
- See the big comment at the start of reader/spirv/function.cc
|
||||
- See internal presentations.
|
||||
|
||||
Basically:
|
||||
* Compute a "structured order" for structurally reachable basic blocks.
|
||||
* Traversing in structured order, use a stack-based algorithn to
|
||||
identify intervals of blocks corresponding to structured constructs.
|
||||
For example, loop construct, continue construct, if-selection,
|
||||
switch-selection, and case-construct. Constructs can be nested,
|
||||
hence the need for a stack. This is akin to "drawing braces"
|
||||
around statements, to form block-statements that will appear in
|
||||
the output. This step performs some validation, which may now be
|
||||
redundant with the SPIRV-Tools validator. This is defensive
|
||||
programming, and some tests skip use of the SPIRV-Tools validator.
|
||||
* Traversing in structured order, identify structured exits from the
|
||||
constructs identified in the previous step. This determines what
|
||||
control flow edges correspond to `break`, `continue`, and `return`,
|
||||
as needed.
|
||||
* Traversing in structured order, generate statements for instructions.
|
||||
This uses a stack corresponding to nested constructs. The kind of
|
||||
each construct being entered or exited determines emission of control
|
||||
flow constructs (WGSL's `if`, `loop`, `continuing`, `switch`, `case`).
|
||||
|
||||
### Preserving execution order
|
||||
|
||||
An instruction inside a SPIR-V instruction is one of:
|
||||
|
||||
- control flow: see the previous section
|
||||
- combinatorial: think of this as an ALU operation, i.e. the effect
|
||||
is purely to evaluate a result value from the values of its operands.
|
||||
It has no side effects, and is not affected by external state such
|
||||
as memory or the actions of other invocations in its subgroup.
|
||||
Examples: arithmetic, OpCopyObject
|
||||
- interacts with memory or other invocations in some way.
|
||||
Examples: load, store, atomics, barriers, (subgroup operations when we
|
||||
get them)
|
||||
- function calls: functions are not analyzed to see if they are pure,
|
||||
so we assume function calls are non-combinatorial.
|
||||
|
||||
To preserve execution order, all non-combinatorial instructions must
|
||||
be translated as their own separate statement. For example, an OpStore
|
||||
maps to an assignment statement.
|
||||
|
||||
However, combinatorial instructions can be emitted at any point
|
||||
in evaluation, provided data flow constraints are satisfied: input
|
||||
values are available, and such that the resulting value is generated
|
||||
in time for consumption by downstream uses.
|
||||
|
||||
The SPIR-V Reader uses a heuristic to choose when to emit combinatorial
|
||||
values:
|
||||
- if a combinatorial expression only has one use, *and*
|
||||
- its use is in the same structured construct as its definition, *then*
|
||||
- emit the expression at the place where it is consumed.
|
||||
|
||||
Otherwise, make a `let` declaration for the value.
|
||||
|
||||
Why:
|
||||
- If a value has many uses, then computing it once can save effort.
|
||||
Preserve that choice if it was made by an upstream optimizing compiler.
|
||||
- If a value is consumed in a different structured construct, then the
|
||||
site of its consumption may be inside a loop, and we don't want to
|
||||
sink the computation into the loop, thereby causing spurious extra
|
||||
evaluation.
|
||||
|
||||
This heuristic generates halfway-readable code, greatly reducing the
|
||||
varbosity of code in the common case.
|
||||
|
||||
### Hoisting and phis
|
||||
|
||||
SPIR-V uses SSA (static single assignment). The key requirement is
|
||||
that the definition of a value must dominate its uses.
|
||||
|
||||
WGSL uses lexical scoping.
|
||||
|
||||
It is easy enough for a human or an optimizing compiler to generate
|
||||
SSA cases which do not map cleanly to a lexically scoped value.
|
||||
|
||||
Example pseudo-GLSL:
|
||||
|
||||
void main() {
|
||||
if (cond) {
|
||||
const uint x = 1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const uint y = x; // x's definition dominates this use.
|
||||
}
|
||||
|
||||
This isn't valid GLSL and its analog would not be a valid WGSL
|
||||
program because x is used outside the scope of its declaration.
|
||||
|
||||
Additionally, SSA uses `phi` nodes to transmit values from predecessor
|
||||
basic blocks that would otherwise not be visible (because the
|
||||
parent does not dominate the consuming basic block). An example
|
||||
is sending the updated value of a loop induction variable back to
|
||||
the top of the loop.
|
||||
|
||||
The SPIR-V reader handles these cases by tracking:
|
||||
- where a value definition occurs
|
||||
- the span of basic blocks, in structured order, where there
|
||||
are uses of the value.
|
||||
|
||||
If the uses of a value span structured contructs which are not
|
||||
contained by the construct containing the definition (or
|
||||
if the value is a `phi` node), then we "hoist" the value
|
||||
into a variable:
|
||||
|
||||
- create a function-scope variable at the top of the structured
|
||||
construct that spans all the uses, so that all the uses
|
||||
are in scope of that variable declaration.
|
||||
|
||||
- for a non-phi: generate an assignment to that variable corresponding
|
||||
to the value definition in the original SPIR-V.
|
||||
|
||||
- for a phi: generate an assigment to that variable at the end of
|
||||
each predecessor block for that phi, assigning the value to be
|
||||
transmitted from that phi.
|
||||
|
||||
This scheme works for values which can be the stored in a variable.
|
||||
|
||||
It does not work for pointers. However, we don't think we need
|
||||
to solve this case any time soon as it is uncommon or hard/impossible
|
||||
to generate via standard tooling.
|
||||
See https://crbug.com/tint/98 and https://crbug.com/tint/837
|
||||
|
||||
## Mapping types
|
||||
|
||||
SPIR-V has a recursive type system. Types are defined, given result IDs,
|
||||
before any functions are defined, and before any constant values using
|
||||
the corresponding types.
|
||||
|
||||
WGSL also has a recursive type system. However, except for structure types,
|
||||
types are spelled inline at their uses.
|
||||
|
||||
## Texture and sampler types
|
||||
|
||||
SPIR-V image types map to WGSL types, but the WGSL type is determined
|
||||
more by usage (what operations are performed on it) than by declaration.
|
||||
|
||||
For example, Vulkan ignores the "Depth" operand of the image type
|
||||
declaration (OpTypeImage).
|
||||
See [16.1 Image Operations Overview](https://registry.khronos.org/vulkan/specs/1.3/html/vkspec.html#_image_operations_overview).
|
||||
Instead, we must infer that a texture is a depth texture because
|
||||
it is used by image instructions using a depth-reference, e.g.
|
||||
OpImageSampleDrefImplicitLod vs. OpImageSampleImplicitLod.
|
||||
|
||||
Similarly, SPIR-V only has one sampler type. The use of the
|
||||
sampler determines whether it maps to a WGSL `sampler` or
|
||||
`sampler_comparison` (for depth sampling).
|
||||
|
||||
The SPIR-V Reader scans uses of each texture and sampler
|
||||
in the module to infer the appropriate target WGSL type.
|
||||
See ParserImpl::RegisterHandleUsage
|
||||
|
||||
In Vulkan SPIR-V it is possible to use the same sampler for regular
|
||||
sampling and depth-reference sampling. In this case the SPIR-V Reader
|
||||
will infer a depth texture, but then the generated program will fail WGSL
|
||||
validation.
|
||||
|
||||
For example, this GLSL fragment shader:
|
||||
|
||||
#version 450
|
||||
|
||||
layout(set=1,binding=0) uniform texture2D tInput;
|
||||
layout(set=1,binding=1) uniform sampler s;
|
||||
|
||||
void main() {
|
||||
vec4 v = texture(sampler2D(tInput,s),vec2(0));
|
||||
float f = texture(sampler2DShadow(tInput,s),vec3(0));
|
||||
}
|
||||
|
||||
Converts to this WGSL shader:
|
||||
|
||||
@group(1) @binding(0) var tInput : texture_depth_2d;
|
||||
|
||||
@group(1) @binding(1) var s : sampler_comparison;
|
||||
|
||||
fn main_1() {
|
||||
var v : vec4<f32>;
|
||||
var f : f32;
|
||||
let x_23 : vec4<f32> = vec4<f32>(textureSample(tInput, s, vec2<f32>(0.0f, 0.0f)), 0.0f, 0.0f, 0.0f);
|
||||
v = x_23;
|
||||
let x_34 : f32 = textureSampleCompare(tInput, s, vec3<f32>(0.0f, 0.0f, 0.0f).xy, vec3<f32>(0.0f, 0.0f, 0.0f).z);
|
||||
f = x_34;
|
||||
return;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn main() {
|
||||
main_1();
|
||||
}
|
||||
|
||||
But then this fails validation:
|
||||
|
||||
error: no matching call to textureSample(texture_depth_2d, sampler_comparison, vec2<f32>)
|
||||
15 candidate functions: ...
|
||||
|
||||
## References and pointers
|
||||
|
||||
SPIR-V has a pointer type.
|
||||
|
||||
A SPIR-V pointer type corresponds to a WGSL memory view. WGSL has two
|
||||
memory view types: a reference type, and a pointer type.
|
||||
|
||||
See [spirv-ptr-ref.md](spirv-ptr-ref.md) for details on the translation.
|
||||
|
||||
## Mapping buffer types
|
||||
|
||||
Vulkan SPIR-V expresses a Uniform Buffer Object (UBO), or
|
||||
a WGSL 'uniform buffer' as:
|
||||
|
||||
- an OpVariable in Uniform storage class
|
||||
- its pointee type (store type) is a Block-decorated structure type
|
||||
|
||||
Vulkan SPIR-V has two ways to express a Shader Storage Buffer Object (SSBO),
|
||||
or a WGSL 'storage buffer' as either deprecated-style:
|
||||
|
||||
- an OpVariable in Uniform storage class
|
||||
- its pointee type (store type) is a BufferBlock-decorated structure type
|
||||
|
||||
or as new-style:
|
||||
|
||||
- an OpVariable in StorageBuffer storage class
|
||||
- its pointee type (store type) is a Block-decorated structure type
|
||||
|
||||
Deprecated-style storage buffer was the only option in un-extended
|
||||
Vulkan 1.0. It is generated by tools that want to generate code for
|
||||
the broadest reach. This includes DXC.
|
||||
|
||||
New-style storage buffer requires the use of the `OpExtension
|
||||
"SPV_KHR_storage_buffer_storage_class"` or SPIR-V 1.3 or later
|
||||
(Vulkan 1.1 or later).
|
||||
|
||||
Additionally, a storage buffer in SPIR-V may be marked as NonWritable.
|
||||
Perhaps surprisingly, this is typically done by marking *all* the
|
||||
members of the top-level (Buffer)Block-decorated structure as NonWritable.
|
||||
(This is the common translation because that's what Glslang does.)
|
||||
|
||||
Translation of uniform buffers is straightforward.
|
||||
|
||||
However, the SPIR-V Reader must support both the deprecated and the new
|
||||
styles of storage buffers.
|
||||
|
||||
Additionally:
|
||||
- a storage buffer with all NonWritable members is translated with `read`
|
||||
access mode. This becomes a part of its WGSL reference type (and hence
|
||||
corresponding pointer type).
|
||||
- a storage buffer without all NonWritable members is translated with
|
||||
an explicit `read_write` access mode. This becomes a part of its
|
||||
WGSL reference type (and hence corresponding pointer type).
|
||||
|
||||
Note that read-only vs. read-write is a property of the pointee-type in SPIR-V,
|
||||
but in WGSL it's part of the reference type (not the store type).
|
||||
|
||||
To handle this mismatch, the SPIR-V Reader has bookkeeping to map
|
||||
each pointer value (inside a function) back to through to the originating
|
||||
variable. This originating variable may be a buffer variable which then
|
||||
tells us which address space and access mode to use for a locally-defined
|
||||
pointer value.
|
||||
|
||||
Since baseline SPIR-V does not allow passing pointers to buffers into
|
||||
user-defined helper functions, we don't need to handle this buffer type
|
||||
remapping into function formal parameters.
|
||||
|
||||
## Mapping OpArrayLength
|
||||
|
||||
The OpArrayLength instruction takes a pointer to the enclosing
|
||||
structure (the pointee type of the storage buffer variable).
|
||||
|
||||
But the WGSL arrayLength builtin variable takes a pointer to the
|
||||
member inside that structure.
|
||||
|
||||
A small local adjustment is sufficient here.
|
|
@ -14,7 +14,7 @@
|
|||
* Do not use C++ exceptions
|
||||
|
||||
* Do not use C++ RTTI.
|
||||
Instead, use `tint::Castable::As<T>()` from
|
||||
Instead, use `tint::utils::Castable::As<T>()` from
|
||||
[src/castable.h](../src/castable.h)
|
||||
|
||||
* Generally, avoid `assert`. Instead, issue a [diagnostic](../src/diagnostic.h)
|
||||
|
|
|
@ -141,7 +141,7 @@ TODO(dsinclair): Nested if's
|
|||
## SPIR-V
|
||||
TODO(dsinclair): Nested if's
|
||||
|
||||
# Storage classes
|
||||
# Address spaces
|
||||
TODO(dsinclair): do ...
|
||||
|
||||
# Storage buffers
|
||||
|
@ -155,7 +155,7 @@ TODO(dsinclair): Rewrite with bools
|
|||
## MSL
|
||||
TODO(dsinclair): Rewrite with bools
|
||||
|
||||
# Input / Output storage class
|
||||
# Input / Output address spaces
|
||||
## HLSL
|
||||
TODO(dsinclair): Structs and params
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
# Copyright 2019 The Dawn Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("../scripts/dawn_overrides_with_defaults.gni")
|
||||
import("dawn_generator.gni")
|
||||
|
||||
# The list of directories in which to check for stale autogenerated files.
|
||||
# It should include the list of all directories in which we ever generated
|
||||
# files but we can't just put dawn_gen_root because there are more than
|
||||
# autogenerated sources there.
|
||||
_stale_dirs = [
|
||||
"dawn",
|
||||
"dawn/native",
|
||||
"dawn/wire",
|
||||
"mock",
|
||||
"src",
|
||||
]
|
||||
|
||||
_allowed_output_dirs_file =
|
||||
"${dawn_gen_root}/removed_stale_autogen_files.allowed_output_dirs"
|
||||
write_file(_allowed_output_dirs_file, dawn_allowed_gen_output_dirs)
|
||||
|
||||
_stale_dirs_file = "${dawn_gen_root}/removed_stale_autogen_files.stale_dirs"
|
||||
write_file(_stale_dirs_file, _stale_dirs)
|
||||
|
||||
_stamp_file = "${dawn_gen_root}/removed_stale_autogen_files.stamp"
|
||||
|
||||
# An action that removes autogenerated files that aren't in allowed directories
|
||||
# see dawn_generator.gni for more details.
|
||||
action("remove_stale_autogen_files") {
|
||||
script = "remove_files.py"
|
||||
args = [
|
||||
"--root-dir",
|
||||
rebase_path(dawn_gen_root, root_build_dir),
|
||||
"--allowed-output-dirs-file",
|
||||
rebase_path(_allowed_output_dirs_file, root_build_dir),
|
||||
"--stale-dirs-file",
|
||||
rebase_path(_stale_dirs_file, root_build_dir),
|
||||
"--stamp",
|
||||
rebase_path(_stamp_file, root_build_dir),
|
||||
]
|
||||
|
||||
# Have the "list of file" inputs as a dependency so that the action reruns
|
||||
# as soon as they change.
|
||||
inputs = [
|
||||
_allowed_output_dirs_file,
|
||||
_stale_dirs_file,
|
||||
]
|
||||
|
||||
# Output a stamp file so we don't re-run this action on every build.
|
||||
outputs = [ _stamp_file ]
|
||||
}
|
|
@ -27,6 +27,7 @@ if (NOT DAWN_JINJA2_DIR)
|
|||
endif()
|
||||
else()
|
||||
message(STATUS "Dawn: using jinja2 at ${DAWN_JINJA2_DIR}")
|
||||
message(STATUS "Dawn: using markupsafe at ${DAWN_MARKUPSAFE_DIR}")
|
||||
endif()
|
||||
|
||||
# Function to invoke a generator_lib.py generator.
|
||||
|
@ -54,6 +55,9 @@ function(DawnGenerator)
|
|||
if (DAWN_JINJA2_DIR)
|
||||
list(APPEND BASE_ARGS --jinja2-path ${DAWN_JINJA2_DIR})
|
||||
endif()
|
||||
if (DAWN_MARKUPSAFE_DIR)
|
||||
list(APPEND BASE_ARGS --markupsafe-path ${DAWN_MARKUPSAFE_DIR})
|
||||
endif()
|
||||
|
||||
# Call the generator to get the list of its dependencies.
|
||||
execute_process(
|
||||
|
|
|
@ -15,41 +15,6 @@
|
|||
import("../scripts/dawn_overrides_with_defaults.gni")
|
||||
import("generator_lib.gni")
|
||||
|
||||
# Dawn used to put autogenerated files in a lot of different places. When we
|
||||
# started to move them around, some compilation issues arised because some
|
||||
# stale include files stayed in the build directory and were picked up.
|
||||
# To counter this, now Dawn does the following:
|
||||
#
|
||||
# 1. The generated output file directory structure has to match the structure
|
||||
# of the source tree, starting at dawn_gen_root (gen/ or
|
||||
# gen/third_party/dawn depending on where we are).
|
||||
# 2. include and dawn_gen_root/include has to match the structure of
|
||||
# the source tree too.
|
||||
# 3. Dawn files must use include relative to src/ or include such as
|
||||
# "dawn/dawn.h" or "dawn/native/backend/BackendStuff.h".
|
||||
#
|
||||
# The allowed list below ensure 1). Include directory rules for Dawn ensure 3)
|
||||
# and 2) is something we need to enforce in code review.
|
||||
#
|
||||
# However GN's toolchains automatically add some include directories for us
|
||||
# which breaks 3) slightly. To avoid stale headers in for example
|
||||
# dawn_gen_root/src/dawn/dawn/ to be picked up (instead of
|
||||
# dawn_gen_root/src/dawn), we have a special action that removes files in
|
||||
# disallowed gen directories.
|
||||
|
||||
dawn_allowed_gen_output_dirs = [
|
||||
"src/dawn/",
|
||||
"src/dawn/common/",
|
||||
"src/dawn/native/",
|
||||
"src/dawn/native/opengl/",
|
||||
"src/dawn/wire/client/",
|
||||
"src/dawn/wire/server/",
|
||||
"src/dawn/wire/",
|
||||
"include/dawn/",
|
||||
"emscripten-bits/",
|
||||
"webgpu-headers/",
|
||||
]
|
||||
|
||||
# Template to help invoking Dawn code generators based on generator_lib
|
||||
#
|
||||
# dawn_generator("my_target_gen") {
|
||||
|
@ -76,20 +41,16 @@ dawn_allowed_gen_output_dirs = [
|
|||
#
|
||||
template("dawn_generator") {
|
||||
generator_lib_action(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
forward_variables_from(invoker, "*", [ "script" ])
|
||||
script = get_path_info(invoker.script, "abspath")
|
||||
|
||||
# Set arguments required to find the python libraries for the generator
|
||||
generator_lib_dir = "${dawn_root}/generator"
|
||||
generator_lib_dir = get_path_info("${dawn_root}/generator", "abspath")
|
||||
jinja2_path = dawn_jinja2_dir
|
||||
|
||||
# Force Dawn's autogenerated file structure to mirror exactly the source
|
||||
# tree but start at ${dawn_gen_root} instead of ${dawn_root}
|
||||
allowed_output_dirs = dawn_allowed_gen_output_dirs
|
||||
custom_gen_dir = dawn_gen_root
|
||||
|
||||
# Make sure that we delete stale autogenerated file in directories that are
|
||||
# no longer used by code generation to avoid include conflicts.
|
||||
deps = [ "${dawn_root}/generator:remove_stale_autogen_files" ]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,3 +80,25 @@ template("dawn_json_generator") {
|
|||
forward_variables_from(invoker, "*", [ "target" ])
|
||||
}
|
||||
}
|
||||
|
||||
template("dawn_json_lpm_generator") {
|
||||
dawn_generator(target_name) {
|
||||
script = "${dawn_root}/generator/dawn_json_generator.py"
|
||||
|
||||
# The base arguments for the generator: from this dawn.json, generate this
|
||||
# target using templates in this directory.
|
||||
args = [
|
||||
"--dawn-json",
|
||||
rebase_path("${dawn_root}/dawn.json", root_build_dir),
|
||||
"--wire-json",
|
||||
rebase_path("${dawn_root}/dawn_wire.json", root_build_dir),
|
||||
"--lpm-json",
|
||||
rebase_path("${dawn_root}/src/dawn/fuzzers/lpmfuzz/dawn_lpm.json",
|
||||
root_build_dir),
|
||||
"--targets",
|
||||
invoker.target,
|
||||
]
|
||||
|
||||
forward_variables_from(invoker, "*", [ "target" ])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@ class RecordMember:
|
|||
self.optional = optional
|
||||
self.is_return_value = is_return_value
|
||||
self.handle_type = None
|
||||
self.id_type = None
|
||||
self.default_value = default_value
|
||||
self.skip_serialize = skip_serialize
|
||||
|
||||
|
@ -188,9 +189,13 @@ class RecordMember:
|
|||
assert self.type.dict_name == "ObjectHandle"
|
||||
self.handle_type = handle_type
|
||||
|
||||
def set_id_type(self, id_type):
|
||||
assert self.type.dict_name == "ObjectId"
|
||||
self.id_type = id_type
|
||||
|
||||
Method = namedtuple('Method',
|
||||
['name', 'return_type', 'arguments', 'json_data'])
|
||||
|
||||
Method = namedtuple(
|
||||
'Method', ['name', 'return_type', 'arguments', 'autolock', 'json_data'])
|
||||
|
||||
|
||||
class ObjectType(Type):
|
||||
|
@ -308,6 +313,9 @@ def linked_record_members(json_data, types):
|
|||
handle_type = m.get('handle_type')
|
||||
if handle_type:
|
||||
member.set_handle_type(types[handle_type])
|
||||
id_type = m.get('id_type')
|
||||
if id_type:
|
||||
member.set_id_type(types[id_type])
|
||||
members.append(member)
|
||||
members_by_name[member.name.canonical_case()] = member
|
||||
|
||||
|
@ -331,17 +339,34 @@ def linked_record_members(json_data, types):
|
|||
return members
|
||||
|
||||
|
||||
def mark_lengths_non_serializable_lpm(record_members):
|
||||
# Remove member length values from command metadata,
|
||||
# these are set to the length of the protobuf array.
|
||||
for record_member in record_members:
|
||||
lengths = set()
|
||||
for member in record_member.members:
|
||||
lengths.add(member.length)
|
||||
|
||||
for member in record_member.members:
|
||||
if member in lengths:
|
||||
member.skip_serialize = True
|
||||
|
||||
############################################################
|
||||
# PARSE
|
||||
############################################################
|
||||
|
||||
|
||||
def link_object(obj, types):
|
||||
# Disable method's autolock if obj's "no autolock" = True
|
||||
obj_scoped_autolock_enabled = not obj.json_data.get('no autolock', False)
|
||||
|
||||
def make_method(json_data):
|
||||
arguments = linked_record_members(json_data.get('args', []), types)
|
||||
autolock_enabled = obj_scoped_autolock_enabled and not json_data.get(
|
||||
'no autolock', False)
|
||||
return Method(Name(json_data['name']),
|
||||
types[json_data.get('returns',
|
||||
'void')], arguments, json_data)
|
||||
types[json_data.get('returns', 'void')], arguments,
|
||||
autolock_enabled, json_data)
|
||||
|
||||
obj.methods = [make_method(m) for m in obj.json_data.get('methods', [])]
|
||||
obj.methods.sort(key=lambda method: method.name.canonical_case())
|
||||
|
@ -371,7 +396,6 @@ def link_function(function, types):
|
|||
function.arguments = linked_record_members(function.json_data['args'],
|
||||
types)
|
||||
|
||||
|
||||
# Sort structures so that if struct A has struct B as a member, then B is
|
||||
# listed before A.
|
||||
#
|
||||
|
@ -566,6 +590,103 @@ def compute_wire_params(api_params, wire_json):
|
|||
|
||||
return wire_params
|
||||
|
||||
############################################################
|
||||
# DAWN LPM FUZZ STUFF
|
||||
############################################################
|
||||
|
||||
|
||||
def compute_lpm_params(api_and_wire_params, lpm_json):
|
||||
# Start with all commands in dawn.json and dawn_wire.json
|
||||
lpm_params = api_and_wire_params.copy()
|
||||
|
||||
# Commands that are built through codegen
|
||||
generated_commands = []
|
||||
|
||||
# All commands, including hand written commands that we can't generate
|
||||
# through codegen
|
||||
all_commands = []
|
||||
|
||||
# Remove blocklisted commands from protobuf generation params
|
||||
blocklisted_cmds_proto = lpm_json.get('blocklisted_cmds')
|
||||
custom_cmds_proto = lpm_json.get('custom_cmds')
|
||||
for command in lpm_params['cmd_records']['command']:
|
||||
blocklisted = command.name.get() in blocklisted_cmds_proto
|
||||
custom = command.name.get() in custom_cmds_proto
|
||||
|
||||
if blocklisted:
|
||||
continue
|
||||
|
||||
if not custom:
|
||||
generated_commands.append(command)
|
||||
all_commands.append(command)
|
||||
|
||||
# Set all fields that are marked as the "length" of another field to
|
||||
# skip_serialize. The values passed by libprotobuf-mutator will cause
|
||||
# an instant crash during serialization if these don't match the length
|
||||
# of the data they are passing. These values aren't used in
|
||||
# deserialization.
|
||||
mark_lengths_non_serializable_lpm(
|
||||
api_and_wire_params['cmd_records']['command'])
|
||||
mark_lengths_non_serializable_lpm(
|
||||
api_and_wire_params['by_category']['structure'])
|
||||
|
||||
lpm_params['cmd_records'] = {
|
||||
'proto_generated_commands': generated_commands,
|
||||
'proto_all_commands': all_commands,
|
||||
'cpp_generated_commands': generated_commands,
|
||||
'lpm_info': lpm_json.get("lpm_info")
|
||||
}
|
||||
|
||||
return lpm_params
|
||||
|
||||
|
||||
def as_protobufTypeLPM(member):
|
||||
assert 'type' in member.json_data
|
||||
|
||||
if member.type.name.native:
|
||||
typ = member.json_data['type']
|
||||
cpp_to_protobuf_type = {
|
||||
"bool": "bool",
|
||||
"float": "float",
|
||||
"double": "double",
|
||||
"int8_t": "int32",
|
||||
"int16_t": "int32",
|
||||
"int32_t": "int32",
|
||||
"int64_t": "int64",
|
||||
"uint8_t": "uint32",
|
||||
"uint16_t": "uint32",
|
||||
"uint32_t": "uint32",
|
||||
"uint64_t": "uint64",
|
||||
}
|
||||
|
||||
assert typ in cpp_to_protobuf_type
|
||||
|
||||
return cpp_to_protobuf_type[typ]
|
||||
|
||||
return member.type.name.CamelCase()
|
||||
|
||||
|
||||
# Helper that generates names for protobuf grammars from contents
|
||||
# of dawn*.json like files. example: membera
|
||||
def as_protobufNameLPM(*names):
|
||||
# `descriptor` is a reserved keyword in lib-protobuf-mutator
|
||||
if (names[0].concatcase() == "descriptor"):
|
||||
return "desc"
|
||||
return as_varName(*names)
|
||||
|
||||
|
||||
# Helper to generate member accesses within C++ of protobuf objects
|
||||
# example: cmd.membera().memberb()
|
||||
def as_protobufMemberNameLPM(*names):
|
||||
# `descriptor` is a reserved keyword in lib-protobuf-mutator
|
||||
if (names[0].concatcase() == "descriptor"):
|
||||
return "desc"
|
||||
return ''.join([name.concatcase().lower() for name in names])
|
||||
|
||||
|
||||
def unreachable_code():
|
||||
assert False
|
||||
|
||||
|
||||
#############################################################
|
||||
# Generator
|
||||
|
@ -698,16 +819,10 @@ def as_formatType(typ):
|
|||
|
||||
def c_methods(params, typ):
|
||||
return typ.methods + [
|
||||
x for x in [
|
||||
Method(Name('reference'), params['types']['void'], [],
|
||||
{'tags': ['dawn', 'emscripten']}),
|
||||
Method(Name('release'), params['types']['void'], [],
|
||||
{'tags': ['dawn', 'emscripten']}),
|
||||
] if item_is_enabled(params['enabled_tags'], x.json_data)
|
||||
and not item_is_disabled(params['disabled_tags'], x.json_data)
|
||||
Method(Name('reference'), params['types']['void'], [], False, {}),
|
||||
Method(Name('release'), params['types']['void'], [], False, {}),
|
||||
]
|
||||
|
||||
|
||||
def get_c_methods_sorted_by_name(api_params):
|
||||
unsorted = [(as_MethodSuffix(typ.name, method.name), typ, method) \
|
||||
for typ in api_params['by_category']['object'] \
|
||||
|
@ -777,7 +892,7 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
def add_commandline_arguments(self, parser):
|
||||
allowed_targets = [
|
||||
'dawn_headers', 'cpp_headers', 'cpp', 'proc', 'mock_api', 'wire',
|
||||
'native_utils'
|
||||
'native_utils', 'dawn_lpmfuzz_cpp', 'dawn_lpmfuzz_proto'
|
||||
]
|
||||
|
||||
parser.add_argument('--dawn-json',
|
||||
|
@ -788,6 +903,10 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
default=None,
|
||||
type=str,
|
||||
help='The DAWN WIRE JSON definition to use.')
|
||||
parser.add_argument("--lpm-json",
|
||||
default=None,
|
||||
type=str,
|
||||
help='The DAWN LPM FUZZER definitions to use.')
|
||||
parser.add_argument(
|
||||
'--targets',
|
||||
required=True,
|
||||
|
@ -795,6 +914,7 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
help=
|
||||
'Comma-separated subset of targets to output. Available targets: '
|
||||
+ ', '.join(allowed_targets))
|
||||
|
||||
def get_file_renders(self, args):
|
||||
with open(args.dawn_json) as f:
|
||||
loaded_json = json.loads(f.read())
|
||||
|
@ -806,6 +926,11 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
with open(args.wire_json) as f:
|
||||
wire_json = json.loads(f.read())
|
||||
|
||||
lpm_json = None
|
||||
if args.lpm_json:
|
||||
with open(args.lpm_json) as f:
|
||||
lpm_json = json.loads(f.read())
|
||||
|
||||
renders = []
|
||||
|
||||
params_dawn = parse_json(loaded_json,
|
||||
|
@ -834,6 +959,11 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
'include/dawn/' + api + '_cpp_print.h',
|
||||
[RENDER_PARAMS_BASE, params_dawn]))
|
||||
|
||||
renders.append(
|
||||
FileRender('api_cpp_chained_struct.h',
|
||||
'include/dawn/' + api + '_cpp_chained_struct.h',
|
||||
[RENDER_PARAMS_BASE, params_dawn]))
|
||||
|
||||
if 'proc' in targets:
|
||||
renders.append(
|
||||
FileRender('dawn_proc.c', 'src/dawn/' + prefix + '_proc.c',
|
||||
|
@ -1025,12 +1155,76 @@ class MultiGeneratorFromDawnJSON(Generator):
|
|||
'src/dawn/wire/server/ServerPrototypes_autogen.inc',
|
||||
wire_params))
|
||||
|
||||
if 'dawn_lpmfuzz_proto' in targets:
|
||||
params_dawn_wire = parse_json(loaded_json,
|
||||
enabled_tags=['dawn', 'deprecated'],
|
||||
disabled_tags=['native'])
|
||||
api_and_wire_params = compute_wire_params(params_dawn_wire,
|
||||
wire_json)
|
||||
|
||||
fuzzer_params = compute_lpm_params(api_and_wire_params, lpm_json)
|
||||
|
||||
lpm_params = [
|
||||
RENDER_PARAMS_BASE, params_dawn_wire, {
|
||||
'as_protobufTypeLPM': as_protobufTypeLPM,
|
||||
'as_protobufNameLPM': as_protobufNameLPM,
|
||||
'unreachable': unreachable_code
|
||||
}, api_and_wire_params, fuzzer_params
|
||||
]
|
||||
|
||||
renders.append(
|
||||
FileRender('dawn/fuzzers/lpmfuzz/dawn_lpm.proto',
|
||||
'src/dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.proto',
|
||||
lpm_params))
|
||||
|
||||
renders.append(
|
||||
FileRender(
|
||||
'dawn/fuzzers/lpmfuzz/dawn_object_types_lpm.proto',
|
||||
'src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto',
|
||||
lpm_params))
|
||||
|
||||
if 'dawn_lpmfuzz_cpp' in targets:
|
||||
params_dawn_wire = parse_json(loaded_json,
|
||||
enabled_tags=['dawn', 'deprecated'],
|
||||
disabled_tags=['native'])
|
||||
api_and_wire_params = compute_wire_params(params_dawn_wire,
|
||||
wire_json)
|
||||
|
||||
fuzzer_params = compute_lpm_params(api_and_wire_params, lpm_json)
|
||||
|
||||
lpm_params = [
|
||||
RENDER_PARAMS_BASE, params_dawn_wire, {
|
||||
'as_protobufMemberName': as_protobufMemberNameLPM,
|
||||
'unreachable_code': unreachable_code
|
||||
}, api_and_wire_params, fuzzer_params
|
||||
]
|
||||
|
||||
renders.append(
|
||||
FileRender(
|
||||
'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp',
|
||||
'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.cpp',
|
||||
lpm_params))
|
||||
|
||||
renders.append(
|
||||
FileRender(
|
||||
'dawn/fuzzers/lpmfuzz/DawnLPMSerializer.h',
|
||||
'src/dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h',
|
||||
lpm_params))
|
||||
|
||||
renders.append(
|
||||
FileRender(
|
||||
'dawn/fuzzers/lpmfuzz/DawnLPMConstants.h',
|
||||
'src/dawn/fuzzers/lpmfuzz/DawnLPMConstants_autogen.h',
|
||||
lpm_params))
|
||||
|
||||
return renders
|
||||
|
||||
def get_dependencies(self, args):
|
||||
deps = [os.path.abspath(args.dawn_json)]
|
||||
if args.wire_json != None:
|
||||
deps += [os.path.abspath(args.wire_json)]
|
||||
if args.lpm_json != None:
|
||||
deps += [os.path.abspath(args.lpm_json)]
|
||||
return deps
|
||||
|
||||
|
||||
|
|
|
@ -37,11 +37,6 @@
|
|||
#
|
||||
# jinja2_path: Optional Jinja2 installation path.
|
||||
#
|
||||
# allowed_output_dirs: Optional list of directories that are the only
|
||||
# directories in which files of `outputs` are allowed to be (and not
|
||||
# in children directories). Generation will fail if an output isn't
|
||||
# in a directory in the list.
|
||||
#
|
||||
# root_dir: Optional root source dir for Python dependencies
|
||||
# computation. Defaults to "${generator_lib_dir}/..". Any dependency
|
||||
# outside of this directory is considered a system file and will be
|
||||
|
@ -62,7 +57,7 @@ template("generator_lib_action") {
|
|||
}
|
||||
_generator_args += [
|
||||
"--template-dir",
|
||||
rebase_path(_template_dir),
|
||||
rebase_path(_template_dir, root_build_dir),
|
||||
]
|
||||
|
||||
if (defined(invoker.root_dir)) {
|
||||
|
@ -75,7 +70,7 @@ template("generator_lib_action") {
|
|||
if (defined(invoker.jinja2_path)) {
|
||||
_generator_args += [
|
||||
"--jinja2-path",
|
||||
rebase_path(invoker.jinja2_path),
|
||||
rebase_path(invoker.jinja2_path, root_build_dir),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -118,19 +113,6 @@ template("generator_lib_action") {
|
|||
rebase_path(_expected_outputs_file, root_build_dir),
|
||||
]
|
||||
|
||||
# Check that all of the outputs are in a directory that's allowed. This is
|
||||
# useful to keep the list of directories in sink with other parts of the
|
||||
# build.
|
||||
if (defined(invoker.allowed_output_dirs)) {
|
||||
_allowed_output_dirs_file = "${_gen_dir}/${target_name}.allowed_output_dirs"
|
||||
write_file(_allowed_output_dirs_file, invoker.allowed_output_dirs)
|
||||
|
||||
_generator_args += [
|
||||
"--allowed-output-dirs-file",
|
||||
rebase_path(_allowed_output_dirs_file, root_build_dir),
|
||||
]
|
||||
}
|
||||
|
||||
# The code generator invocation that will write the JSON tarball, check the
|
||||
# outputs are what's expected and write a depfile for Ninja.
|
||||
action(_json_tarball_target) {
|
||||
|
|
|
@ -90,6 +90,16 @@ except ValueError:
|
|||
# --jinja2-path isn't passed, ignore the exception and just import Jinja2
|
||||
# assuming it already is in the Python PATH.
|
||||
pass
|
||||
kMarkupSafePath = '--markupsafe-path'
|
||||
try:
|
||||
markupsafe_path_argv_index = sys.argv.index(kMarkupSafePath)
|
||||
# Add parent path for the import to succeed.
|
||||
path = os.path.join(sys.argv[markupsafe_path_argv_index + 1], os.pardir)
|
||||
sys.path.insert(1, path)
|
||||
except ValueError:
|
||||
# --markupsafe-path isn't passed, ignore the exception and just import
|
||||
# assuming it already is in the Python PATH.
|
||||
pass
|
||||
|
||||
import jinja2
|
||||
|
||||
|
@ -236,6 +246,11 @@ def run_generator(generator):
|
|||
default=None,
|
||||
type=str,
|
||||
help='Additional python path to set before loading Jinja2')
|
||||
parser.add_argument(
|
||||
kMarkupSafePath,
|
||||
default=None,
|
||||
type=str,
|
||||
help='Additional python path to set before loading MarkupSafe')
|
||||
parser.add_argument(
|
||||
'--output-json-tarball',
|
||||
default=None,
|
||||
|
@ -258,12 +273,6 @@ def run_generator(generator):
|
|||
type=str,
|
||||
help=('Optional source root directory for Python dependency '
|
||||
'computations'))
|
||||
parser.add_argument(
|
||||
'--allowed-output-dirs-file',
|
||||
default=None,
|
||||
type=str,
|
||||
help=("File containing a list of allowed directories where files "
|
||||
"can be output."))
|
||||
parser.add_argument(
|
||||
'--print-cmake-dependencies',
|
||||
default=False,
|
||||
|
@ -326,32 +335,6 @@ def run_generator(generator):
|
|||
|
||||
outputs = _do_renders(renders, args.template_dir)
|
||||
|
||||
# The caller wants to assert that the outputs are only in specific
|
||||
# directories.
|
||||
if args.allowed_output_dirs_file != None:
|
||||
with open(args.allowed_output_dirs_file) as f:
|
||||
allowed_dirs = set([line.strip() for line in f.readlines()])
|
||||
|
||||
for directory in allowed_dirs:
|
||||
if not directory.endswith('/'):
|
||||
print('Allowed directory entry "{}" doesn\'t '
|
||||
'end with /'.format(directory))
|
||||
return 1
|
||||
|
||||
def check_in_subdirectory(path, directory):
|
||||
return path.startswith(
|
||||
directory) and not '/' in path[len(directory):]
|
||||
|
||||
for render in renders:
|
||||
if not any(
|
||||
check_in_subdirectory(render.output, directory)
|
||||
for directory in allowed_dirs):
|
||||
print('Output file "{}" is not in the allowed directory '
|
||||
'list below:'.format(render.output))
|
||||
for directory in sorted(allowed_dirs):
|
||||
print(' "{}"'.format(directory))
|
||||
return 1
|
||||
|
||||
# Output the JSON tarball
|
||||
if args.output_json_tarball != None:
|
||||
json_root = {}
|
||||
|
@ -367,8 +350,7 @@ def run_generator(generator):
|
|||
output_path = os.path.join(args.output_dir, output.name)
|
||||
|
||||
directory = os.path.dirname(output_path)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
|
||||
with open(output_path, 'w') as outfile:
|
||||
outfile.write(output.content)
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright 2019 The Dawn Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import argparse, glob, os, sys
|
||||
|
||||
|
||||
def check_in_subdirectory(path, directory):
|
||||
return path.startswith(directory) and not '/' in path[len(directory):]
|
||||
|
||||
|
||||
def check_is_allowed(path, allowed_dirs):
|
||||
return any(
|
||||
check_in_subdirectory(path, directory) for directory in allowed_dirs)
|
||||
|
||||
|
||||
def get_all_files_in_dir(find_directory):
|
||||
result = []
|
||||
for (directory, _, files) in os.walk(find_directory):
|
||||
result += [os.path.join(directory, filename) for filename in files]
|
||||
return result
|
||||
|
||||
|
||||
def run():
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Removes stale autogenerated files from gen/ directories.")
|
||||
parser.add_argument(
|
||||
'--root-dir',
|
||||
type=str,
|
||||
help='The root directory, all other paths in files are relative to it.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--allowed-output-dirs-file',
|
||||
type=str,
|
||||
help='The file containing a list of allowed directories')
|
||||
parser.add_argument(
|
||||
'--stale-dirs-file',
|
||||
type=str,
|
||||
help=
|
||||
'The file containing a list of directories to check for stale files')
|
||||
parser.add_argument('--stamp',
|
||||
type=str,
|
||||
help='A stamp written once this script completes')
|
||||
args = parser.parse_args()
|
||||
|
||||
root_dir = args.root_dir
|
||||
stamp_file = args.stamp
|
||||
|
||||
# Load the list of allowed and stale directories
|
||||
with open(args.allowed_output_dirs_file) as f:
|
||||
allowed_dirs = set(
|
||||
[os.path.join(root_dir, line.strip()) for line in f.readlines()])
|
||||
|
||||
for directory in allowed_dirs:
|
||||
if not directory.endswith('/'):
|
||||
print('Allowed directory entry "{}" doesn\'t end with /'.format(
|
||||
directory))
|
||||
return 1
|
||||
|
||||
with open(args.stale_dirs_file) as f:
|
||||
stale_dirs = set([line.strip() for line in f.readlines()])
|
||||
|
||||
# Remove all files in stale dirs that aren't in the allowed dirs.
|
||||
for stale_dir in stale_dirs:
|
||||
stale_dir = os.path.join(root_dir, stale_dir)
|
||||
|
||||
for candidate in get_all_files_in_dir(stale_dir):
|
||||
if not check_is_allowed(candidate, allowed_dirs):
|
||||
os.remove(candidate)
|
||||
|
||||
# Finished! Write the stamp file so ninja knows to not run this again.
|
||||
with open(stamp_file, "w") as f:
|
||||
f.write("")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run())
|
|
@ -32,37 +32,58 @@
|
|||
#ifndef {{metadata.api.upper()}}_H_
|
||||
#define {{metadata.api.upper()}}_H_
|
||||
|
||||
{% set c_prefix = metadata.c_prefix %}
|
||||
#if defined({{c_prefix}}_SHARED_LIBRARY)
|
||||
{% set API = metadata.c_prefix %}
|
||||
#if defined({{API}}_SHARED_LIBRARY)
|
||||
# if defined(_WIN32)
|
||||
# if defined({{c_prefix}}_IMPLEMENTATION)
|
||||
# define {{c_prefix}}_EXPORT __declspec(dllexport)
|
||||
# if defined({{API}}_IMPLEMENTATION)
|
||||
# define {{API}}_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define {{c_prefix}}_EXPORT __declspec(dllimport)
|
||||
# define {{API}}_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else // defined(_WIN32)
|
||||
# if defined({{c_prefix}}_IMPLEMENTATION)
|
||||
# define {{c_prefix}}_EXPORT __attribute__((visibility("default")))
|
||||
# if defined({{API}}_IMPLEMENTATION)
|
||||
# define {{API}}_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
# define {{c_prefix}}_EXPORT
|
||||
# define {{API}}_EXPORT
|
||||
# endif
|
||||
# endif // defined(_WIN32)
|
||||
#else // defined({{c_prefix}}_SHARED_LIBRARY)
|
||||
# define {{c_prefix}}_EXPORT
|
||||
#endif // defined({{c_prefix}}_SHARED_LIBRARY)
|
||||
#else // defined({{API}}_SHARED_LIBRARY)
|
||||
# define {{API}}_EXPORT
|
||||
#endif // defined({{API}}_SHARED_LIBRARY)
|
||||
|
||||
#if !defined({{API}}_OBJECT_ATTRIBUTE)
|
||||
#define {{API}}_OBJECT_ATTRIBUTE
|
||||
#endif
|
||||
#if !defined({{API}}_ENUM_ATTRIBUTE)
|
||||
#define {{API}}_ENUM_ATTRIBUTE
|
||||
#endif
|
||||
#if !defined({{API}}_STRUCTURE_ATTRIBUTE)
|
||||
#define {{API}}_STRUCTURE_ATTRIBUTE
|
||||
#endif
|
||||
#if !defined({{API}}_FUNCTION_ATTRIBUTE)
|
||||
#define {{API}}_FUNCTION_ATTRIBUTE
|
||||
#endif
|
||||
#if !defined({{API}}_NULLABLE)
|
||||
#define {{API}}_NULLABLE
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
{% for constant in by_category["constant"] %}
|
||||
#define {{c_prefix}}_{{constant.name.SNAKE_CASE()}} {{constant.value}}
|
||||
#define {{API}}_{{constant.name.SNAKE_CASE()}} {{constant.value}}
|
||||
{% endfor %}
|
||||
|
||||
typedef uint32_t {{c_prefix}}Flags;
|
||||
typedef uint32_t {{API}}Flags;
|
||||
|
||||
{% for type in by_category["object"] %}
|
||||
typedef struct {{as_cType(type.name)}}Impl* {{as_cType(type.name)}};
|
||||
typedef struct {{as_cType(type.name)}}Impl* {{as_cType(type.name)}} {{API}}_OBJECT_ATTRIBUTE;
|
||||
{% endfor %}
|
||||
|
||||
// Structure forward declarations
|
||||
{% for type in by_category["structure"] %}
|
||||
struct {{as_cType(type.name)}};
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["enum"] + by_category["bitmask"] %}
|
||||
|
@ -71,22 +92,34 @@ typedef uint32_t {{c_prefix}}Flags;
|
|||
{{as_cEnum(type.name, value.name)}} = 0x{{format(value.value, "08X")}},
|
||||
{% endfor %}
|
||||
{{as_cEnum(type.name, Name("force32"))}} = 0x7FFFFFFF
|
||||
} {{as_cType(type.name)}};
|
||||
} {{as_cType(type.name)}} {{API}}_ENUM_ATTRIBUTE;
|
||||
{% if type.category == "bitmask" %}
|
||||
typedef {{c_prefix}}Flags {{as_cType(type.name)}}Flags;
|
||||
typedef {{API}}Flags {{as_cType(type.name)}}Flags {{API}}_ENUM_ATTRIBUTE;
|
||||
{% endif %}
|
||||
|
||||
{% endfor -%}
|
||||
{% for type in by_category["function pointer"] %}
|
||||
typedef {{as_cType(type.return_type.name)}} (*{{as_cType(type.name)}})(
|
||||
{%- if type.arguments == [] -%}
|
||||
void
|
||||
{%- else -%}
|
||||
{%- for arg in type.arguments -%}
|
||||
{% if not loop.first %}, {% endif %}
|
||||
{% if arg.type.category == "structure" %}struct {% endif %}{{as_annotated_cType(arg)}}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
) {{API}}_FUNCTION_ATTRIBUTE;
|
||||
{% endfor %}
|
||||
|
||||
typedef struct {{c_prefix}}ChainedStruct {
|
||||
struct {{c_prefix}}ChainedStruct const * next;
|
||||
{{c_prefix}}SType sType;
|
||||
} {{c_prefix}}ChainedStruct;
|
||||
typedef struct {{API}}ChainedStruct {
|
||||
struct {{API}}ChainedStruct const * next;
|
||||
{{API}}SType sType;
|
||||
} {{API}}ChainedStruct {{API}}_STRUCTURE_ATTRIBUTE;
|
||||
|
||||
typedef struct {{c_prefix}}ChainedStructOut {
|
||||
struct {{c_prefix}}ChainedStructOut * next;
|
||||
{{c_prefix}}SType sType;
|
||||
} {{c_prefix}}ChainedStructOut;
|
||||
typedef struct {{API}}ChainedStructOut {
|
||||
struct {{API}}ChainedStructOut * next;
|
||||
{{API}}SType sType;
|
||||
} {{API}}ChainedStructOut {{API}}_STRUCTURE_ATTRIBUTE;
|
||||
|
||||
{% for type in by_category["structure"] %}
|
||||
{% for root in type.chain_roots %}
|
||||
|
@ -96,16 +129,19 @@ typedef struct {{c_prefix}}ChainedStructOut {
|
|||
{% set Out = "Out" if type.output else "" %}
|
||||
{% set const = "const " if not type.output else "" %}
|
||||
{% if type.extensible %}
|
||||
{{c_prefix}}ChainedStruct{{Out}} {{const}}* nextInChain;
|
||||
{{API}}ChainedStruct{{Out}} {{const}}* nextInChain;
|
||||
{% endif %}
|
||||
{% if type.chained %}
|
||||
{{c_prefix}}ChainedStruct{{Out}} chain;
|
||||
{{API}}ChainedStruct{{Out}} chain;
|
||||
{% endif %}
|
||||
{% for member in type.members %}
|
||||
{{as_annotated_cType(member)}};
|
||||
{%- if member.optional %} // nullable{% endif %}{{""}}
|
||||
{% if member.optional %}
|
||||
{{API}}_NULLABLE {{as_annotated_cType(member)}};
|
||||
{% else %}
|
||||
{{as_annotated_cType(member)}};
|
||||
{% endif-%}
|
||||
{% endfor %}
|
||||
} {{as_cType(type.name)}};
|
||||
} {{as_cType(type.name)}} {{API}}_STRUCTURE_ATTRIBUTE;
|
||||
|
||||
{% endfor %}
|
||||
{% for typeDef in by_category["typedef"] %}
|
||||
|
@ -118,26 +154,14 @@ typedef struct {{c_prefix}}ChainedStructOut {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
{% for type in by_category["function pointer"] %}
|
||||
typedef {{as_cType(type.return_type.name)}} (*{{as_cType(type.name)}})(
|
||||
{%- if type.arguments == [] -%}
|
||||
void
|
||||
{%- else -%}
|
||||
{%- for arg in type.arguments -%}
|
||||
{% if not loop.first %}, {% endif %}{{as_annotated_cType(arg)}}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
);
|
||||
{% endfor %}
|
||||
|
||||
#if !defined({{c_prefix}}_SKIP_PROCS)
|
||||
#if !defined({{API}}_SKIP_PROCS)
|
||||
|
||||
{% for function in by_category["function"] %}
|
||||
typedef {{as_cType(function.return_type.name)}} (*{{as_cProc(None, function.name)}})(
|
||||
{%- for arg in function.arguments -%}
|
||||
{% if not loop.first %}, {% endif %}{{as_annotated_cType(arg)}}
|
||||
{%- endfor -%}
|
||||
);
|
||||
) {{API}}_FUNCTION_ATTRIBUTE;
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["object"] if len(c_methods(type)) > 0 %}
|
||||
|
@ -146,39 +170,41 @@ extern "C" {
|
|||
typedef {{as_cType(method.return_type.name)}} (*{{as_cProc(type.name, method.name)}})(
|
||||
{{-as_cType(type.name)}} {{as_varName(type.name)}}
|
||||
{%- for arg in method.arguments -%}
|
||||
, {{as_annotated_cType(arg)}}
|
||||
{%- if arg.optional %} /* nullable */{% endif %}
|
||||
,{{" "}}
|
||||
{%- if arg.optional %}{{API}}_NULLABLE {% endif -%}
|
||||
{{as_annotated_cType(arg)}}
|
||||
{%- endfor -%}
|
||||
);
|
||||
) {{API}}_FUNCTION_ATTRIBUTE;
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
#endif // !defined({{c_prefix}}_SKIP_PROCS)
|
||||
#endif // !defined({{API}}_SKIP_PROCS)
|
||||
|
||||
#if !defined({{c_prefix}}_SKIP_DECLARATIONS)
|
||||
#if !defined({{API}}_SKIP_DECLARATIONS)
|
||||
|
||||
{% for function in by_category["function"] %}
|
||||
{{c_prefix}}_EXPORT {{as_cType(function.return_type.name)}} {{as_cMethod(None, function.name)}}(
|
||||
{{API}}_EXPORT {{as_cType(function.return_type.name)}} {{as_cMethod(None, function.name)}}(
|
||||
{%- for arg in function.arguments -%}
|
||||
{% if not loop.first %}, {% endif %}{{as_annotated_cType(arg)}}
|
||||
{%- endfor -%}
|
||||
);
|
||||
) {{API}}_FUNCTION_ATTRIBUTE;
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["object"] if len(c_methods(type)) > 0 %}
|
||||
// Methods of {{type.name.CamelCase()}}
|
||||
{% for method in c_methods(type) %}
|
||||
{{c_prefix}}_EXPORT {{as_cType(method.return_type.name)}} {{as_cMethod(type.name, method.name)}}(
|
||||
{{API}}_EXPORT {{as_cType(method.return_type.name)}} {{as_cMethod(type.name, method.name)}}(
|
||||
{{-as_cType(type.name)}} {{as_varName(type.name)}}
|
||||
{%- for arg in method.arguments -%}
|
||||
, {{as_annotated_cType(arg)}}
|
||||
{%- if arg.optional %} /* nullable */{% endif %}
|
||||
,{{" "}}
|
||||
{%- if arg.optional %}{{API}}_NULLABLE {% endif -%}
|
||||
{{as_annotated_cType(arg)}}
|
||||
{%- endfor -%}
|
||||
);
|
||||
) {{API}}_FUNCTION_ATTRIBUTE;
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
#endif // !defined({{c_prefix}}_SKIP_DECLARATIONS)
|
||||
#endif // !defined({{API}}_SKIP_DECLARATIONS)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//* limitations under the License.
|
||||
{% set API = metadata.api.upper() %}
|
||||
{% set api = API.lower() %}
|
||||
{% if 'dawn' not in enabled_tags %}
|
||||
{% if 'dawn' in enabled_tags %}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}."
|
||||
#endif
|
||||
|
@ -22,17 +22,14 @@
|
|||
#define {{API}}_CPP_H_
|
||||
|
||||
#include "dawn/{{api}}.h"
|
||||
#include "dawn/{{api}}_cpp_chained_struct.h"
|
||||
#include "dawn/EnumClassBitmasks.h"
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace {{metadata.namespace}} {
|
||||
|
||||
namespace detail {
|
||||
constexpr size_t ConstexprMax(size_t a, size_t b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
{% set c_prefix = metadata.c_prefix %}
|
||||
{% for constant in by_category["constant"] %}
|
||||
{% set type = as_cppType(constant.type.name) %}
|
||||
|
@ -136,11 +133,17 @@ namespace {{metadata.namespace}} {
|
|||
CType Get() const {
|
||||
return mHandle;
|
||||
}
|
||||
// TODO(dawn:1639) Deprecate Release after uses have been removed.
|
||||
CType Release() {
|
||||
CType result = mHandle;
|
||||
mHandle = 0;
|
||||
return result;
|
||||
}
|
||||
CType MoveToCHandle() {
|
||||
CType result = mHandle;
|
||||
mHandle = 0;
|
||||
return result;
|
||||
}
|
||||
static Derived Acquire(CType handle) {
|
||||
Derived result;
|
||||
result.mHandle = handle;
|
||||
|
@ -212,16 +215,6 @@ namespace {{metadata.namespace}} {
|
|||
);
|
||||
{% endfor %}
|
||||
|
||||
struct ChainedStruct {
|
||||
ChainedStruct const * nextInChain = nullptr;
|
||||
SType sType = SType::Invalid;
|
||||
};
|
||||
|
||||
struct ChainedStructOut {
|
||||
ChainedStruct * nextInChain = nullptr;
|
||||
SType sType = SType::Invalid;
|
||||
};
|
||||
|
||||
{% for type in by_category["structure"] %}
|
||||
{% set Out = "Out" if type.output else "" %}
|
||||
{% set const = "const" if not type.output else "" %}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
//* Copyright 2023 The Dawn Authors
|
||||
//*
|
||||
//* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
//* you may not use this file except in compliance with the License.
|
||||
//* You may obtain a copy of the License at
|
||||
//*
|
||||
//* http://www.apache.org/licenses/LICENSE-2.0
|
||||
//*
|
||||
//* Unless required by applicable law or agreed to in writing, software
|
||||
//* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
//* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//* See the License for the specific language governing permissions and
|
||||
//* limitations under the License.
|
||||
{% set API = metadata.api.upper() %}
|
||||
{% if 'dawn' in enabled_tags %}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}."
|
||||
#endif
|
||||
{% endif %}
|
||||
#ifndef {{API}}_CPP_CHAINED_STRUCT_H_
|
||||
#define {{API}}_CPP_CHAINED_STRUCT_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
// This header file declares the ChainedStruct structures separately from the {{metadata.api}}
|
||||
// headers so that dependencies can directly extend structures without including the larger header
|
||||
// which exposes capabilities that may require correctly set proc tables.
|
||||
namespace {{metadata.namespace}} {
|
||||
|
||||
namespace detail {
|
||||
constexpr size_t ConstexprMax(size_t a, size_t b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
enum class SType : uint32_t;
|
||||
|
||||
struct ChainedStruct {
|
||||
ChainedStruct const * nextInChain = nullptr;
|
||||
SType sType = SType(0u);
|
||||
};
|
||||
|
||||
struct ChainedStructOut {
|
||||
ChainedStructOut * nextInChain = nullptr;
|
||||
SType sType = SType(0u);
|
||||
};
|
||||
|
||||
} // namespace {{metadata.namespace}}}
|
||||
|
||||
#endif // {{API}}_CPP_CHAINED_STRUCT_H_
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "dawn/common/Assert.h"
|
||||
|
||||
namespace gpu_info {
|
||||
namespace dawn::gpu_info {
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -151,4 +151,4 @@ std::string GetArchitectureName(PCIVendorID vendorId, PCIDeviceID deviceId) {
|
|||
return "";
|
||||
}
|
||||
|
||||
} // namespace gpu_info
|
||||
} // namespace dawn::gpu_info
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
using PCIVendorID = uint32_t;
|
||||
using PCIDeviceID = uint32_t;
|
||||
|
||||
namespace gpu_info {
|
||||
namespace dawn::gpu_info {
|
||||
|
||||
// Vendor IDs
|
||||
{% for vendor in vendors %}
|
||||
|
@ -51,5 +51,5 @@ namespace gpu_info {
|
|||
std::string GetVendorName(PCIVendorID vendorId);
|
||||
std::string GetArchitectureName(PCIVendorID vendorId, PCIDeviceID deviceId);
|
||||
|
||||
} // namespace gpu_info
|
||||
} // namespace dawn::gpu_info
|
||||
#endif // SRC_DAWN_COMMON_GPUINFO_AUTOGEN_H_
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace DawnLPMFuzzer {
|
||||
|
||||
|
||||
static constexpr int kInstanceObjectId = 1;
|
||||
static constexpr uint32_t kInvalidObjectId = {{ cmd_records["lpm_info"]["invalid object id"] }};
|
||||
|
||||
{% for type in by_category["object"] %}
|
||||
{% if type.name.get() in cmd_records["lpm_info"]["limits"] %}
|
||||
static constexpr int k{{ type.name.CamelCase() }}Limit = {{ cmd_records["lpm_info"]["limits"][type.name.get()] }};
|
||||
{% else %}
|
||||
static constexpr int k{{ type.name.CamelCase() }}Limit = {{ cmd_records["lpm_info"]["limits"]["default"] }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
} // namespace DawnLPMFuzzer
|
|
@ -0,0 +1,269 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMConstants_autogen.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMObjectStore.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h"
|
||||
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h"
|
||||
#include "dawn/webgpu.h"
|
||||
#include "dawn/wire/BufferConsumer_impl.h"
|
||||
#include "dawn/wire/ObjectHandle.h"
|
||||
#include "dawn/wire/Wire.h"
|
||||
#include "dawn/wire/WireClient.h"
|
||||
#include "dawn/wire/WireCmd_autogen.h"
|
||||
#include "dawn/wire/WireResult.h"
|
||||
#include "dawn/wire/client/ApiObjects_autogen.h"
|
||||
|
||||
namespace dawn::wire {
|
||||
|
||||
//* Outputs an rvalue that's the number of elements a pointer member points to.
|
||||
{% macro member_length(member, proto_accessor) -%}
|
||||
{%- if member.length == "constant" -%}
|
||||
{{member.constant_length}}u
|
||||
{%- else -%}
|
||||
{{proto_accessor}}().size()
|
||||
{%- endif -%}
|
||||
{%- endmacro %}
|
||||
|
||||
//* Outputs the type that will be used on the wire for the member
|
||||
{% macro member_type(member) -%}
|
||||
{{ assert(as_cType(member.type.name) != "size_t") }}
|
||||
{{as_cType(member.type.name)}}
|
||||
{%- endmacro %}
|
||||
|
||||
//* Outputs the conversion code to put `in` in `out`
|
||||
{% macro convert_member(member, in, out, in_access="") %}
|
||||
{% if member.type in by_category["structure"] %}
|
||||
{{ convert_structure(member, in, out, in_access) }}
|
||||
{% elif member.type in by_category["bitmask"] %}
|
||||
{{ convert_bitmask(member, in, out, in_access) }}
|
||||
{% elif member.type in by_category["enum"] %}
|
||||
{{ convert_enum(member, in, out, in_access) }}
|
||||
{% elif member.type in by_category["object"] %}
|
||||
{{ convert_object(member, in, out, in_access) }}
|
||||
{% elif member.type.name.get() == "ObjectId" %}
|
||||
{{ convert_objectid(member, in, out, access) }}
|
||||
{% elif member.type.name.get() == "ObjectHandle" %}
|
||||
{{ convert_objecthandle(member, in, out, in_access) }}
|
||||
{% else %}
|
||||
{{out}} = {{in}}({{in_access}});
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
//* Helper functions for converting protobufs to specific types
|
||||
{% macro convert_enum(member, in, out, in_access) %}
|
||||
{{out}} = static_cast<{{ member_type(member) }}>(
|
||||
{{in}}({{in_access}})
|
||||
);
|
||||
{% endmacro %}
|
||||
|
||||
{% macro convert_object(member, in, out, in_access) -%}
|
||||
{{ out }} = reinterpret_cast<{{ as_cType(member.type.name) }}>(
|
||||
objectStores[ObjectType::{{ member.type.name.CamelCase() }}].Lookup(
|
||||
static_cast<ObjectId>(
|
||||
{{in}}({{in_access}})
|
||||
)
|
||||
)
|
||||
);
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro convert_objectid(member, in, out, in_access) -%}
|
||||
{{ out }} = objectStores[ObjectType::{{ member.id_type.name.CamelCase() }}].Lookup(
|
||||
static_cast<ObjectId>(
|
||||
{{in}}({{ in_access}})
|
||||
)
|
||||
);
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro convert_objecthandle(member, in, out, in_access) -%}
|
||||
if (objectStores[ObjectType::{{ member.handle_type.name.CamelCase() }}].Size() < DawnLPMFuzzer::k{{ member.handle_type.name.CamelCase() }}Limit) {
|
||||
{{ out }} = objectStores[ObjectType::{{ member.handle_type.name.CamelCase() }}].ReserveHandle();
|
||||
} else {
|
||||
{{ out }} = {0, 0};
|
||||
}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro convert_bitmask(member, in, out, in_access) -%}
|
||||
{{ out }} = 0;
|
||||
for (size_t bm = 0; bm < static_cast<size_t>({{ in }}().size()); bm++) {
|
||||
{{ out }} |=
|
||||
static_cast<{{ member_type(member) }}>(
|
||||
{{ in }}(bm)
|
||||
);
|
||||
}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro convert_structure(member, in, out, in_access) -%}
|
||||
// Serializing a Structure Recursively
|
||||
WIRE_TRY({{member_type(member)}}ProtoConvert({{in}}({{in_access}}), &{{out}}, serializeBuffer, objectStores));
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro write_record_conversion_helpers(record, name, members, is_cmd) %}
|
||||
{% set overrides = cmd_records["lpm_info"]["overrides"] %}
|
||||
{% set overrides_key = record.name.canonical_case() %}
|
||||
{% set name = record.name.CamelCase() %}
|
||||
{% set Cmd = "Cmd" if is_cmd else "" %}
|
||||
{% set WGPU = "WGPU" if not is_cmd else "" %}
|
||||
|
||||
WireResult {{WGPU}}{{name}}ProtoConvert(fuzzing::{{ name }} proto_record, {{WGPU}}{{ name }}{{ Cmd }} const *record, SerializeBuffer* serializeBuffer, PerObjectType<DawnLPMObjectStore> &objectStores) {
|
||||
|
||||
{{WGPU}}{{ name }}{{ Cmd }} *mutable_record = const_cast<{{WGPU}}{{ name }}{{ Cmd }} *>(record);
|
||||
|
||||
//* Some commands don't set any members.
|
||||
DAWN_UNUSED(mutable_record);
|
||||
|
||||
//* Zero out any non-serializable values as they won't be set
|
||||
{% for member in members if member.skip_serialize %}
|
||||
{% set memberName = as_varName(member.name) %}
|
||||
memset(&mutable_record->{{ memberName }}, 0, sizeof(mutable_record->{{ memberName }}));
|
||||
{% endfor %}
|
||||
|
||||
//* Pass by Value handling. This mirrors WireCmd with some differences between
|
||||
//* convert_member and serialize_member
|
||||
{% for member in members if member.annotation == "value" if not member.skip_serialize %}
|
||||
{% set memberName = as_varName(member.name) %}
|
||||
{% set protoMember = as_protobufMemberName(member.name) %}
|
||||
|
||||
//* Major WireCmd Divergence: Some member values are hardcoded in dawn_lpm.json
|
||||
{% if overrides_key in overrides and member.name.canonical_case() in overrides[overrides_key] %}
|
||||
mutable_record->{{ memberName }} = {{ overrides[overrides_key][member.name.canonical_case()] }};
|
||||
{% else %}
|
||||
{{ convert_member(member, 'proto_record.' + protoMember, "mutable_record->" + memberName) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
//* Chained structures are currently not supported.
|
||||
{% if record.extensible %}
|
||||
mutable_record->nextInChain = nullptr;
|
||||
{% endif %}
|
||||
|
||||
//* Special handling for strings for now.
|
||||
{% for member in members if member.length == "strlen" %}
|
||||
{% set memberName = as_varName(member.name) %}
|
||||
{
|
||||
mutable_record->{{ memberName }} = "main";
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
//* Pass by Pointer handling. This mirrors WireCmd with some divergences when handling
|
||||
//* byte arrays.
|
||||
{% for member in members if member.annotation != "value" and member.length != "strlen" and not member.skip_serialize %}
|
||||
{% set memberName = as_varName(member.name) %}
|
||||
{% set protoMember = as_protobufMemberName(member.name) %}
|
||||
{% set protoAccess = "i" if member.length != "constant" or member.constant_length > 1 else "" %}
|
||||
|
||||
//* Major WireCmd Divergence: DawnLPM handles raw byte arrays uniquely
|
||||
//* as they don't lead to new coverage, lead to OOMs when allocated with
|
||||
//* an arbitrary size, and are difficult to work with in protobuf.
|
||||
{% if member.type.name.get() == 'uint8_t' %}
|
||||
{
|
||||
const size_t kDataBufferLength = 128;
|
||||
auto memberLength = kDataBufferLength;
|
||||
|
||||
{{member_type(member)}}* memberBuffer;
|
||||
WIRE_TRY(serializeBuffer->NextN(memberLength, &memberBuffer));
|
||||
memset(memberBuffer, 0, kDataBufferLength);
|
||||
mutable_record->{{ memberName }} = memberBuffer;
|
||||
|
||||
{% if member.length != "constant" -%}
|
||||
mutable_record->{{ member.length.name.camelCase() }} = memberLength;
|
||||
{%- endif %}
|
||||
}
|
||||
{% else %}
|
||||
{
|
||||
auto memberLength = static_cast<unsigned int>({{member_length(member, "proto_record." + protoMember)}});
|
||||
|
||||
//* Needed for the edge cases in "external texture descriptor"
|
||||
//* where we want to fuzzer to fill the fixed-length float arrays
|
||||
//* with values, but the length of the protobuf buffer might not
|
||||
//* be large enough for "src transfer function parameters".
|
||||
{% if member.length == "constant" and member.constant_length > 1 %}
|
||||
memberLength = std::min(memberLength, static_cast<unsigned int>({{"proto_record." + protoMember}}().size()));
|
||||
{% endif %}
|
||||
|
||||
{{member_type(member)}}* memberBuffer;
|
||||
WIRE_TRY(serializeBuffer->NextN(memberLength, &memberBuffer));
|
||||
|
||||
for (decltype(memberLength) i = 0; i < memberLength; ++i) {
|
||||
{{convert_member(member, "proto_record." + protoMember, "memberBuffer[i]", protoAccess )}}
|
||||
}
|
||||
|
||||
mutable_record->{{ memberName }} = memberBuffer;
|
||||
|
||||
//* Major WireCmd Divergence: Within the serializer the length member is
|
||||
//* set by using record.length. Here we aren't receiving any data
|
||||
//* and set it to the number of protobuf objects in proto_record.
|
||||
{% if member.length != "constant" -%}
|
||||
mutable_record->{{ member.length.name.camelCase() }} = memberLength;
|
||||
{%- endif %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
return WireResult::Success;
|
||||
}
|
||||
{% endmacro %}
|
||||
|
||||
//* Output structure conversion first because it is used by commands.
|
||||
{% for type in by_category["structure"] %}
|
||||
{% set name = as_cType(type.name) %}
|
||||
{% if type.name.CamelCase() not in client_side_structures %}
|
||||
{{ write_record_conversion_helpers(type, name, type.members, False) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
//* Output command conversion functions.
|
||||
{% for command in cmd_records["cpp_generated_commands"] %}
|
||||
{% set name = command.name.CamelCase() %}
|
||||
{{ write_record_conversion_helpers(command, name, command.members, True) }}
|
||||
{% endfor %}
|
||||
|
||||
WireResult SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCommandSerializer serializer) {
|
||||
DawnLPMObjectIdProvider provider;
|
||||
PerObjectType<DawnLPMObjectStore> objectStores;
|
||||
|
||||
// Allocate a scoped buffer allocation
|
||||
const size_t kMaxSerializeBufferSize = 65536;
|
||||
std::unique_ptr<char[]> allocatedBuffer(
|
||||
new char[kMaxSerializeBufferSize]()
|
||||
);
|
||||
|
||||
for (const fuzzing::Command& command : program.commands()) {
|
||||
switch (command.command_case()) {
|
||||
|
||||
{% for command in cmd_records["cpp_generated_commands"] %}
|
||||
{% set name = command.name.CamelCase() %}
|
||||
case fuzzing::Command::k{{name}}: {
|
||||
SerializeBuffer serializeBuffer(allocatedBuffer.get(), kMaxSerializeBufferSize);
|
||||
{{ name }}Cmd *cmd = nullptr;
|
||||
WIRE_TRY(serializeBuffer.Next(&cmd));
|
||||
|
||||
WIRE_TRY({{name}}ProtoConvert(command.{{ command.name.concatcase() }}(), cmd, &serializeBuffer, objectStores));
|
||||
|
||||
serializer.SerializeCommand(*cmd, provider);
|
||||
break;
|
||||
}
|
||||
{% endfor %}
|
||||
default: {
|
||||
GetCustomSerializedData(command, serializer, objectStores, provider);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WireResult::Success;
|
||||
}
|
||||
|
||||
} // namespace dawn::wire
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_DAWN_FUZZERS_DAWNLPMSERIALIZER_H_
|
||||
#define SRC_DAWN_FUZZERS_DAWNLPMSERIALIZER_H_
|
||||
|
||||
#include "dawn/fuzzers/lpmfuzz/dawn_lpm_autogen.pb.h"
|
||||
#include "dawn/wire/ChunkedCommandSerializer.h"
|
||||
#include "dawn/wire/WireCmd_autogen.h"
|
||||
#include "dawn/wire/WireResult.h"
|
||||
|
||||
namespace dawn::wire {
|
||||
|
||||
class DawnLPMObjectIdProvider : public ObjectIdProvider {
|
||||
private:
|
||||
|
||||
// Implementation of the ObjectIdProvider interface
|
||||
{% for type in by_category["object"] %}
|
||||
WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||
*out = reinterpret_cast<uintptr_t>(object);
|
||||
return WireResult::Success;
|
||||
}
|
||||
WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const final {
|
||||
*out = reinterpret_cast<uintptr_t>(object);
|
||||
return WireResult::Success;
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
};
|
||||
|
||||
WireResult SerializedData(const fuzzing::Program& program,
|
||||
dawn::wire::ChunkedCommandSerializer serializer);
|
||||
|
||||
} // namespace dawn::wire
|
||||
|
||||
#endif // SRC_DAWN_FUZZERS_DAWNLPMSERIALIZER_H_
|
|
@ -0,0 +1,179 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
package fuzzing;
|
||||
|
||||
import "third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto";
|
||||
|
||||
|
||||
// These are hardcoded limits for Dawn Object allocations based on type to help
|
||||
// guide the fuzzer towards reusing existing objects.
|
||||
{% for type in by_category["object"] %}
|
||||
{% set type_key = type.name.canonical_case() %}
|
||||
enum {{ type.name.CamelCase() }}Id {
|
||||
{% if type_key in cmd_records["lpm_info"]["limits"] %}
|
||||
{% for n in range(cmd_records["lpm_info"]["limits"][type_key]) %}
|
||||
{{ type.name.SNAKE_CASE() }}_{{ loop.index }} = {{ loop.index }};
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for n in range(cmd_records["lpm_info"]["limits"]["default"]) %}
|
||||
{{ type.name.SNAKE_CASE() }}_{{ loop.index }} = {{ loop.index }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
INVALID_{{ type.name.SNAKE_CASE() }} = {{ cmd_records["lpm_info"]["invalid object id"] }};
|
||||
};
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["enum"] %}
|
||||
enum {{as_cppType(type.name)}} {
|
||||
{% for value in type.values %}
|
||||
{{ as_cppType(type.name) }}{{as_cppEnum(value.name)}} = {{ value.value }};
|
||||
{% endfor %}
|
||||
};
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% for type in by_category["bitmask"] %}
|
||||
enum {{as_cppType(type.name)}} {
|
||||
{% for value in type.values %}
|
||||
{{ as_cppType(type.name) }}{{as_cppEnum(value.name)}} = {{ value.value }};
|
||||
{% endfor %}
|
||||
};
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% macro lift_string_proto_member(member, count) -%}
|
||||
required string {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
|
||||
{%- endmacro %}
|
||||
|
||||
|
||||
{% macro lift_float_array_proto_member(member, count) -%}
|
||||
repeated float {{ as_varName(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{%- endmacro %}
|
||||
|
||||
|
||||
{% macro lift_object_member(member, count) %}
|
||||
{{ member.type.name.CamelCase() }}Id {{ as_protobufNameLPM(member.name) }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro lift_objectid_member(member, count) %}
|
||||
{{ member.id_type.name.CamelCase() }}Id {{ as_protobufNameLPM(member.name) }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro lift_varlength_proto_member(member, count) -%}
|
||||
{% if member.type in by_category["object"] %}
|
||||
repeated {{ lift_object_member(member, count) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type.name.get() == "object id" %}
|
||||
repeated {{ lift_objectid_member(member, count) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% else %}
|
||||
repeated {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
|
||||
{% macro lift_dawn_member_pass_by_value(record, name, member, count) %}
|
||||
{% if member.type in by_category["structure"] %}
|
||||
required {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type in by_category["bitmask"] %}
|
||||
repeated {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type in by_category["enum"] %}
|
||||
required {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type in by_category["object"] %}
|
||||
required {{ lift_object_member(member, count) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type.name.get() == "ObjectId" %}
|
||||
required {{ lift_objectid_member(member, count) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type.name.get() == "ObjectHandle" %}
|
||||
// Skips object handles while lifting dawn.json to protobuf because
|
||||
// ObjectHandles are created and managed in DawnLPMSerializer. Passing
|
||||
// arbitrary ObjectHandles from the fuzzer's bytestream isn't the
|
||||
// strategy for this fuzzer.
|
||||
{% else %}
|
||||
required {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro lift_dawn_member_pass_by_pointer(record, name, member, count) %}
|
||||
{% if member.type in by_category["structure"] and member.length == "constant" and member.constant_length == 1 %}
|
||||
required {{ as_protobufTypeLPM(member) }} {{ as_protobufNameLPM(member.name) }} = {{ count.value }};
|
||||
{% set count.value = count.value + 1 %}
|
||||
{% elif member.type.name.get() == "char" and member.length == 'strlen' %}
|
||||
{{ lift_string_proto_member(member, count) }}
|
||||
{% elif member.type.name.get() == "float" %}
|
||||
{{ lift_float_array_proto_member(member, count) }}
|
||||
{% elif member.type.name.get() == "uint8_t" %}
|
||||
// Skip over byte arrays in protobuf, handled by DawnLPMSerializer
|
||||
// with a hardcoded bytes and length.
|
||||
{% elif member.length != 'constant' %}
|
||||
{{ lift_varlength_proto_member(member, count) }}
|
||||
{% else %}
|
||||
// There shouldn't be any other pass-by-pointer types in
|
||||
// dawn*.json, if any are added we would like to know at compile time
|
||||
{{ unreachable_code() }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro lift_proto_members_helper(record, name, members) %}
|
||||
{% set count = namespace(value=1) %}
|
||||
{% for member in members %}
|
||||
{% if member.skip_serialize == True %}
|
||||
// {{ member.name.camelCase()}}.skip_serialize
|
||||
{% elif member.annotation == 'value' %}
|
||||
{{ lift_dawn_member_pass_by_value(record, name, member, count) }}
|
||||
{% elif member.annotation == 'const*' %}
|
||||
{{ lift_dawn_member_pass_by_pointer(record, name, member, count) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% for structure in by_category["structure"] %}
|
||||
message {{structure.name.CamelCase()}} {
|
||||
{{ lift_proto_members_helper(structure, structure.name, structure.members) }}
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
{% for command in cmd_records["proto_generated_commands"] %}
|
||||
message {{command.name.CamelCase()}} {
|
||||
{{ lift_proto_members_helper(command, command.name, command.members) }}
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
message Command {
|
||||
oneof command {
|
||||
{% for command in cmd_records["proto_all_commands"] %}
|
||||
{{command.name.CamelCase()}} {{command.name.camelCase()}} = {{ loop.index }};
|
||||
{% endfor %}
|
||||
}
|
||||
}
|
||||
|
||||
message Program {
|
||||
repeated Command commands = 1;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
package fuzzing;
|
||||
|
||||
enum ObjectType {
|
||||
{% for type in by_category["object"] %}
|
||||
{{ type.name.CamelCase() }} = {{ loop.index - 1}};
|
||||
{% endfor %}
|
||||
};
|
|
@ -23,43 +23,55 @@
|
|||
namespace {{native_namespace}} {
|
||||
|
||||
{% set namespace = metadata.namespace %}
|
||||
{% for value in types["s type"].values %}
|
||||
{% if value.valid %}
|
||||
void FindInChain(const ChainedStruct* chain, const {{as_cppEnum(value.name)}}** out) {
|
||||
for (; chain; chain = chain->nextInChain) {
|
||||
if (chain->sType == {{namespace}}::SType::{{as_cppEnum(value.name)}}) {
|
||||
*out = static_cast<const {{as_cppEnum(value.name)}}*>(chain);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
MaybeError ValidateSTypes(const ChainedStruct* chain,
|
||||
std::vector<std::vector<{{namespace}}::SType>> oneOfConstraints) {
|
||||
std::unordered_set<{{namespace}}::SType> allSTypes;
|
||||
for (; chain; chain = chain->nextInChain) {
|
||||
if (allSTypes.find(chain->sType) != allSTypes.end()) {
|
||||
return DAWN_VALIDATION_ERROR("Chain cannot have duplicate sTypes");
|
||||
}
|
||||
DAWN_INVALID_IF(allSTypes.find(chain->sType) != allSTypes.end(),
|
||||
"Extension chain has duplicate sType %s.", chain->sType);
|
||||
allSTypes.insert(chain->sType);
|
||||
}
|
||||
|
||||
for (const auto& oneOfConstraint : oneOfConstraints) {
|
||||
bool satisfied = false;
|
||||
for ({{namespace}}::SType oneOfSType : oneOfConstraint) {
|
||||
if (allSTypes.find(oneOfSType) != allSTypes.end()) {
|
||||
if (satisfied) {
|
||||
return DAWN_VALIDATION_ERROR("Unsupported sType combination");
|
||||
}
|
||||
DAWN_INVALID_IF(satisfied,
|
||||
"sType %s is part of a group of exclusive sTypes that is already present.",
|
||||
oneOfSType);
|
||||
satisfied = true;
|
||||
allSTypes.erase(oneOfSType);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allSTypes.empty()) {
|
||||
return DAWN_VALIDATION_ERROR("Unsupported sType");
|
||||
|
||||
DAWN_INVALID_IF(!allSTypes.empty(), "Unsupported sType %s.", *allSTypes.begin());
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateSTypes(const ChainedStructOut* chain,
|
||||
std::vector<std::vector<{{namespace}}::SType>> oneOfConstraints) {
|
||||
std::unordered_set<{{namespace}}::SType> allSTypes;
|
||||
for (; chain; chain = chain->nextInChain) {
|
||||
DAWN_INVALID_IF(allSTypes.find(chain->sType) != allSTypes.end(),
|
||||
"Extension chain has duplicate sType %s.", chain->sType);
|
||||
allSTypes.insert(chain->sType);
|
||||
}
|
||||
|
||||
for (const auto& oneOfConstraint : oneOfConstraints) {
|
||||
bool satisfied = false;
|
||||
for ({{namespace}}::SType oneOfSType : oneOfConstraint) {
|
||||
if (allSTypes.find(oneOfSType) != allSTypes.end()) {
|
||||
DAWN_INVALID_IF(satisfied,
|
||||
"sType %s is part of a group of exclusive sTypes that is already present.",
|
||||
oneOfSType);
|
||||
satisfied = true;
|
||||
allSTypes.erase(oneOfSType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DAWN_INVALID_IF(!allSTypes.empty(), "Unsupported sType %s.", *allSTypes.begin());
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define {{DIR}}_CHAIN_UTILS_H_
|
||||
|
||||
{% set impl_dir = metadata.impl_dir + "/" if metadata.impl_dir else "" %}
|
||||
{% set namespace = metadata.namespace %}
|
||||
{% set namespace_name = Name(metadata.native_namespace) %}
|
||||
{% set native_namespace = namespace_name.namespace_case() %}
|
||||
{% set native_dir = impl_dir + namespace_name.Dirs() %}
|
||||
|
@ -26,11 +27,44 @@
|
|||
#include "{{native_dir}}/Error.h"
|
||||
|
||||
namespace {{native_namespace}} {
|
||||
namespace detail {
|
||||
// Mapping from native types to the expected STypes is implemented as template specializations.
|
||||
template <typename T>
|
||||
struct STypeForImpl;
|
||||
{% for value in types["s type"].values %}
|
||||
{% if value.valid %}
|
||||
void FindInChain(const ChainedStruct* chain, const {{as_cppEnum(value.name)}}** out);
|
||||
{% if value.valid and value.name.get() in types %}
|
||||
template <>
|
||||
struct STypeForImpl<{{as_cppEnum(value.name)}}> {
|
||||
static constexpr {{namespace}}::SType value = {{namespace}}::SType::{{as_cppEnum(value.name)}};
|
||||
};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
template <>
|
||||
struct STypeForImpl<DawnInstanceDescriptor> {
|
||||
static constexpr {{namespace}}::SType value = {{namespace}}::SType::DawnInstanceDescriptor;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
constexpr {{namespace}}::SType STypeFor = detail::STypeForImpl<T>::value;
|
||||
template <typename T>
|
||||
void FindInChain(const ChainedStruct* chain, const T** out) {
|
||||
for (; chain; chain = chain->nextInChain) {
|
||||
if (chain->sType == STypeFor<T>) {
|
||||
*out = static_cast<const T*>(chain);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void FindInChain(ChainedStructOut* chain, T** out) {
|
||||
for (; chain; chain = chain->nextInChain) {
|
||||
if (chain->sType == STypeFor<T>) {
|
||||
*out = static_cast<T*>(chain);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that |chain| only contains ChainedStructs of types enumerated in
|
||||
// |oneOfConstraints| and contains no duplicate sTypes. Each vector in
|
||||
|
@ -38,9 +72,10 @@ namespace {{native_namespace}} {
|
|||
// For example:
|
||||
// ValidateSTypes(chain, { { ShaderModuleSPIRVDescriptor, ShaderModuleWGSLDescriptor } }))
|
||||
// ValidateSTypes(chain, { { Extension1 }, { Extension2 } })
|
||||
{% set namespace = metadata.namespace %}
|
||||
MaybeError ValidateSTypes(const ChainedStruct* chain,
|
||||
std::vector<std::vector<{{namespace}}::SType>> oneOfConstraints);
|
||||
MaybeError ValidateSTypes(const ChainedStructOut* chain,
|
||||
std::vector<std::vector<{{namespace}}::SType>> oneOfConstraints);
|
||||
|
||||
template <typename T>
|
||||
MaybeError ValidateSingleSTypeInner(const ChainedStruct* chain, T sType) {
|
||||
|
@ -48,6 +83,12 @@ namespace {{native_namespace}} {
|
|||
"Unsupported sType (%s). Expected (%s)", chain->sType, sType);
|
||||
return {};
|
||||
}
|
||||
template <typename T>
|
||||
MaybeError ValidateSingleSTypeInner(const ChainedStructOut* chain, T sType) {
|
||||
DAWN_INVALID_IF(chain->sType != sType,
|
||||
"Unsupported sType (%s). Expected (%s)", chain->sType, sType);
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
MaybeError ValidateSingleSTypeInner(const ChainedStruct* chain, T sType, Args... sTypes) {
|
||||
|
@ -56,6 +97,13 @@ namespace {{native_namespace}} {
|
|||
}
|
||||
return ValidateSingleSTypeInner(chain, sTypes...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
MaybeError ValidateSingleSTypeInner(const ChainedStructOut* chain, T sType, Args... sTypes) {
|
||||
if (chain->sType == sType) {
|
||||
return {};
|
||||
}
|
||||
return ValidateSingleSTypeInner(chain, sTypes...);
|
||||
}
|
||||
|
||||
// Verifies that |chain| contains a single ChainedStruct of type |sType| or no ChainedStructs
|
||||
// at all.
|
||||
|
@ -68,6 +116,15 @@ namespace {{native_namespace}} {
|
|||
"Chain can only contain a single chained struct.");
|
||||
return ValidateSingleSTypeInner(chain, sType);
|
||||
}
|
||||
template <typename T>
|
||||
MaybeError ValidateSingleSType(const ChainedStructOut* chain, T sType) {
|
||||
if (chain == nullptr) {
|
||||
return {};
|
||||
}
|
||||
DAWN_INVALID_IF(chain->nextInChain != nullptr,
|
||||
"Chain can only contain a single chained struct.");
|
||||
return ValidateSingleSTypeInner(chain, sType);
|
||||
}
|
||||
|
||||
// Verifies that |chain| contains a single ChainedStruct with a type enumerated in the
|
||||
// parameter pack or no ChainedStructs at all.
|
||||
|
@ -80,6 +137,15 @@ namespace {{native_namespace}} {
|
|||
"Chain can only contain a single chained struct.");
|
||||
return ValidateSingleSTypeInner(chain, sType, sTypes...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
MaybeError ValidateSingleSType(const ChainedStructOut* chain, T sType, Args... sTypes) {
|
||||
if (chain == nullptr) {
|
||||
return {};
|
||||
}
|
||||
DAWN_INVALID_IF(chain->nextInChain != nullptr,
|
||||
"Chain can only contain a single chained struct.");
|
||||
return ValidateSingleSTypeInner(chain, sType, sTypes...);
|
||||
}
|
||||
|
||||
} // namespace {{native_namespace}}
|
||||
|
||||
|
|
|
@ -56,6 +56,17 @@ namespace {{native_namespace}} {
|
|||
{% endif %}
|
||||
{%- endfor-%}
|
||||
|
||||
{% if method.autolock %}
|
||||
{% if type.name.get() != "device" %}
|
||||
auto device = self->GetDevice();
|
||||
{% else %}
|
||||
auto device = self;
|
||||
{% endif %}
|
||||
auto deviceLock(device->GetScopedLock());
|
||||
{% else %}
|
||||
// This method is specified to not use AutoLock in json script.
|
||||
{% endif %}
|
||||
|
||||
{% if method.return_type.name.canonical_case() != "void" %}
|
||||
auto result =
|
||||
{%- endif %}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace {{native_namespace}} {
|
|||
return {};
|
||||
{% endfor %}
|
||||
default:
|
||||
return DAWN_VALIDATION_ERROR("Invalid value for {{as_cType(type.name)}}");
|
||||
return DAWN_VALIDATION_ERROR("Value %i is invalid for {{as_cType(type.name)}}.", static_cast<uint32_t>(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace {{native_namespace}} {
|
|||
if ((value & static_cast<{{namespace}}::{{as_cppType(type.name)}}>(~{{type.full_mask}})) == 0) {
|
||||
return {};
|
||||
}
|
||||
return DAWN_VALIDATION_ERROR("Invalid value for {{as_cType(type.name)}}");
|
||||
return DAWN_VALIDATION_ERROR("Value %i is invalid for {{as_cType(type.name)}}.", static_cast<uint32_t>(value));
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
@ -25,7 +25,15 @@
|
|||
namespace {{native_namespace}} {
|
||||
|
||||
//
|
||||
// Cache key writers for wgpu structures used in caching.
|
||||
// Streaming readers for wgpu structures.
|
||||
//
|
||||
{% macro render_reader(member) %}
|
||||
{%- set name = member.name.camelCase() -%}
|
||||
DAWN_TRY(StreamOut(source, &t->{{name}}));
|
||||
{% endmacro %}
|
||||
|
||||
//
|
||||
// Streaming writers for wgpu structures.
|
||||
//
|
||||
{% macro render_writer(member) %}
|
||||
{%- set name = member.name.camelCase() -%}
|
||||
|
@ -38,31 +46,50 @@ namespace {{native_namespace}} {
|
|||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{# Helper macro to render writers. Should be used in a call block to provide additional custom
|
||||
{# Helper macro to render readers and writers. Should be used in a call block to provide additional custom
|
||||
handling when necessary. The optional `omit` field can be used to omit fields that are either
|
||||
handled in the custom code, or unnecessary in the serialized output.
|
||||
Example:
|
||||
{% call render_cache_key_writer("struct name", omits=["omit field"]) %}
|
||||
{% call render_streaming_impl("struct name", writer=true, reader=false, omits=["omit field"]) %}
|
||||
// Custom C++ code to handle special types/members that are hard to generate code for
|
||||
{% endcall %}
|
||||
One day we should probably make the generator smart enough to generate everything it can
|
||||
instead of manually adding streaming implementations here.
|
||||
#}
|
||||
{% macro render_cache_key_writer(json_type, omits=[]) %}
|
||||
{% macro render_streaming_impl(json_type, writer, reader, omits=[]) %}
|
||||
{%- set cpp_type = types[json_type].name.CamelCase() -%}
|
||||
template <>
|
||||
void stream::Stream<{{cpp_type}}>::Write(stream::Sink* sink, const {{cpp_type}}& t) {
|
||||
{{ caller() }}
|
||||
{% for member in types[json_type].members %}
|
||||
{%- if not member.name.get() in omits %}
|
||||
{{render_writer(member)}}
|
||||
{%- endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% if reader %}
|
||||
template <>
|
||||
MaybeError stream::Stream<{{cpp_type}}>::Read(stream::Source* source, {{cpp_type}}* t) {
|
||||
{{ caller() }}
|
||||
{% for member in types[json_type].members %}
|
||||
{% if not member.name.get() in omits %}
|
||||
{{render_reader(member)}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
return {};
|
||||
}
|
||||
{% endif %}
|
||||
{% if writer %}
|
||||
template <>
|
||||
void stream::Stream<{{cpp_type}}>::Write(stream::Sink* sink, const {{cpp_type}}& t) {
|
||||
{{ caller() }}
|
||||
{% for member in types[json_type].members %}
|
||||
{% if not member.name.get() in omits %}
|
||||
{{render_writer(member)}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% call render_cache_key_writer("adapter properties") %}
|
||||
{% call render_streaming_impl("adapter properties", true, false) %}
|
||||
{% endcall %}
|
||||
|
||||
{% call render_cache_key_writer("dawn cache device descriptor") %}
|
||||
{% call render_streaming_impl("dawn cache device descriptor", true, false) %}
|
||||
{% endcall %}
|
||||
|
||||
{% call render_streaming_impl("extent 3D", true, true) %}
|
||||
{% endcall %}
|
||||
|
||||
} // namespace {{native_namespace}}
|
||||
|
|
|
@ -44,14 +44,13 @@ namespace {{native_namespace}} {
|
|||
{%- endif -%}
|
||||
{%- endmacro %}
|
||||
|
||||
struct ChainedStruct {
|
||||
ChainedStruct const * nextInChain = nullptr;
|
||||
{{namespace}}::SType sType = {{namespace}}::SType::Invalid;
|
||||
};
|
||||
using {{namespace}}::ChainedStruct;
|
||||
using {{namespace}}::ChainedStructOut;
|
||||
|
||||
{% for type in by_category["structure"] %}
|
||||
{% if type.chained %}
|
||||
struct {{as_cppType(type.name)}} : ChainedStruct {
|
||||
{% set chainedStructType = "ChainedStructOut" if type.chained == "out" else "ChainedStruct" %}
|
||||
struct {{as_cppType(type.name)}} : {{chainedStructType}} {
|
||||
{{as_cppType(type.name)}}() {
|
||||
sType = {{namespace}}::SType::{{type.name.CamelCase()}};
|
||||
}
|
||||
|
@ -59,7 +58,8 @@ namespace {{native_namespace}} {
|
|||
struct {{as_cppType(type.name)}} {
|
||||
{% endif %}
|
||||
{% if type.extensible %}
|
||||
ChainedStruct const * nextInChain = nullptr;
|
||||
{% set chainedStructType = "ChainedStructOut" if type.output else "ChainedStruct const" %}
|
||||
{{chainedStructType}} * nextInChain = nullptr;
|
||||
{% endif %}
|
||||
{% for member in type.members %}
|
||||
{% set member_declaration = as_annotated_frontendType(member) + render_cpp_default_value(member) %}
|
||||
|
|
|
@ -48,6 +48,23 @@ namespace {{native_namespace}} {
|
|||
inline {{as_cppType(type.name)}}* FromAPI({{as_cType(type.name)}}* rhs) {
|
||||
return reinterpret_cast<{{as_cppType(type.name)}}*>(rhs);
|
||||
}
|
||||
|
||||
inline const {{metadata.namespace}}::{{as_cppType(type.name)}}* ToCppAPI(const {{as_cppType(type.name)}}* rhs) {
|
||||
return reinterpret_cast<const {{metadata.namespace}}::{{as_cppType(type.name)}}*>(rhs);
|
||||
}
|
||||
|
||||
inline {{metadata.namespace}}::{{as_cppType(type.name)}}* ToCppAPI({{as_cppType(type.name)}}* rhs) {
|
||||
return reinterpret_cast<{{metadata.namespace}}::{{as_cppType(type.name)}}*>(rhs);
|
||||
}
|
||||
|
||||
inline const {{as_cppType(type.name)}}* FromCppAPI(const {{metadata.namespace}}::{{as_cppType(type.name)}}* rhs) {
|
||||
return reinterpret_cast<const {{as_cppType(type.name)}}*>(rhs);
|
||||
}
|
||||
|
||||
inline {{as_cppType(type.name)}}* FromCppAPI({{metadata.namespace}}::{{as_cppType(type.name)}}* rhs) {
|
||||
return reinterpret_cast<{{as_cppType(type.name)}}*>(rhs);
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["object"] %}
|
||||
|
@ -87,6 +104,6 @@ namespace {{native_namespace}} {
|
|||
return static_cast<{{namespace}}::{{as_cppType(type.name)}}>(rhs);
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
||||
} // namespace {{native_namespace}}
|
||||
|
||||
#endif // {{NATIVE_DIR}}_{{PREFIX}}_PLATFORM_AUTOGEN_H_
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
namespace dawn::wire {
|
||||
|
||||
constexpr uint32_t kObjectTypes = {{len(by_category["object"])}};
|
||||
|
||||
enum class ObjectType : uint32_t {
|
||||
{% for type in by_category["object"] %}
|
||||
{{type.name.CamelCase()}},
|
||||
|
|
|
@ -64,13 +64,10 @@
|
|||
{%- set Optional = "Optional" if member.optional else "" -%}
|
||||
WIRE_TRY(provider.Get{{Optional}}Id({{in}}, &{{out}}));
|
||||
{%- elif member.type.category == "structure" -%}
|
||||
{%- if member.type.is_wire_transparent -%}
|
||||
static_assert(sizeof({{out}}) == sizeof({{in}}), "Serialize memcpy size must match.");
|
||||
memcpy(&{{out}}, &{{in}}, {{member_transfer_sizeof(member)}});
|
||||
{%- else -%}
|
||||
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
|
||||
WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}}));
|
||||
{%- endif -%}
|
||||
//* Do not memcpy or we may serialize padding bytes which can leak information across a
|
||||
//* trusted boundary.
|
||||
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
|
||||
WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}}));
|
||||
{%- else -%}
|
||||
{{out}} = {{in}};
|
||||
{%- endif -%}
|
||||
|
@ -166,9 +163,11 @@
|
|||
{% if member.optional %}
|
||||
bool has_{{memberName}} = record.{{memberName}} != nullptr;
|
||||
if (has_{{memberName}})
|
||||
{% else %}
|
||||
ASSERT(record.{{memberName}} != nullptr);
|
||||
{% endif %}
|
||||
{
|
||||
result += std::strlen(record.{{memberName}});
|
||||
result += Align(std::strlen(record.{{memberName}}), kWireBufferAlignment);
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
|
@ -181,7 +180,9 @@
|
|||
{% if member.annotation != "value" %}
|
||||
{{ assert(member.annotation != "const*const*") }}
|
||||
auto memberLength = {{member_length(member, "record.")}};
|
||||
result += memberLength * {{member_transfer_sizeof(member)}};
|
||||
auto size = WireAlignSizeofN<{{member_transfer_type(member)}}>(memberLength);
|
||||
ASSERT(size);
|
||||
result += *size;
|
||||
//* Structures might contain more pointers so we need to add their extra size as well.
|
||||
{% if member.type.category == "structure" %}
|
||||
for (decltype(memberLength) i = 0; i < memberLength; ++i) {
|
||||
|
@ -434,7 +435,7 @@
|
|||
{% set Cmd = Name + "Cmd" %}
|
||||
|
||||
size_t {{Cmd}}::GetRequiredSize() const {
|
||||
size_t size = sizeof({{Name}}Transfer) + {{Name}}GetExtraRequiredSize(*this);
|
||||
size_t size = WireAlignSizeof<{{Name}}Transfer>() + {{Name}}GetExtraRequiredSize(*this);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -512,7 +513,7 @@
|
|||
) %}
|
||||
case {{as_cEnum(types["s type"].name, sType.name)}}: {
|
||||
const auto& typedStruct = *reinterpret_cast<{{as_cType(sType.name)}} const *>(chainedStruct);
|
||||
result += sizeof({{as_cType(sType.name)}}Transfer);
|
||||
result += WireAlignSizeof<{{as_cType(sType.name)}}Transfer>();
|
||||
result += {{as_cType(sType.name)}}GetExtraRequiredSize(typedStruct);
|
||||
chainedStruct = typedStruct.chain.next;
|
||||
break;
|
||||
|
@ -522,7 +523,7 @@
|
|||
case WGPUSType_Invalid:
|
||||
default:
|
||||
// Invalid enum. Reserve space just for the transfer header (sType and hasNext).
|
||||
result += sizeof(WGPUChainedStructTransfer);
|
||||
result += WireAlignSizeof<WGPUChainedStructTransfer>();
|
||||
chainedStruct = chainedStruct->next;
|
||||
break;
|
||||
}
|
||||
|
@ -603,7 +604,7 @@
|
|||
WIRE_TRY(deserializeBuffer->Read(&transfer));
|
||||
|
||||
{{CType}}* outStruct;
|
||||
WIRE_TRY(GetSpace(allocator, sizeof({{CType}}), &outStruct));
|
||||
WIRE_TRY(GetSpace(allocator, 1u, &outStruct));
|
||||
outStruct->chain.sType = sType;
|
||||
outStruct->chain.next = nullptr;
|
||||
|
||||
|
@ -632,7 +633,7 @@
|
|||
WIRE_TRY(deserializeBuffer->Read(&transfer));
|
||||
|
||||
{{ChainedStruct}}* outStruct;
|
||||
WIRE_TRY(GetSpace(allocator, sizeof({{ChainedStruct}}), &outStruct));
|
||||
WIRE_TRY(GetSpace(allocator, 1u, &outStruct));
|
||||
outStruct->sType = WGPUSType_Invalid;
|
||||
outStruct->next = nullptr;
|
||||
|
||||
|
@ -657,13 +658,23 @@ namespace dawn::wire {
|
|||
// Always writes to |out| on success.
|
||||
template <typename T, typename N>
|
||||
WireResult GetSpace(DeserializeAllocator* allocator, N count, T** out) {
|
||||
constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
|
||||
if (count > kMaxCountWithoutOverflows) {
|
||||
// Because we use this function extensively when `count` == 1, we can optimize the
|
||||
// size computations a bit more for those cases via constexpr version of the
|
||||
// alignment computation.
|
||||
constexpr size_t kSizeofT = WireAlignSizeof<T>();
|
||||
size_t size = 0;
|
||||
if (count == 1) {
|
||||
size = kSizeofT;
|
||||
} else {
|
||||
auto sizeN = WireAlignSizeofN<T>(count);
|
||||
// A size of 0 indicates an overflow, so return an error.
|
||||
if (!sizeN) {
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
size = *sizeN;
|
||||
}
|
||||
|
||||
size_t totalSize = sizeof(T) * count;
|
||||
*out = static_cast<T*>(allocator->GetSpace(totalSize));
|
||||
*out = static_cast<T*>(allocator->GetSpace(size));
|
||||
if (*out == nullptr) {
|
||||
return WireResult::FatalError;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace dawn::wire::server {
|
|||
{% set Type = member.handle_type.name.CamelCase() %}
|
||||
{% set name = as_varName(member.name) %}
|
||||
|
||||
auto* {{name}}Data = {{Type}}Objects().Allocate(cmd.{{name}}.id);
|
||||
auto* {{name}}Data = {{Type}}Objects().Allocate(cmd.{{name}});
|
||||
if ({{name}}Data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,13 +36,26 @@ MaybeError OpenGLFunctionsBase::LoadOpenGLESProcs(GetProcAddress getProc, int ma
|
|||
|
||||
{% endfor %}
|
||||
|
||||
InitializeSupportedGLExtensions();
|
||||
|
||||
{% for block in extension_gles_blocks %}
|
||||
// {{block.extension}}
|
||||
{% for proc in block.procs %}
|
||||
DAWN_TRY(LoadProc(getProc, &{{proc.ProcName()}}, "{{proc.glProcName()}}"));
|
||||
if (IsGLExtensionSupported("{{block.extension}}")) {
|
||||
{% for proc in block.procs %}
|
||||
DAWN_TRY(LoadProc(getProc, &{{proc.ProcName()}}, "{{proc.glProcName()}}"));
|
||||
{% endfor %}
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
// GL_ANGLE_base_vertex_base_instance
|
||||
// See crbug.com/dawn/1715 for why this is embedded
|
||||
if (IsGLExtensionSupported("GL_ANGLE_base_vertex_base_instance")) {
|
||||
DAWN_TRY(LoadProc(getProc, &DrawArraysInstancedBaseInstanceANGLE, "glDrawArraysInstancedBaseInstanceANGLE"));
|
||||
DAWN_TRY(LoadProc(getProc, &DrawElementsInstancedBaseVertexBaseInstanceANGLE, "glDrawElementsInstancedBaseVertexBaseInstanceANGLE"));
|
||||
DAWN_TRY(LoadProc(getProc, &MultiDrawArraysInstancedBaseInstanceANGLE, "glMultiDrawArraysInstancedBaseInstanceANGLE"));
|
||||
DAWN_TRY(LoadProc(getProc, &MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE, "glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE"));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -57,14 +70,33 @@ MaybeError OpenGLFunctionsBase::LoadDesktopGLProcs(GetProcAddress getProc, int m
|
|||
|
||||
{% endfor %}
|
||||
|
||||
InitializeSupportedGLExtensions();
|
||||
|
||||
{% for block in extension_desktop_gl_blocks %}
|
||||
// {{block.extension}}
|
||||
{% for proc in block.procs %}
|
||||
DAWN_TRY(LoadProc(getProc, &{{proc.ProcName()}}, "{{proc.glProcName()}}"));
|
||||
{% endfor %}
|
||||
if (IsGLExtensionSupported("{{block.extension}}")) {
|
||||
{% for proc in block.procs %}
|
||||
DAWN_TRY(LoadProc(getProc, &{{proc.ProcName()}}, "{{proc.glProcName()}}"));
|
||||
{% endfor %}
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void OpenGLFunctionsBase::InitializeSupportedGLExtensions() {
|
||||
int32_t numExtensions;
|
||||
GetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
|
||||
|
||||
for (int32_t i = 0; i < numExtensions; ++i) {
|
||||
const char* extensionName = reinterpret_cast<const char*>(GetStringi(GL_EXTENSIONS, i));
|
||||
mSupportedGLExtensionsSet.insert(extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenGLFunctionsBase::IsGLExtensionSupported(const char* extension) const {
|
||||
ASSERT(extension != nullptr);
|
||||
return mSupportedGLExtensionsSet.count(extension) != 0;
|
||||
}
|
||||
|
||||
} // namespace dawn::native::opengl
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef DAWNNATIVE_OPENGL_OPENGLFUNCTIONSBASE_H_
|
||||
#define DAWNNATIVE_OPENGL_OPENGLFUNCTIONSBASE_H_
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "dawn/native/Error.h"
|
||||
#include "dawn/native/opengl/opengl_platform.h"
|
||||
|
||||
|
@ -31,6 +33,15 @@ namespace dawn::native::opengl {
|
|||
|
||||
{% endfor%}
|
||||
|
||||
// GL_ANGLE_base_vertex_base_instance
|
||||
// See crbug.com/dawn/1715 for why this is embedded
|
||||
PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC DrawArraysInstancedBaseInstanceANGLE = nullptr;
|
||||
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC DrawElementsInstancedBaseVertexBaseInstanceANGLE = nullptr;
|
||||
PFNGLMULTIDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC MultiDrawArraysInstancedBaseInstanceANGLE = nullptr;
|
||||
PFNGLMULTIDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE = nullptr;
|
||||
|
||||
bool IsGLExtensionSupported(const char* extension) const;
|
||||
|
||||
protected:
|
||||
MaybeError LoadDesktopGLProcs(GetProcAddress getProc, int majorVersion, int minorVersion);
|
||||
MaybeError LoadOpenGLESProcs(GetProcAddress getProc, int majorVersion, int minorVersion);
|
||||
|
@ -38,6 +49,9 @@ namespace dawn::native::opengl {
|
|||
private:
|
||||
template<typename T>
|
||||
MaybeError LoadProc(GetProcAddress getProc, T* memberProc, const char* name);
|
||||
void InitializeSupportedGLExtensions();
|
||||
|
||||
std::unordered_set<std::string> mSupportedGLExtensionsSet;
|
||||
};
|
||||
|
||||
} // namespace dawn::native::opengl
|
||||
|
|
|
@ -70,4 +70,12 @@ using GLDEBUGPROCAMD = void(KHRONOS_APIENTRY*)(GLuint id,
|
|||
{% endfor %}
|
||||
|
||||
{% endfor%}
|
||||
|
||||
// GL_ANGLE_base_vertex_base_instance
|
||||
// See crbug.com/dawn/1715 for why this is embedded
|
||||
using PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC = void(KHRONOS_APIENTRY *)(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount, GLuint baseInstance);
|
||||
using PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC = void(KHRONOS_APIENTRY *)(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance);
|
||||
using PFNGLMULTIDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC = void(KHRONOS_APIENTRY *)(GLenum mode, const GLint * firsts, const GLsizei * counts, const GLsizei * instanceCounts, const GLuint * baseInstances, GLsizei drawcount);
|
||||
using PFNGLMULTIDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC = void(KHRONOS_APIENTRY *)(GLenum mode, const GLsizei * counts, GLenum type, const GLvoid *const* indices, const GLsizei * instanceCounts, const GLint * baseVertices, const GLuint * baseInstances, GLsizei drawcount);
|
||||
|
||||
#undef DAWN_GL_APIENTRY
|
||||
|
|
53
go.mod
53
go.mod
|
@ -3,46 +3,53 @@ module dawn.googlesource.com/dawn
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/andygrunwald/go-gerrit v0.0.0-20220427111355-d3e91fbf2db5
|
||||
github.com/andygrunwald/go-gerrit v0.0.0-20230508072829-423d372345aa
|
||||
github.com/ben-clayton/webidlparser v0.0.0-20210923100217-8ba896ded094
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/google/go-cmp v0.5.6
|
||||
github.com/mattn/go-colorable v0.1.9
|
||||
github.com/mattn/go-isatty v0.0.14
|
||||
github.com/sergi/go-diff v1.2.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/mattn/go-colorable v0.1.12
|
||||
github.com/mattn/go-isatty v0.0.16
|
||||
github.com/sergi/go-diff v1.3.1
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/tidwall/jsonc v0.3.2
|
||||
go.chromium.org/luci v0.0.0-20220412023008-ab2409fe739a
|
||||
golang.org/x/net v0.0.0-20220403103023-749bd193bc2b
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
google.golang.org/api v0.63.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
go.chromium.org/luci v0.0.0-20230311013728-313c8e2205bc
|
||||
golang.org/x/net v0.8.0
|
||||
golang.org/x/oauth2 v0.6.0
|
||||
google.golang.org/api v0.112.0
|
||||
google.golang.org/grpc v1.53.0
|
||||
google.golang.org/protobuf v1.29.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.99.0 // indirect
|
||||
cloud.google.com/go/compute v1.18.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||
github.com/klauspost/compress v1.13.5 // indirect
|
||||
github.com/klauspost/compress v1.16.3 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/maruel/subcommands v1.1.0 // indirect
|
||||
github.com/maruel/subcommands v1.1.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/texttheater/golang-levenshtein v1.0.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8 // indirect
|
||||
google.golang.org/grpc v1.44.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/term v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
google.golang.org/appengine v1.6.8-0.20221117013220-504804fb50de // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
)
|
||||
|
||||
exclude github.com/sergi/go-diff v1.2.0
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright 2022 The Dawn & Tint Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
def go_path(input_api):
|
||||
go = input_api.os_path.join(input_api.change.RepositoryRoot(), "tools",
|
||||
"golang", "bin", "go")
|
||||
if input_api.is_windows:
|
||||
go += '.exe'
|
||||
|
||||
return go
|
||||
|
||||
|
||||
def RunGoTests(input_api, output_api):
|
||||
results = []
|
||||
try:
|
||||
input_api.subprocess.check_call_out(
|
||||
[go_path(input_api), "test", "./..."],
|
||||
stdout=input_api.subprocess.PIPE,
|
||||
stderr=input_api.subprocess.PIPE,
|
||||
cwd=input_api.PresubmitLocalPath())
|
||||
except input_api.subprocess.CalledProcessError as e:
|
||||
results.append(output_api.PresubmitError('%s' % (e, )))
|
||||
return results
|
|
@ -34,7 +34,6 @@ source_set("headers") {
|
|||
public_deps = [ ":headers_gen" ]
|
||||
|
||||
sources = get_target_outputs(":headers_gen")
|
||||
sources += [ "${dawn_root}/include/dawn/dawn_wsi.h" ]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
@ -45,6 +44,7 @@ dawn_json_generator("cpp_headers_gen") {
|
|||
target = "cpp_headers"
|
||||
outputs = [
|
||||
"include/dawn/webgpu_cpp.h",
|
||||
"include/dawn/webgpu_cpp_chained_struct.h",
|
||||
"include/dawn/webgpu_cpp_print.h",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ struct BoolConvertible {
|
|||
using Integral = typename std::underlying_type<T>::type;
|
||||
|
||||
// NOLINTNEXTLINE(runtime/explicit)
|
||||
constexpr BoolConvertible(Integral value) : value(value) {}
|
||||
explicit constexpr BoolConvertible(Integral value) : value(value) {}
|
||||
constexpr operator bool() const { return value != 0; }
|
||||
constexpr operator T() const { return static_cast<T>(value); }
|
||||
|
||||
|
@ -74,8 +74,8 @@ template <
|
|||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator|(T1 left, T2 right) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return static_cast<Integral>(LowerBitmask<T1>::Lower(left)) |
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right));
|
||||
return BoolConvertible<T>(static_cast<Integral>(LowerBitmask<T1>::Lower(left)) |
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right)));
|
||||
}
|
||||
|
||||
template <
|
||||
|
@ -85,8 +85,8 @@ template <
|
|||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator&(T1 left, T2 right) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return static_cast<Integral>(LowerBitmask<T1>::Lower(left)) &
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right));
|
||||
return BoolConvertible<T>(static_cast<Integral>(LowerBitmask<T1>::Lower(left)) &
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right)));
|
||||
}
|
||||
|
||||
template <
|
||||
|
@ -96,15 +96,15 @@ template <
|
|||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator^(T1 left, T2 right) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return static_cast<Integral>(LowerBitmask<T1>::Lower(left)) ^
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right));
|
||||
return BoolConvertible<T>(static_cast<Integral>(LowerBitmask<T1>::Lower(left)) ^
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right)));
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator~(T1 t) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return ~static_cast<Integral>(LowerBitmask<T1>::Lower(t));
|
||||
return BoolConvertible<T>(~static_cast<Integral>(LowerBitmask<T1>::Lower(t)));
|
||||
}
|
||||
|
||||
template <
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright 2017 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef INCLUDE_DAWN_DAWN_WSI_H_
|
||||
#define INCLUDE_DAWN_DAWN_WSI_H_
|
||||
|
||||
#include "dawn/webgpu.h"
|
||||
|
||||
// Error message (or nullptr if there was no error)
|
||||
typedef const char* DawnSwapChainError;
|
||||
constexpr DawnSwapChainError DAWN_SWAP_CHAIN_NO_ERROR = nullptr;
|
||||
constexpr DawnSwapChainError DAWN_SWAP_CHAIN_ERROR_OUT_OF_DATE = "Out of date";
|
||||
|
||||
typedef struct {
|
||||
/// Backend-specific texture id/name/pointer
|
||||
union {
|
||||
void* ptr;
|
||||
uint64_t u64;
|
||||
uint32_t u32;
|
||||
} texture;
|
||||
} DawnSwapChainNextTexture;
|
||||
|
||||
typedef struct {
|
||||
/// Initialize the swap chain implementation.
|
||||
/// (*wsiContext) is one of DawnWSIContext{D3D12,Metal,GL}
|
||||
void (*Init)(void* userData, void* wsiContext);
|
||||
|
||||
/// Destroy the swap chain implementation.
|
||||
void (*Destroy)(void* userData);
|
||||
|
||||
/// Configure/reconfigure the swap chain.
|
||||
DawnSwapChainError (*Configure)(void* userData,
|
||||
WGPUTextureFormat format,
|
||||
WGPUTextureUsage allowedUsage,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
/// Acquire the next texture from the swap chain.
|
||||
DawnSwapChainError (*GetNextTexture)(void* userData, DawnSwapChainNextTexture* nextTexture);
|
||||
|
||||
/// Present the last acquired texture to the screen.
|
||||
DawnSwapChainError (*Present)(void* userData);
|
||||
|
||||
/// Each function is called with userData as its first argument.
|
||||
void* userData;
|
||||
|
||||
/// For use by the D3D12 and Vulkan backends: how the swapchain will use the texture.
|
||||
WGPUTextureUsage textureUsage;
|
||||
} DawnSwapChainImplementation;
|
||||
|
||||
#if defined(DAWN_ENABLE_BACKEND_D3D12) && defined(__cplusplus)
|
||||
struct DawnWSIContextD3D12 {
|
||||
WGPUDevice device = nullptr;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(DAWN_ENABLE_BACKEND_METAL) && defined(__OBJC__)
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
struct DawnWSIContextMetal {
|
||||
id<MTLDevice> device = nil;
|
||||
id<MTLCommandQueue> queue = nil;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DAWN_ENABLE_BACKEND_OPENGL
|
||||
typedef struct {
|
||||
} DawnWSIContextGL;
|
||||
#endif
|
||||
|
||||
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||
typedef struct {
|
||||
} DawnWSIContextVulkan;
|
||||
#endif
|
||||
|
||||
#endif // INCLUDE_DAWN_DAWN_WSI_H_
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_
|
||||
#define INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_
|
||||
|
||||
#include <d3d11_1.h>
|
||||
#include <windows.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "dawn/native/D3DBackend.h"
|
||||
|
||||
namespace dawn::native::d3d11 {
|
||||
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions
|
||||
: public d3d::PhysicalDeviceDiscoveryOptions {
|
||||
PhysicalDeviceDiscoveryOptions();
|
||||
explicit PhysicalDeviceDiscoveryOptions(Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
|
||||
};
|
||||
|
||||
// TODO(dawn:1774): Deprecated.
|
||||
using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions;
|
||||
|
||||
DAWN_NATIVE_EXPORT Microsoft::WRL::ComPtr<ID3D11Device> GetD3D11Device(WGPUDevice device);
|
||||
|
||||
} // namespace dawn::native::d3d11
|
||||
|
||||
#endif // INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_
|
|
@ -20,25 +20,14 @@
|
|||
#include <windows.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "dawn/dawn_wsi.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
#include "dawn/native/D3DBackend.h"
|
||||
|
||||
struct ID3D12Device;
|
||||
struct ID3D12Resource;
|
||||
|
||||
namespace dawn::native::d3d12 {
|
||||
|
||||
class D3D11on12ResourceCache;
|
||||
class Device;
|
||||
class ExternalImageDXGIImpl;
|
||||
|
||||
DAWN_NATIVE_EXPORT Microsoft::WRL::ComPtr<ID3D12Device> GetD3D12Device(WGPUDevice device);
|
||||
DAWN_NATIVE_EXPORT DawnSwapChainImplementation CreateNativeSwapChainImpl(WGPUDevice device,
|
||||
HWND window);
|
||||
DAWN_NATIVE_EXPORT WGPUTextureFormat
|
||||
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);
|
||||
|
||||
enum MemorySegment {
|
||||
Local,
|
||||
|
@ -49,80 +38,14 @@ DAWN_NATIVE_EXPORT uint64_t SetExternalMemoryReservation(WGPUDevice device,
|
|||
uint64_t requestedReservationSize,
|
||||
MemorySegment memorySegment);
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
|
||||
public:
|
||||
ExternalImageDescriptorDXGISharedHandle();
|
||||
|
||||
// Note: SharedHandle must be a handle to a texture object.
|
||||
// TODO(dawn:576): Remove after changing Chromium code to set textureSharedHandle.
|
||||
HANDLE sharedHandle = nullptr;
|
||||
HANDLE textureSharedHandle = nullptr;
|
||||
|
||||
// Optional shared handle to a D3D11/12 fence which can be used to synchronize using wait/signal
|
||||
// values specified in the access descriptor below. If null, the texture will be assumed to have
|
||||
// an associated DXGI keyed mutex which will be used with a fixed key of 0 for synchronization.
|
||||
HANDLE fenceSharedHandle = nullptr;
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions
|
||||
: public d3d::PhysicalDeviceDiscoveryOptions {
|
||||
PhysicalDeviceDiscoveryOptions();
|
||||
explicit PhysicalDeviceDiscoveryOptions(Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
|
||||
};
|
||||
|
||||
// Keyed mutex acquire/release uses a fixed key of 0 to match Chromium behavior.
|
||||
constexpr UINT64 kDXGIKeyedMutexAcquireReleaseKey = 0;
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptorDXGISharedHandle
|
||||
: ExternalImageAccessDescriptor {
|
||||
public:
|
||||
// Value used for fence wait. A value of 0 is valid, but essentially a no-op since the fence
|
||||
// lifetime starts with the 0 value signaled. A value of UINT64_MAX is ignored since it's also
|
||||
// used by the D3D runtime to indicate that the device was removed.
|
||||
uint64_t fenceWaitValue = 0;
|
||||
|
||||
// Value to signal the fence with after the texture is destroyed. A value of 0 means the fence
|
||||
// will not be signaled.
|
||||
uint64_t fenceSignalValue = 0;
|
||||
|
||||
// Whether the texture is for a WebGPU swap chain.
|
||||
bool isSwapChainTexture = false;
|
||||
};
|
||||
|
||||
// TODO(dawn:576): Remove after changing Chromium code to use the new struct name.
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptorDXGIKeyedMutex
|
||||
: ExternalImageAccessDescriptorDXGISharedHandle {
|
||||
public:
|
||||
// TODO(chromium:1241533): Remove deprecated keyed mutex params after removing associated
|
||||
// code from Chromium - we use a fixed key of 0 for acquire and release everywhere now.
|
||||
uint64_t acquireMutexKey;
|
||||
uint64_t releaseMutexKey;
|
||||
};
|
||||
|
||||
class DAWN_NATIVE_EXPORT ExternalImageDXGI {
|
||||
public:
|
||||
~ExternalImageDXGI();
|
||||
|
||||
static std::unique_ptr<ExternalImageDXGI> Create(
|
||||
WGPUDevice device,
|
||||
const ExternalImageDescriptorDXGISharedHandle* descriptor);
|
||||
|
||||
// Returns true if the external image resources are still valid, otherwise ProduceTexture() is
|
||||
// guaranteed to fail e.g. after device destruction.
|
||||
bool IsValid() const;
|
||||
|
||||
// TODO(sunnyps): |device| is ignored - remove after Chromium migrates to single parameter call.
|
||||
WGPUTexture ProduceTexture(WGPUDevice device,
|
||||
const ExternalImageAccessDescriptorDXGISharedHandle* descriptor);
|
||||
|
||||
WGPUTexture ProduceTexture(const ExternalImageAccessDescriptorDXGISharedHandle* descriptor);
|
||||
|
||||
private:
|
||||
explicit ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl);
|
||||
|
||||
std::unique_ptr<ExternalImageDXGIImpl> mImpl;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
|
||||
AdapterDiscoveryOptions();
|
||||
explicit AdapterDiscoveryOptions(Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||
};
|
||||
// TODO(dawn:1774): Deprecated.
|
||||
using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions;
|
||||
|
||||
} // namespace dawn::native::d3d12
|
||||
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2023 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef INCLUDE_DAWN_NATIVE_D3DBACKEND_H_
|
||||
#define INCLUDE_DAWN_NATIVE_D3DBACKEND_H_
|
||||
|
||||
#include <dxgi1_4.h>
|
||||
#include <windows.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/native/DawnNative.h"
|
||||
|
||||
namespace dawn::native::d3d {
|
||||
|
||||
class ExternalImageDXGIImpl;
|
||||
|
||||
DAWN_NATIVE_EXPORT Microsoft::WRL::ComPtr<IDXGIAdapter> GetDXGIAdapter(WGPUAdapter adapter);
|
||||
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions
|
||||
: public PhysicalDeviceDiscoveryOptionsBase {
|
||||
PhysicalDeviceDiscoveryOptions(WGPUBackendType type,
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter);
|
||||
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||
};
|
||||
|
||||
// TODO(dawn:1774): Deprecated.
|
||||
using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions;
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
|
||||
public:
|
||||
ExternalImageDescriptorDXGISharedHandle();
|
||||
|
||||
// Note: SharedHandle must be a handle to a texture object.
|
||||
HANDLE sharedHandle = nullptr;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDXGIFenceDescriptor {
|
||||
// Shared handle for the fence. This never passes ownership to the callee (when used as an input
|
||||
// parameter) or to the caller (when used as a return value or output parameter).
|
||||
HANDLE fenceHandle = nullptr;
|
||||
|
||||
// The value that was previously signaled on this fence and should be waited on.
|
||||
uint64_t fenceValue = 0;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDXGIBeginAccessDescriptor {
|
||||
bool isInitialized = false; // Whether the texture is initialized on import
|
||||
WGPUTextureUsageFlags usage = WGPUTextureUsage_None;
|
||||
|
||||
// A list of fences to wait on before accessing the texture.
|
||||
std::vector<ExternalImageDXGIFenceDescriptor> waitFences;
|
||||
|
||||
// Whether the texture is for a WebGPU swap chain.
|
||||
bool isSwapChainTexture = false;
|
||||
};
|
||||
|
||||
class DAWN_NATIVE_EXPORT ExternalImageDXGI {
|
||||
public:
|
||||
~ExternalImageDXGI();
|
||||
|
||||
static std::unique_ptr<ExternalImageDXGI> Create(
|
||||
WGPUDevice device,
|
||||
const ExternalImageDescriptorDXGISharedHandle* descriptor);
|
||||
|
||||
// Returns true if the external image resources are still valid, otherwise BeginAccess() is
|
||||
// guaranteed to fail e.g. after device destruction.
|
||||
bool IsValid() const;
|
||||
|
||||
// Creates WGPUTexture wrapping the DXGI shared handle. The provided wait fences will be
|
||||
// synchronized before using the texture in any command lists. Empty fences (nullptr handle) are
|
||||
// ignored for convenience (EndAccess can return such fences).
|
||||
WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor);
|
||||
|
||||
// Returns the signalFence that the client must wait on for correct synchronization. Can return
|
||||
// an empty fence (nullptr handle) if the texture wasn't accessed by Dawn.
|
||||
// Note that merely calling Destroy() on the WGPUTexture does not ensure synchronization.
|
||||
void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence);
|
||||
|
||||
private:
|
||||
explicit ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl);
|
||||
|
||||
std::unique_ptr<ExternalImageDXGIImpl> mImpl;
|
||||
};
|
||||
|
||||
} // namespace dawn::native::d3d
|
||||
|
||||
#endif // INCLUDE_DAWN_NATIVE_D3DBACKEND_H_
|
|
@ -21,6 +21,7 @@
|
|||
#include "dawn/dawn_proc_table.h"
|
||||
#include "dawn/native/dawn_native_export.h"
|
||||
#include "dawn/webgpu.h"
|
||||
#include "dawn/webgpu_cpp_chained_struct.h"
|
||||
|
||||
namespace dawn::platform {
|
||||
class Platform;
|
||||
|
@ -36,18 +37,9 @@ namespace dawn::native {
|
|||
class InstanceBase;
|
||||
class AdapterBase;
|
||||
|
||||
// An optional parameter of Adapter::CreateDevice() to send additional information when creating
|
||||
// a Device. For example, we can use it to enable a workaround, optimization or feature.
|
||||
struct DAWN_NATIVE_EXPORT DawnDeviceDescriptor {
|
||||
DawnDeviceDescriptor();
|
||||
~DawnDeviceDescriptor();
|
||||
|
||||
std::vector<const char*> requiredFeatures;
|
||||
std::vector<const char*> forceEnabledToggles;
|
||||
std::vector<const char*> forceDisabledToggles;
|
||||
|
||||
const WGPURequiredLimits* requiredLimits = nullptr;
|
||||
};
|
||||
// Each toggle is assigned with a TogglesStage, indicating the validation and earliest usage
|
||||
// time of the toggle.
|
||||
enum class ToggleStage { Instance, Adapter, Device };
|
||||
|
||||
// A struct to record the information of a toggle. A toggle is a code path in Dawn device that
|
||||
// can be manually configured to run or not outside Dawn, including workarounds, special
|
||||
|
@ -56,12 +48,21 @@ struct ToggleInfo {
|
|||
const char* name;
|
||||
const char* description;
|
||||
const char* url;
|
||||
ToggleStage stage;
|
||||
};
|
||||
|
||||
// A struct to record the information of a feature. A feature is a GPU feature that is not
|
||||
// required to be supported by all Dawn backends and can only be used when it is enabled on the
|
||||
// creation of device.
|
||||
using FeatureInfo = ToggleInfo;
|
||||
struct FeatureInfo {
|
||||
const char* name;
|
||||
const char* description;
|
||||
const char* url;
|
||||
// The enum of feature state, could be stable or experimental. Using an experimental feature
|
||||
// requires the AllowUnsafeAPIs toggle to be enabled.
|
||||
enum class FeatureState { Stable = 0, Experimental };
|
||||
FeatureState featureState;
|
||||
};
|
||||
|
||||
// An adapter is an object that represent on possibility of creating devices in the system.
|
||||
// Most of the time it will represent a combination of a physical GPU and an API. Not that the
|
||||
|
@ -97,13 +98,9 @@ class DAWN_NATIVE_EXPORT Adapter {
|
|||
explicit operator bool() const;
|
||||
|
||||
// Create a device on this adapter. On an error, nullptr is returned.
|
||||
WGPUDevice CreateDevice(const DawnDeviceDescriptor* deviceDescriptor);
|
||||
WGPUDevice CreateDevice(const wgpu::DeviceDescriptor* deviceDescriptor);
|
||||
WGPUDevice CreateDevice(const WGPUDeviceDescriptor* deviceDescriptor = nullptr);
|
||||
|
||||
void RequestDevice(const DawnDeviceDescriptor* descriptor,
|
||||
WGPURequestDeviceCallback callback,
|
||||
void* userdata);
|
||||
void RequestDevice(const wgpu::DeviceDescriptor* descriptor,
|
||||
WGPURequestDeviceCallback callback,
|
||||
void* userdata);
|
||||
|
@ -121,17 +118,35 @@ class DAWN_NATIVE_EXPORT Adapter {
|
|||
AdapterBase* mImpl = nullptr;
|
||||
};
|
||||
|
||||
// Base class for options passed to Instance::DiscoverAdapters.
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsBase {
|
||||
// Base class for options passed to Instance::DiscoverPhysicalDevices.
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptionsBase {
|
||||
public:
|
||||
const WGPUBackendType backendType;
|
||||
|
||||
protected:
|
||||
explicit AdapterDiscoveryOptionsBase(WGPUBackendType type);
|
||||
explicit PhysicalDeviceDiscoveryOptionsBase(WGPUBackendType type);
|
||||
};
|
||||
|
||||
// Deprecated, use PhysicalDeviceDiscoveryOptionsBase instead.
|
||||
// TODO(dawn:1774): Remove this.
|
||||
using AdapterDiscoveryOptionsBase = PhysicalDeviceDiscoveryOptionsBase;
|
||||
|
||||
enum BackendValidationLevel { Full, Partial, Disabled };
|
||||
|
||||
// Can be chained in InstanceDescriptor
|
||||
struct DAWN_NATIVE_EXPORT DawnInstanceDescriptor : wgpu::ChainedStruct {
|
||||
DawnInstanceDescriptor();
|
||||
static constexpr size_t kFirstMemberAlignment =
|
||||
wgpu::detail::ConstexprMax(alignof(wgpu::ChainedStruct), alignof(uint32_t));
|
||||
alignas(kFirstMemberAlignment) uint32_t additionalRuntimeSearchPathsCount = 0;
|
||||
const char* const* additionalRuntimeSearchPaths;
|
||||
dawn::platform::Platform* platform = nullptr;
|
||||
|
||||
// Equality operators, mostly for testing. Note that this tests
|
||||
// strict pointer-pointer equality if the struct contains member pointers.
|
||||
bool operator==(const DawnInstanceDescriptor& rhs) const;
|
||||
};
|
||||
|
||||
// Represents a connection to dawn_native and is used for dependency injection, discovering
|
||||
// system adapters and injecting custom adapters (like a Swiftshader Vulkan adapter).
|
||||
//
|
||||
|
@ -145,15 +160,20 @@ class DAWN_NATIVE_EXPORT Instance {
|
|||
Instance(const Instance& other) = delete;
|
||||
Instance& operator=(const Instance& other) = delete;
|
||||
|
||||
// Gather all adapters in the system that can be accessed with no special options. These
|
||||
// adapters will later be returned by GetAdapters.
|
||||
void DiscoverDefaultAdapters();
|
||||
// Gather all physical devices in the system that can be accessed with no special options.
|
||||
void DiscoverDefaultPhysicalDevices();
|
||||
|
||||
// Adds adapters that can be discovered with the options provided (like a getProcAddress).
|
||||
// The backend is chosen based on the type of the options used. Returns true on success.
|
||||
// Adds physical devices that can be discovered with the options provided (like a
|
||||
// getProcAddress). The backend is chosen based on the type of the options used. Returns true on
|
||||
// success.
|
||||
bool DiscoverPhysicalDevices(const PhysicalDeviceDiscoveryOptionsBase* options);
|
||||
|
||||
// Deprecated, use DiscoverDefaultPhysicalDevices and DiscoverPhysicalDevices instead.
|
||||
// TODO(Dawn:1774): Remove these.
|
||||
void DiscoverDefaultAdapters();
|
||||
bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
// Returns all the adapters that the instance knows about.
|
||||
// Returns a vector of adapters, one for each physical device the instance knows about.
|
||||
std::vector<Adapter> GetAdapters() const;
|
||||
|
||||
const ToggleInfo* GetToggleInfo(const char* toggleName);
|
||||
|
@ -166,8 +186,8 @@ class DAWN_NATIVE_EXPORT Instance {
|
|||
// Enable debug capture on Dawn startup
|
||||
void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup);
|
||||
|
||||
// TODO(dawn:1374) Deprecate this once it is passed via the descriptor.
|
||||
void SetPlatform(dawn::platform::Platform* platform);
|
||||
// Enable / disable the adapter blocklist.
|
||||
void EnableAdapterBlocklist(bool enable);
|
||||
|
||||
uint64_t GetDeviceCountForTesting() const;
|
||||
|
||||
|
@ -207,6 +227,8 @@ DAWN_NATIVE_EXPORT std::vector<const char*> GetProcMapNamesForTesting();
|
|||
|
||||
DAWN_NATIVE_EXPORT bool DeviceTick(WGPUDevice device);
|
||||
|
||||
DAWN_NATIVE_EXPORT bool InstanceProcessEvents(WGPUInstance instance);
|
||||
|
||||
// ErrorInjector functions used for testing only. Defined in dawn_native/ErrorInjector.cpp
|
||||
DAWN_NATIVE_EXPORT void EnableErrorInjector();
|
||||
DAWN_NATIVE_EXPORT void DisableErrorInjector();
|
||||
|
@ -221,6 +243,7 @@ enum ExternalImageType {
|
|||
IOSurface,
|
||||
DXGISharedHandle,
|
||||
EGLImage,
|
||||
AHardwareBuffer,
|
||||
};
|
||||
|
||||
// Common properties of external images
|
||||
|
@ -237,12 +260,6 @@ struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
|
|||
ExternalImageType mType;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptor {
|
||||
public:
|
||||
bool isInitialized = false; // Whether the texture is initialized on import
|
||||
WGPUTextureUsageFlags usage = WGPUTextureUsage_None;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfo {
|
||||
public:
|
||||
bool isInitialized = false; // Whether the texture is initialized after export
|
||||
|
@ -266,6 +283,12 @@ DAWN_NATIVE_EXPORT bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayo
|
|||
|
||||
} // namespace dawn::native
|
||||
|
||||
// Alias the DawnInstanceDescriptor up to wgpu.
|
||||
// TODO(dawn:1374) Remove this aliasing once the usages are updated.
|
||||
namespace wgpu {
|
||||
using dawn::native::DawnInstanceDescriptor;
|
||||
} // namespace wgpu
|
||||
|
||||
// TODO(dawn:824): Remove once the deprecation period is passed.
|
||||
namespace dawn_native = dawn::native;
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
#ifndef INCLUDE_DAWN_NATIVE_METALBACKEND_H_
|
||||
#define INCLUDE_DAWN_NATIVE_METALBACKEND_H_
|
||||
|
||||
#include "dawn/dawn_wsi.h"
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/native/DawnNative.h"
|
||||
|
||||
// The specifics of the Metal backend expose types in function signatures that might not be
|
||||
|
@ -34,23 +35,52 @@ typedef __IOSurface* IOSurfaceRef;
|
|||
|
||||
namespace dawn::native::metal {
|
||||
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
|
||||
AdapterDiscoveryOptions();
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions
|
||||
: public PhysicalDeviceDiscoveryOptionsBase {
|
||||
PhysicalDeviceDiscoveryOptions();
|
||||
};
|
||||
|
||||
// TODO(dawn:1774): Deprecated.
|
||||
using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions;
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageMTLSharedEventDescriptor {
|
||||
// Shared event handle `id<MTLSharedEvent>`.
|
||||
// This never passes ownership to the callee (when used as an input
|
||||
// parameter) or to the caller (when used as a return value or output parameter).
|
||||
#ifdef __OBJC__
|
||||
id<MTLSharedEvent> sharedEvent = nil;
|
||||
static_assert(sizeof(id<MTLSharedEvent>) == sizeof(void*));
|
||||
static_assert(alignof(id<MTLSharedEvent>) == alignof(void*));
|
||||
#else
|
||||
void* sharedEvent = nullptr;
|
||||
#endif
|
||||
|
||||
// The value that was previously signaled on this event and should be waited on.
|
||||
uint64_t signaledValue = 0;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorIOSurface : ExternalImageDescriptor {
|
||||
public:
|
||||
ExternalImageDescriptorIOSurface();
|
||||
~ExternalImageDescriptorIOSurface();
|
||||
|
||||
IOSurfaceRef ioSurface;
|
||||
|
||||
// This has been deprecated.
|
||||
uint32_t plane;
|
||||
// A list of events to wait on before accessing the texture.
|
||||
std::vector<ExternalImageMTLSharedEventDescriptor> waitEvents;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageIOSurfaceEndAccessDescriptor
|
||||
: ExternalImageMTLSharedEventDescriptor {
|
||||
bool isInitialized;
|
||||
};
|
||||
|
||||
DAWN_NATIVE_EXPORT WGPUTexture WrapIOSurface(WGPUDevice device,
|
||||
const ExternalImageDescriptorIOSurface* descriptor);
|
||||
|
||||
DAWN_NATIVE_EXPORT void IOSurfaceEndAccess(WGPUTexture texture,
|
||||
ExternalImageIOSurfaceEndAccessDescriptor* descriptor);
|
||||
|
||||
// When making Metal interop with other APIs, we need to be careful that QueueSubmit doesn't
|
||||
// mean that the operations will be visible to other APIs/Metal devices right away. macOS
|
||||
// does have a global queue of graphics operations, but the command buffers are inserted there
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
#ifndef INCLUDE_DAWN_NATIVE_NULLBACKEND_H_
|
||||
#define INCLUDE_DAWN_NATIVE_NULLBACKEND_H_
|
||||
|
||||
#include "dawn/dawn_wsi.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
|
||||
namespace dawn::native::null {
|
||||
DAWN_NATIVE_EXPORT DawnSwapChainImplementation CreateNativeSwapChainImpl();
|
||||
|
||||
// Nothing for now \o/
|
||||
|
||||
} // namespace dawn::native::null
|
||||
|
||||
#endif // INCLUDE_DAWN_NATIVE_NULLBACKEND_H_
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
typedef void* EGLImage;
|
||||
|
||||
#include "dawn/dawn_wsi.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
|
||||
namespace dawn::native::opengl {
|
||||
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
|
||||
explicit AdapterDiscoveryOptions(WGPUBackendType type);
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions
|
||||
: public PhysicalDeviceDiscoveryOptionsBase {
|
||||
explicit PhysicalDeviceDiscoveryOptions(WGPUBackendType type);
|
||||
|
||||
void* (*getProc)(const char*);
|
||||
// Context
|
||||
|
@ -32,18 +32,14 @@ struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptio
|
|||
void* userData;
|
||||
};
|
||||
|
||||
// TODO(dawn:1774): Deprecated.
|
||||
using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions;
|
||||
|
||||
// TODO(crbug.com/dawn/810): This struct can be removed once Chrome is no longer using it.
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsES : public AdapterDiscoveryOptions {
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsES : public PhysicalDeviceDiscoveryOptions {
|
||||
AdapterDiscoveryOptionsES();
|
||||
};
|
||||
|
||||
using PresentCallback = void (*)(void*);
|
||||
DAWN_NATIVE_EXPORT DawnSwapChainImplementation CreateNativeSwapChainImpl(WGPUDevice device,
|
||||
PresentCallback present,
|
||||
void* presentUserdata);
|
||||
DAWN_NATIVE_EXPORT WGPUTextureFormat
|
||||
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorEGLImage : ExternalImageDescriptor {
|
||||
public:
|
||||
ExternalImageDescriptorEGLImage();
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/dawn_wsi.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
|
||||
namespace dawn::native::vulkan {
|
||||
|
@ -29,17 +28,23 @@ DAWN_NATIVE_EXPORT VkInstance GetInstance(WGPUDevice device);
|
|||
|
||||
DAWN_NATIVE_EXPORT PFN_vkVoidFunction GetInstanceProcAddr(WGPUDevice device, const char* pName);
|
||||
|
||||
DAWN_NATIVE_EXPORT DawnSwapChainImplementation CreateNativeSwapChainImpl(WGPUDevice device,
|
||||
::VkSurfaceKHR surface);
|
||||
DAWN_NATIVE_EXPORT WGPUTextureFormat
|
||||
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);
|
||||
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
|
||||
AdapterDiscoveryOptions();
|
||||
struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions
|
||||
: public PhysicalDeviceDiscoveryOptionsBase {
|
||||
PhysicalDeviceDiscoveryOptions();
|
||||
|
||||
bool forceSwiftShader = false;
|
||||
};
|
||||
|
||||
// TODO(dawn:1774): Deprecated.
|
||||
using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions;
|
||||
|
||||
enum class NeedsDedicatedAllocation {
|
||||
Yes,
|
||||
No,
|
||||
// Use Vulkan reflection to detect whether a dedicated allocation is needed.
|
||||
Detect,
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorVk : ExternalImageDescriptor {
|
||||
public:
|
||||
// The following members may be ignored if |ExternalImageDescriptor::isInitialized| is false
|
||||
|
@ -54,6 +59,11 @@ struct DAWN_NATIVE_EXPORT ExternalImageDescriptorVk : ExternalImageDescriptor {
|
|||
VkImageLayout releasedOldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
VkImageLayout releasedNewLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
// Try to detect the need to use a dedicated allocation for imported images by default but let
|
||||
// the application override this as drivers have bugs and forget to require a dedicated
|
||||
// allocation.
|
||||
NeedsDedicatedAllocation dedicatedAllocation = NeedsDedicatedAllocation::Detect;
|
||||
|
||||
protected:
|
||||
using ExternalImageDescriptor::ExternalImageDescriptor;
|
||||
};
|
||||
|
@ -126,6 +136,26 @@ struct DAWN_NATIVE_EXPORT ExternalImageExportInfoDmaBuf : ExternalImageExportInf
|
|||
ExternalImageExportInfoDmaBuf();
|
||||
};
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
// Descriptor for AHardwareBuffer image import
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorAHardwareBuffer : ExternalImageDescriptorVk {
|
||||
public:
|
||||
ExternalImageDescriptorAHardwareBuffer();
|
||||
|
||||
struct AHardwareBuffer* handle; // The AHardwareBuffer which contains the memory of the image
|
||||
std::vector<int> waitFDs; // File descriptors of semaphores which will be waited on
|
||||
|
||||
protected:
|
||||
using ExternalImageDescriptorVk::ExternalImageDescriptorVk;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoAHardwareBuffer : ExternalImageExportInfoFD {
|
||||
ExternalImageExportInfoAHardwareBuffer();
|
||||
};
|
||||
|
||||
#endif // __ANDROID__
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
// Imports external memory into a Vulkan image. Internally, this uses external memory /
|
||||
|
@ -142,6 +172,8 @@ DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice device,
|
|||
DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture,
|
||||
VkImageLayout desiredLayout,
|
||||
ExternalImageExportInfoVk* info);
|
||||
// |ExportVulkanImage| with default desiredLayout of VK_IMAGE_LAYOUT_UNDEFINED.
|
||||
DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture, ExternalImageExportInfoVk* info);
|
||||
|
||||
} // namespace dawn::native::vulkan
|
||||
|
||||
|
|
|
@ -70,9 +70,9 @@ class DAWN_WIRE_EXPORT WireClient : public CommandHandler {
|
|||
|
||||
const volatile char* HandleCommands(const volatile char* commands, size_t size) override;
|
||||
|
||||
ReservedTexture ReserveTexture(WGPUDevice device,
|
||||
const WGPUTextureDescriptor* descriptor);
|
||||
ReservedSwapChain ReserveSwapChain(WGPUDevice device);
|
||||
ReservedTexture ReserveTexture(WGPUDevice device, const WGPUTextureDescriptor* descriptor);
|
||||
ReservedSwapChain ReserveSwapChain(WGPUDevice device,
|
||||
const WGPUSwapChainDescriptor* descriptor);
|
||||
ReservedDevice ReserveDevice();
|
||||
ReservedInstance ReserveInstance();
|
||||
|
||||
|
|
|
@ -16,12 +16,18 @@
|
|||
#define SRC_TINT_OVERRIDE_ID_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
|
||||
#include "src/tint/reflection.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// OverrideId is a numerical identifier for an override variable, unique per program.
|
||||
struct OverrideId {
|
||||
uint16_t value = 0;
|
||||
|
||||
/// Reflect the fields of this struct so that it can be used by tint::ForeachField()
|
||||
TINT_REFLECT(value);
|
||||
};
|
||||
|
||||
/// Equality operator for OverrideId
|
||||
|
|
|
@ -15,24 +15,27 @@
|
|||
#ifndef INCLUDE_TINT_TINT_H_
|
||||
#define INCLUDE_TINT_TINT_H_
|
||||
|
||||
// Guard for accidental includes to private headers
|
||||
#define CURRENTLY_IN_TINT_PUBLIC_HEADER
|
||||
|
||||
// TODO(tint:88): When implementing support for an install target, all of these
|
||||
// headers will need to be moved to include/tint/.
|
||||
|
||||
#include "src/tint/demangler.h"
|
||||
#include "src/tint/ast/transform/first_index_offset.h"
|
||||
#include "src/tint/ast/transform/renamer.h"
|
||||
#include "src/tint/ast/transform/single_entry_point.h"
|
||||
#include "src/tint/ast/transform/substitute_override.h"
|
||||
#include "src/tint/ast/transform/vertex_pulling.h"
|
||||
#include "src/tint/diagnostic/printer.h"
|
||||
#include "src/tint/inspector/inspector.h"
|
||||
#include "src/tint/reader/reader.h"
|
||||
#include "src/tint/sem/type_manager.h"
|
||||
#include "src/tint/transform/binding_remapper.h"
|
||||
#include "src/tint/transform/first_index_offset.h"
|
||||
#include "src/tint/transform/fold_trivial_single_use_lets.h"
|
||||
#include "src/tint/transform/manager.h"
|
||||
#include "src/tint/transform/multiplanar_external_texture.h"
|
||||
#include "src/tint/transform/renamer.h"
|
||||
#include "src/tint/transform/robustness.h"
|
||||
#include "src/tint/transform/single_entry_point.h"
|
||||
#include "src/tint/transform/substitute_override.h"
|
||||
#include "src/tint/transform/vertex_pulling.h"
|
||||
#include "src/tint/type/manager.h"
|
||||
#include "src/tint/utils/unicode.h"
|
||||
#include "src/tint/writer/array_length_from_uniform_options.h"
|
||||
#include "src/tint/writer/binding_point.h"
|
||||
#include "src/tint/writer/binding_remapper_options.h"
|
||||
#include "src/tint/writer/external_texture_options.h"
|
||||
#include "src/tint/writer/flatten_bindings.h"
|
||||
#include "src/tint/writer/writer.h"
|
||||
|
||||
|
@ -45,7 +48,6 @@
|
|||
#endif // TINT_BUILD_WGSL_READER
|
||||
|
||||
#if TINT_BUILD_SPV_WRITER
|
||||
#include "spirv-tools/libspirv.hpp"
|
||||
#include "src/tint/writer/spirv/generator.h"
|
||||
#endif // TINT_BUILD_SPV_WRITER
|
||||
|
||||
|
@ -65,4 +67,16 @@
|
|||
#include "src/tint/writer/glsl/generator.h"
|
||||
#endif // TINT_BUILD_GLSL_WRITER
|
||||
|
||||
namespace tint {
|
||||
|
||||
/// Initialize initializes the Tint library. Call before using the Tint API.
|
||||
void Initialize();
|
||||
|
||||
/// Shutdown uninitializes the Tint library. Call after using the Tint API.
|
||||
void Shutdown();
|
||||
|
||||
} // namespace tint
|
||||
|
||||
#undef CURRENTLY_IN_TINT_PUBLIC_HEADER
|
||||
|
||||
#endif // INCLUDE_TINT_TINT_H_
|
||||
|
|
|
@ -18,6 +18,9 @@ config_groups {
|
|||
projects {
|
||||
name: "dawn"
|
||||
ref_regexp: "refs/heads/.+"
|
||||
ref_regexp_exclude: "refs/heads/chromium/5615"
|
||||
ref_regexp_exclude: "refs/heads/chromium/5672"
|
||||
ref_regexp_exclude: "refs/heads/chromium/5735"
|
||||
}
|
||||
}
|
||||
verifiers {
|
||||
|
@ -26,6 +29,12 @@ config_groups {
|
|||
dry_run_access_list: "project-dawn-tryjob-access"
|
||||
}
|
||||
tryjob {
|
||||
builders {
|
||||
name: "chromium/try/android-dawn-arm-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium/try/android-dawn-arm64-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium/try/dawn-try-win10-x86-rel"
|
||||
includable_only: true
|
||||
|
@ -89,3 +98,243 @@ config_groups {
|
|||
}
|
||||
}
|
||||
}
|
||||
config_groups {
|
||||
name: "Dawn-CQ-m112"
|
||||
gerrit {
|
||||
url: "https://dawn-review.googlesource.com"
|
||||
projects {
|
||||
name: "dawn"
|
||||
ref_regexp: "refs/heads/chromium/5615"
|
||||
}
|
||||
}
|
||||
verifiers {
|
||||
gerrit_cq_ability {
|
||||
committer_list: "project-dawn-committers"
|
||||
dry_run_access_list: "project-dawn-tryjob-access"
|
||||
}
|
||||
tryjob {
|
||||
builders {
|
||||
name: "chromium-m112/try/dawn-android-arm-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m112/try/dawn-mac-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m112/try/dawn-win10-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m112/try/dawn-win10-x86-deps-rel"
|
||||
includable_only: true
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-dbg-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-rel-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-rel-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/mac-dbg"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/mac-rel"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/presubmit"
|
||||
disable_reuse: true
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-dbg-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-rel-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-rel-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-msvc-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-msvc-rel-x64"
|
||||
}
|
||||
retry_config {
|
||||
single_quota: 1
|
||||
global_quota: 2
|
||||
failure_weight: 1
|
||||
transient_failure_weight: 1
|
||||
timeout_weight: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
config_groups {
|
||||
name: "Dawn-CQ-m113"
|
||||
gerrit {
|
||||
url: "https://dawn-review.googlesource.com"
|
||||
projects {
|
||||
name: "dawn"
|
||||
ref_regexp: "refs/heads/chromium/5672"
|
||||
}
|
||||
}
|
||||
verifiers {
|
||||
gerrit_cq_ability {
|
||||
committer_list: "project-dawn-committers"
|
||||
dry_run_access_list: "project-dawn-tryjob-access"
|
||||
}
|
||||
tryjob {
|
||||
builders {
|
||||
name: "chromium-m113/try/dawn-android-arm-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m113/try/dawn-linux-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m113/try/dawn-mac-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m113/try/dawn-win10-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m113/try/dawn-win10-x86-deps-rel"
|
||||
includable_only: true
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-dbg-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-rel-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-rel-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/mac-dbg"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/mac-rel"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/presubmit"
|
||||
disable_reuse: true
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-dbg-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-rel-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-rel-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-msvc-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-msvc-rel-x64"
|
||||
}
|
||||
retry_config {
|
||||
single_quota: 1
|
||||
global_quota: 2
|
||||
failure_weight: 1
|
||||
transient_failure_weight: 1
|
||||
timeout_weight: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
config_groups {
|
||||
name: "Dawn-CQ-m114"
|
||||
gerrit {
|
||||
url: "https://dawn-review.googlesource.com"
|
||||
projects {
|
||||
name: "dawn"
|
||||
ref_regexp: "refs/heads/chromium/5735"
|
||||
}
|
||||
}
|
||||
verifiers {
|
||||
gerrit_cq_ability {
|
||||
committer_list: "project-dawn-committers"
|
||||
dry_run_access_list: "project-dawn-tryjob-access"
|
||||
}
|
||||
tryjob {
|
||||
builders {
|
||||
name: "chromium-m114/try/dawn-android-arm-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m114/try/dawn-linux-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m114/try/dawn-mac-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m114/try/dawn-win10-x64-deps-rel"
|
||||
}
|
||||
builders {
|
||||
name: "chromium-m114/try/dawn-win10-x86-deps-rel"
|
||||
includable_only: true
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-dbg-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-rel-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/linux-clang-rel-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/mac-dbg"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/mac-rel"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/presubmit"
|
||||
disable_reuse: true
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-dbg-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-rel-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-clang-rel-x86"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-msvc-dbg-x64"
|
||||
}
|
||||
builders {
|
||||
name: "dawn/try/win-msvc-rel-x64"
|
||||
}
|
||||
retry_config {
|
||||
single_quota: 1
|
||||
global_quota: 2
|
||||
failure_weight: 1
|
||||
transient_failure_weight: 1
|
||||
timeout_weight: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-dbg-x64"
|
||||
|
@ -48,10 +44,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-dbg-x86"
|
||||
|
@ -69,10 +61,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x86\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-rel-x64"
|
||||
|
@ -90,10 +78,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-rel-x86"
|
||||
|
@ -111,10 +95,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x86\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "mac-dbg"
|
||||
|
@ -136,10 +116,6 @@ buckets {
|
|||
path: "osx_sdk"
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "mac-rel"
|
||||
|
@ -161,10 +137,6 @@ buckets {
|
|||
path: "osx_sdk"
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-dbg-x64"
|
||||
|
@ -186,10 +158,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-dbg-x86"
|
||||
|
@ -211,10 +179,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-rel-x64"
|
||||
|
@ -236,10 +200,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-rel-x86"
|
||||
|
@ -261,10 +221,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-msvc-dbg-x64"
|
||||
|
@ -281,10 +237,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-msvc-rel-x64"
|
||||
|
@ -301,10 +253,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,10 +287,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-dbg-x86"
|
||||
|
@ -361,10 +305,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x86\""
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-rel-x64"
|
||||
|
@ -383,10 +323,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "linux-clang-rel-x86"
|
||||
|
@ -405,10 +341,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x86\""
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "mac-dbg"
|
||||
|
@ -431,10 +363,6 @@ buckets {
|
|||
path: "osx_sdk"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "mac-rel"
|
||||
|
@ -457,10 +385,6 @@ buckets {
|
|||
path: "osx_sdk"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "presubmit"
|
||||
|
@ -477,10 +401,6 @@ buckets {
|
|||
properties_j: "runhooks:true"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-dbg-x64"
|
||||
|
@ -503,10 +423,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-dbg-x86"
|
||||
|
@ -529,10 +445,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-rel-x64"
|
||||
|
@ -555,10 +467,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-clang-rel-x86"
|
||||
|
@ -581,10 +489,6 @@ buckets {
|
|||
path: "win_toolchain"
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-msvc-dbg-x64"
|
||||
|
@ -602,10 +506,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
builders {
|
||||
name: "win-msvc-rel-x64"
|
||||
|
@ -623,10 +523,6 @@ buckets {
|
|||
properties_j: "target_cpu:\"x64\""
|
||||
}
|
||||
service_account: "dawn-try-builder@chops-service-accounts.iam.gserviceaccount.com"
|
||||
experiments {
|
||||
key: "luci.recipes.use_python3"
|
||||
value: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
name: "dawn"
|
||||
access: "group:all"
|
||||
lucicfg {
|
||||
version: "1.31.3"
|
||||
version: "1.39.8"
|
||||
package_dir: ".."
|
||||
config_dir: "generated"
|
||||
entry_point: "main.star"
|
||||
|
|
|
@ -8,13 +8,11 @@
|
|||
main.star: lucicfg configuration for Dawn's standalone builers.
|
||||
"""
|
||||
|
||||
load("//project.star", "ACTIVE_MILESTONES")
|
||||
|
||||
# Use LUCI Scheduler BBv2 names and add Scheduler realms configs.
|
||||
lucicfg.enable_experiment("crbug.com/1182002")
|
||||
|
||||
luci.builder.defaults.experiments.set({
|
||||
"luci.recipes.use_python3": 100,
|
||||
})
|
||||
|
||||
lucicfg.config(fail_on_warnings = True)
|
||||
|
||||
luci.project(
|
||||
|
@ -349,16 +347,69 @@ def dawn_standalone_builder(name, clang, debug, cpu, fuzzer = False):
|
|||
builder = "dawn:try/" + name,
|
||||
)
|
||||
|
||||
def chromium_dawn_tryjob(os):
|
||||
# These builders run fine unbranched on branch CLs, so add them to the
|
||||
# branch groups as well.
|
||||
for milestone in ACTIVE_MILESTONES.keys():
|
||||
luci.cq_tryjob_verifier(
|
||||
cq_group = "Dawn-CQ-" + milestone,
|
||||
builder = "dawn:try/" + name,
|
||||
)
|
||||
|
||||
def _add_branch_verifiers(builder_name, os, min_milestone = None, includable_only = False):
|
||||
for milestone, details in ACTIVE_MILESTONES.items():
|
||||
if os not in details.platforms:
|
||||
continue
|
||||
if min_milestone != None and int(milestone[1:]) < min_milestone:
|
||||
continue
|
||||
luci.cq_tryjob_verifier(
|
||||
cq_group = "Dawn-CQ-" + milestone,
|
||||
builder = "{}:try/{}".format(details.chromium_project, builder_name),
|
||||
includable_only = includable_only,
|
||||
)
|
||||
|
||||
# We use the DEPS version for branches because ToT builders do not make sense on
|
||||
# branches and the DEPS versions already exist.
|
||||
_os_arch_to_branch_builder = {
|
||||
"linux": "dawn-linux-x64-deps-rel",
|
||||
"mac": "dawn-mac-x64-deps-rel",
|
||||
"win": "dawn-win10-x64-deps-rel",
|
||||
"android-arm": "dawn-android-arm-deps-rel",
|
||||
"android-arm64": "dawn-android-arm64-deps-rel",
|
||||
}
|
||||
|
||||
# The earliest milestone that the builder is relevant for
|
||||
_os_arch_to_min_milestone = {
|
||||
"linux": 112,
|
||||
"mac": 112,
|
||||
"win": 112,
|
||||
"android-arm": 112,
|
||||
"android-arm64": 115,
|
||||
}
|
||||
|
||||
def chromium_dawn_tryjob(os, arch = None):
|
||||
"""Adds a tryjob that tests against Chromium
|
||||
|
||||
Args:
|
||||
os: string for the OS, should be one or linux|mac|win
|
||||
arch: string for the arch, or None
|
||||
"""
|
||||
luci.cq_tryjob_verifier(
|
||||
cq_group = "Dawn-CQ",
|
||||
builder = "chromium:try/" + os + "-dawn-rel",
|
||||
)
|
||||
|
||||
if arch:
|
||||
luci.cq_tryjob_verifier(
|
||||
cq_group = "Dawn-CQ",
|
||||
builder = "chromium:try/{os}-dawn-{arch}-rel".format(os = os, arch = arch),
|
||||
)
|
||||
_add_branch_verifiers(
|
||||
_os_arch_to_branch_builder["{os}-{arch}".format(os = os, arch = arch)],
|
||||
os,
|
||||
_os_arch_to_min_milestone["{os}-{arch}".format(os = os, arch = arch)],
|
||||
)
|
||||
else:
|
||||
luci.cq_tryjob_verifier(
|
||||
cq_group = "Dawn-CQ",
|
||||
builder = "chromium:try/{}-dawn-rel".format(os),
|
||||
)
|
||||
_add_branch_verifiers(_os_arch_to_branch_builder[os], os)
|
||||
|
||||
luci.gitiles_poller(
|
||||
name = "primary-poller",
|
||||
|
@ -411,12 +462,15 @@ dawn_standalone_builder("cron-linux-clang-rel-x64", True, False, "x64", True)
|
|||
chromium_dawn_tryjob("linux")
|
||||
chromium_dawn_tryjob("mac")
|
||||
chromium_dawn_tryjob("win")
|
||||
chromium_dawn_tryjob("android", "arm")
|
||||
chromium_dawn_tryjob("android", "arm64")
|
||||
|
||||
luci.cq_tryjob_verifier(
|
||||
cq_group = "Dawn-CQ",
|
||||
builder = "chromium:try/dawn-try-win10-x86-rel",
|
||||
includable_only = True,
|
||||
)
|
||||
_add_branch_verifiers("dawn-win10-x86-deps-rel", "win", includable_only = True)
|
||||
|
||||
# Views
|
||||
|
||||
|
@ -444,33 +498,49 @@ luci.cq(
|
|||
submit_burst_delay = 480 * time.second,
|
||||
)
|
||||
|
||||
luci.cq_group(
|
||||
name = "Dawn-CQ",
|
||||
watch = cq.refset(
|
||||
"https://dawn.googlesource.com/dawn",
|
||||
refs = ["refs/heads/.+"],
|
||||
),
|
||||
acls = [
|
||||
acl.entry(
|
||||
acl.CQ_COMMITTER,
|
||||
groups = "project-dawn-committers",
|
||||
def _create_dawn_cq_group(name, refs, refs_exclude = None):
|
||||
luci.cq_group(
|
||||
name = name,
|
||||
watch = cq.refset(
|
||||
"https://dawn.googlesource.com/dawn",
|
||||
refs = refs,
|
||||
refs_exclude = refs_exclude,
|
||||
),
|
||||
acl.entry(
|
||||
acl.CQ_DRY_RUNNER,
|
||||
groups = "project-dawn-tryjob-access",
|
||||
acls = [
|
||||
acl.entry(
|
||||
acl.CQ_COMMITTER,
|
||||
groups = "project-dawn-committers",
|
||||
),
|
||||
acl.entry(
|
||||
acl.CQ_DRY_RUNNER,
|
||||
groups = "project-dawn-tryjob-access",
|
||||
),
|
||||
],
|
||||
verifiers = [
|
||||
luci.cq_tryjob_verifier(
|
||||
builder = "dawn:try/presubmit",
|
||||
disable_reuse = True,
|
||||
),
|
||||
],
|
||||
retry_config = cq.retry_config(
|
||||
single_quota = 1,
|
||||
global_quota = 2,
|
||||
failure_weight = 1,
|
||||
transient_failure_weight = 1,
|
||||
timeout_weight = 2,
|
||||
),
|
||||
],
|
||||
verifiers = [
|
||||
luci.cq_tryjob_verifier(
|
||||
builder = "dawn:try/presubmit",
|
||||
disable_reuse = True,
|
||||
),
|
||||
],
|
||||
retry_config = cq.retry_config(
|
||||
single_quota = 1,
|
||||
global_quota = 2,
|
||||
failure_weight = 1,
|
||||
transient_failure_weight = 1,
|
||||
timeout_weight = 2,
|
||||
),
|
||||
)
|
||||
|
||||
def _create_branch_groups():
|
||||
for milestone, details in ACTIVE_MILESTONES.items():
|
||||
_create_dawn_cq_group(
|
||||
"Dawn-CQ-" + milestone,
|
||||
[details.ref],
|
||||
)
|
||||
|
||||
_create_dawn_cq_group(
|
||||
"Dawn-CQ",
|
||||
["refs/heads/.+"],
|
||||
[details.ref for details in ACTIVE_MILESTONES.values()],
|
||||
)
|
||||
_create_branch_groups()
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"112": {
|
||||
"name": "m112",
|
||||
"chromium_project": "chromium-m112",
|
||||
"ref": "refs/heads/chromium/5615",
|
||||
"platforms": [
|
||||
"mac",
|
||||
"win",
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"113": {
|
||||
"name": "m113",
|
||||
"chromium_project": "chromium-m113",
|
||||
"ref": "refs/heads/chromium/5672",
|
||||
"platforms": [
|
||||
"linux",
|
||||
"mac",
|
||||
"win",
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"114": {
|
||||
"name": "m114",
|
||||
"chromium_project": "chromium-m114",
|
||||
"ref": "refs/heads/chromium/5735",
|
||||
"platforms": [
|
||||
"linux",
|
||||
"mac",
|
||||
"win",
|
||||
"android"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Copyright 2023 The Dawn Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
#
|
||||
|
||||
def _milestone_details(*, chromium_project, ref, platforms):
|
||||
"""Define the details for an active milestone.
|
||||
|
||||
Args:
|
||||
* chromium_project - The name of the LUCI project that is configured for the
|
||||
milestone.
|
||||
* ref - The ref in the Dawn git repository that contains the code for the
|
||||
milestone.
|
||||
* platforms - A list of platform strings that the milestone is active for.
|
||||
"""
|
||||
return struct(
|
||||
chromium_project = chromium_project,
|
||||
ref = ref,
|
||||
platforms = platforms,
|
||||
)
|
||||
|
||||
ACTIVE_MILESTONES = {
|
||||
m["name"]: _milestone_details(
|
||||
chromium_project = m["chromium_project"],
|
||||
ref = m["ref"],
|
||||
platforms = m["platforms"],
|
||||
)
|
||||
for m in json.decode(io.read_file("./milestones.json")).values()
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 The Dawn Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""Script for updating the active milestones for the Dawn project.
|
||||
|
||||
This is largely based on the Chromium equivalent in
|
||||
chromium/src/infra/config/scripts/milestones.py.
|
||||
|
||||
To activate a new branch, run the following from the root of the repo (where MMM
|
||||
is the milestone number and BBBB is the branch number):
|
||||
```
|
||||
infra/config/scripts/milestones.py activate --milestone MMM --branch BBBB
|
||||
infra/config/global/main.star
|
||||
```
|
||||
|
||||
To deactivate a branch, run the following from the root of the repo (where MMM
|
||||
is the milestone number):
|
||||
```
|
||||
infra/config/scripts/milestones.py deactivate --milestone MMM
|
||||
infra/config/global/main.star
|
||||
```
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
INFRA_CONFIG_GLOBAL_DIR = os.path.realpath(
|
||||
os.path.join(os.path.dirname(__file__), '..', 'global'))
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Update the active milestones for the Dawn project')
|
||||
parser.set_defaults(func=None)
|
||||
parser.add_argument('--milestones-json',
|
||||
default=os.path.join(INFRA_CONFIG_GLOBAL_DIR,
|
||||
'milestones.json'),
|
||||
help='Path to the milestones.json file to modify')
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
activate_parser = subparsers.add_parser(
|
||||
'activate', help='Add an additional active milestone.')
|
||||
activate_parser.set_defaults(func=cmd_activate)
|
||||
activate_parser.add_argument(
|
||||
'--milestone',
|
||||
required=True,
|
||||
type=int,
|
||||
help='The milestone identifier/release channel number')
|
||||
activate_parser.add_argument(
|
||||
'--branch',
|
||||
required=True,
|
||||
help='The branch name, which should correspond to a ref in refs/heads')
|
||||
|
||||
deactivate_parser = subparsers.add_parser(
|
||||
'deactivate', help='Remove an active milestone')
|
||||
deactivate_parser.set_defaults(func=cmd_deactivate)
|
||||
deactivate_parser.add_argument(
|
||||
'--milestone',
|
||||
required=True,
|
||||
type=int,
|
||||
help='The milestone identifier/release channel number')
|
||||
|
||||
args = parser.parse_args()
|
||||
if not args.func:
|
||||
parser.error('No sub-command specified')
|
||||
return args
|
||||
|
||||
|
||||
def _sort_milestones(milestones):
|
||||
# We have to manually sort here instead of relying on
|
||||
# json.dump(..., sort_keys=True) later since we only want to sort the top
|
||||
# level keys, not all keys.
|
||||
milestones = {
|
||||
str(k): milestones[str(k)]
|
||||
for k in sorted([int(s) for s in milestones])
|
||||
}
|
||||
return milestones
|
||||
|
||||
|
||||
def add_milestone(milestones, milestone_num, branch):
|
||||
if str(milestone_num) in milestones:
|
||||
raise RuntimeError('Milestone %d already exists' % milestone_num)
|
||||
|
||||
milestones[str(milestone_num)] = {
|
||||
'name': f'm{milestone_num}',
|
||||
'chromium_project': f'chromium-m{milestone_num}',
|
||||
'ref': f'refs/heads/{branch}',
|
||||
'platforms': [
|
||||
'linux',
|
||||
'mac',
|
||||
'win',
|
||||
'android',
|
||||
],
|
||||
}
|
||||
|
||||
return _sort_milestones(milestones)
|
||||
|
||||
|
||||
def remove_milestone(milestones, milestone_num):
|
||||
if str(milestone_num) not in milestones:
|
||||
raise RuntimeError('Milestone %d does not exist' % milestone_num)
|
||||
del milestones[str(milestone_num)]
|
||||
# Not strictly necessary, but returning a value keeps this consistent with
|
||||
# add_milestone.
|
||||
return milestones
|
||||
|
||||
|
||||
def cmd_activate(args):
|
||||
with open(args.milestones_json) as infile:
|
||||
milestones = json.load(infile)
|
||||
milestones = add_milestone(milestones, args.milestone, args.branch)
|
||||
with open(args.milestones_json, 'w') as outfile:
|
||||
json.dump(milestones, outfile, indent=4)
|
||||
|
||||
|
||||
def cmd_deactivate(args):
|
||||
with open(args.milestones_json) as infile:
|
||||
milestones = json.load(infile)
|
||||
milestones = remove_milestone(milestones, args.milestone)
|
||||
with open(args.milestones_json, 'w') as outfile:
|
||||
json.dump(milestones, outfile, indent=4)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -79,7 +79,7 @@ CLONE_SRC_DIR="$(pwd)"
|
|||
|
||||
using depot_tools
|
||||
using go-1.18
|
||||
using doxygen-1.8.18
|
||||
using doxygen-1.9.5
|
||||
|
||||
status "Creating source directory '${SRC_DIR}' and build directory '${BUILD_DIR}'"
|
||||
mkdir -p ${SRC_DIR}
|
||||
|
@ -129,6 +129,7 @@ if [ "$BUILD_SYSTEM" == "cmake" ]; then
|
|||
COMMON_CMAKE_FLAGS+=" -DTINT_BUILD_MSL_WRITER=1"
|
||||
COMMON_CMAKE_FLAGS+=" -DTINT_BUILD_SPV_WRITER=1"
|
||||
COMMON_CMAKE_FLAGS+=" -DTINT_BUILD_WGSL_WRITER=1"
|
||||
COMMON_CMAKE_FLAGS+=" -DTINT_RANDOMIZE_HASHES=1"
|
||||
|
||||
if [ "$BUILD_TOOLCHAIN" == "clang" ]; then
|
||||
using clang-10.0.0
|
||||
|
@ -137,7 +138,7 @@ if [ "$BUILD_SYSTEM" == "cmake" ]; then
|
|||
COMMON_CMAKE_FLAGS+=" -DTINT_BUILD_AST_FUZZER=1"
|
||||
COMMON_CMAKE_FLAGS+=" -DTINT_BUILD_REGEX_FUZZER=1"
|
||||
elif [ "$BUILD_TOOLCHAIN" == "gcc" ]; then
|
||||
using gcc-9
|
||||
using gcc-10
|
||||
fi
|
||||
|
||||
if [ "$BUILD_SANITIZER" == "asan" ]; then
|
||||
|
|
|
@ -44,8 +44,8 @@ exit /b 0
|
|||
|
||||
set ORIGINAL_SRC_DIR= %~dp0\..\..\..
|
||||
set TEMP_DIR=%TEMP%\dawn-temp
|
||||
set SRC_DIR="%TEMP_DIR%\dawn-src"
|
||||
set BUILD_DIR="%TEMP_DIR%\dawn-build"
|
||||
set SRC_DIR=%TEMP_DIR%\dawn-src
|
||||
set BUILD_DIR=%TEMP_DIR%\dawn-build
|
||||
|
||||
cd /d %ORIGINAL_SRC_DIR%
|
||||
if not exist ".git\" (
|
||||
|
@ -105,11 +105,29 @@ copy scripts\standalone.gclient .gclient || goto :error
|
|||
call gclient sync || goto :error
|
||||
@echo off
|
||||
|
||||
call :status "Adding the Ninja from DEPS to the PATH"
|
||||
@echo on
|
||||
set PATH=%SRC_DIR%\third_party\ninja;%PATH%
|
||||
@echo off
|
||||
|
||||
call :status "Configuring build system"
|
||||
@echo on
|
||||
mkdir %BUILD_DIR%
|
||||
cd /d %BUILD_DIR%
|
||||
set COMMON_CMAKE_FLAGS=-DTINT_BUILD_DOCS=O -DTINT_BUILD_BENCHMARKS=1 -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DTINT_BUILD_BENCHMARKS=1 -DTINT_BUILD_SPV_READER=1 -DTINT_BUILD_WGSL_READER=1 -DTINT_BUILD_GLSL_WRITER=1 -DTINT_BUILD_HLSL_WRITER=1 -DTINT_BUILD_MSL_WRITER=1 -DTINT_BUILD_SPV_WRITER=1 -DTINT_BUILD_WGSL_WRITER=1
|
||||
set COMMON_CMAKE_FLAGS= ^
|
||||
-DTINT_BUILD_DOCS=O ^
|
||||
-DTINT_BUILD_BENCHMARKS=1 ^
|
||||
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% ^
|
||||
-DTINT_BUILD_BENCHMARKS=1 ^
|
||||
-DTINT_BUILD_SPV_READER=1 ^
|
||||
-DTINT_BUILD_WGSL_READER=1 ^
|
||||
-DTINT_BUILD_GLSL_WRITER=1 ^
|
||||
-DTINT_BUILD_HLSL_WRITER=1 ^
|
||||
-DTINT_BUILD_MSL_WRITER=1 ^
|
||||
-DTINT_BUILD_SPV_WRITER=1 ^
|
||||
-DTINT_BUILD_WGSL_WRITER=1 ^
|
||||
-DTINT_RANDOMIZE_HASHES=1
|
||||
|
||||
@echo off
|
||||
|
||||
call :status "Building dawn"
|
||||
|
@ -138,9 +156,7 @@ cd /d %SRC_DIR% || goto :error
|
|||
rem Run tests with DXC, FXC and Metal validation
|
||||
set OLD_PATH=%PATH%
|
||||
set PATH=C:\Program Files\Metal Developer Tools\macos\bin;%PATH%
|
||||
where metal.exe
|
||||
set PATH=%DXC_PATH%;%D3DCOMPILER_PATH%;%OLD_PATH%
|
||||
call git bash -- ./test/tint/test-all.sh ../dawn-build/tint.exe --verbose || goto :error
|
||||
call git bash -- ./test/tint/test-all.sh %BUILD_DIR%/tint.exe --verbose || goto :error
|
||||
set PATH=%OLD_PATH%
|
||||
@echo off
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ rm -rf third_party/angle
|
|||
rm -rf third_party/benchmark
|
||||
rm -rf third_party/catapult
|
||||
rm -rf third_party/googletest
|
||||
rm -rf third_party/google_benchmark
|
||||
rm -rf third_party/gpuweb-cts
|
||||
rm -rf third_party/llvm-build
|
||||
rm -rf third_party/markupsafe
|
||||
rm -rf third_party/protobuf
|
||||
rm -rf third_party/swiftshader
|
||||
rm -rf third_party/vulkan_memory_allocator
|
||||
|
|
|
@ -32,11 +32,17 @@ if (build_with_chromium) {
|
|||
dawn_is_winuwp = is_win && target_os == "winuwp"
|
||||
|
||||
declare_args() {
|
||||
dawn_use_angle = true
|
||||
# TODO(dawn:1545): Re-enable dawn_use_angle on Android. In non-component
|
||||
# builds, this is adding a dependency on ANGLE's libEGL.so and
|
||||
# libGLESv2.so, apparently without regard for the use_static_angle=true
|
||||
# GN variable. Chromium's linker on Android disallows production of more
|
||||
# than one shared object per target (?).
|
||||
dawn_use_angle = !is_android
|
||||
|
||||
# Enables SwiftShader as the fallback adapter. Requires dawn_swiftshader_dir
|
||||
# to be set to take effect.
|
||||
dawn_use_swiftshader = true
|
||||
# TODO(dawn:1536): Enable SwiftShader for Android.
|
||||
dawn_use_swiftshader = !is_android
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
|
@ -48,6 +54,9 @@ declare_args() {
|
|||
# standalone to produce static libraries to use in their projects.
|
||||
dawn_complete_static_libs = false
|
||||
|
||||
# Enables the compilation of Dawn's D3D11 backend
|
||||
dawn_enable_d3d11 = is_win
|
||||
|
||||
# Enables the compilation of Dawn's D3D12 backend
|
||||
dawn_enable_d3d12 = is_win
|
||||
|
||||
|
@ -90,6 +99,10 @@ declare_args() {
|
|||
# assume to have one present at the system level.
|
||||
dawn_enable_vulkan_loader =
|
||||
dawn_enable_vulkan && (is_mac || (is_linux && !is_android))
|
||||
|
||||
# Disable SPIR-V validation on Android because it adds a significant amount
|
||||
# to the binary size, and Tint's output should be well-formed.
|
||||
dawn_enable_spirv_validation = dawn_enable_vulkan && !is_android
|
||||
}
|
||||
|
||||
# UWP only supports CoreWindow for windowing
|
||||
|
|
|
@ -22,8 +22,12 @@ import sys
|
|||
import os
|
||||
import re
|
||||
|
||||
# Assume running the dawn_perf_tests build in Chromium checkout
|
||||
# Dawn locates at /path/to/Chromium/src/third_party/dawn/
|
||||
# Chromium build usually locates at /path/to/Chromium/src/out/Release/
|
||||
# You might want to change the base_path if you want to run dawn_perf_tests build from a Dawn standalone build.
|
||||
base_path = os.path.abspath(
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../../'))
|
||||
|
||||
# Look for a [Rr]elease build.
|
||||
perftests_paths = glob.glob('out/*elease*')
|
||||
|
@ -112,17 +116,19 @@ def get_results(metric, extra_args=[]):
|
|||
stderr=subprocess.PIPE)
|
||||
output, err = process.communicate()
|
||||
|
||||
m = re.search(r'Running (\d+) tests', output)
|
||||
output_string = output.decode('utf-8')
|
||||
|
||||
m = re.search(r"Running (\d+) tests", output_string)
|
||||
if m and int(m.group(1)) > 1:
|
||||
print("Found more than one test result in output:")
|
||||
print(output)
|
||||
print(output_string)
|
||||
sys.exit(3)
|
||||
|
||||
pattern = metric + r'.*= ([0-9.]+)'
|
||||
m = re.findall(pattern, output)
|
||||
m = re.findall(pattern, output_string)
|
||||
if not m:
|
||||
print("Did not find the metric '%s' in the test output:" % metric)
|
||||
print(output)
|
||||
print(output_string)
|
||||
sys.exit(1)
|
||||
|
||||
return [float(value) for value in m]
|
||||
|
|
|
@ -27,10 +27,8 @@ dawn_json_generator("cpp_gen") {
|
|||
}
|
||||
|
||||
source_set("cpp") {
|
||||
deps = [
|
||||
":cpp_gen",
|
||||
"${dawn_root}/include/dawn:cpp_headers",
|
||||
]
|
||||
public_deps = [ "${dawn_root}/include/dawn:cpp_headers" ]
|
||||
deps = [ ":cpp_gen" ]
|
||||
sources = get_target_outputs(":cpp_gen")
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ add_subdirectory(wire)
|
|||
# TODO(dawn:269): Remove once the implementation-based swapchains are removed.
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(glfw)
|
||||
add_subdirectory(tests/benchmarks)
|
||||
|
||||
if (DAWN_BUILD_SAMPLES)
|
||||
#TODO(dawn:269): Add this once implementation-based swapchains are removed.
|
||||
|
@ -72,10 +73,7 @@ DawnJSONGenerator(
|
|||
# because the file doesn't exist on disk.
|
||||
add_library(dawn_headers STATIC ${DAWN_PLACEHOLDER_FILE})
|
||||
common_compile_options(dawn_headers)
|
||||
target_sources(dawn_headers PRIVATE
|
||||
"${DAWN_INCLUDE_DIR}/dawn/dawn_wsi.h"
|
||||
${DAWN_HEADERS_GEN_SOURCES}
|
||||
)
|
||||
target_sources(dawn_headers PRIVATE ${DAWN_HEADERS_GEN_SOURCES})
|
||||
target_link_libraries(dawn_headers INTERFACE dawn_public_config)
|
||||
|
||||
###############################################################################
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace dawn {
|
||||
|
||||
template <typename T>
|
||||
T* AllocNoThrow(size_t count) {
|
||||
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
|
||||
|
@ -30,4 +32,6 @@ T* AllocNoThrow(size_t count) {
|
|||
return new (std::nothrow) T[count];
|
||||
}
|
||||
|
||||
} // namespace dawn
|
||||
|
||||
#endif // SRC_DAWN_COMMON_ALLOC_H_
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
#include "dawn/common/Log.h"
|
||||
#include "dawn/common/Platform.h"
|
||||
|
||||
#if DAWN_COMPILER_IS(MSVC)
|
||||
extern void __cdecl __debugbreak(void);
|
||||
#endif
|
||||
|
||||
namespace dawn {
|
||||
|
||||
#if DAWN_COMPILER_IS(CLANG) || DAWN_COMPILER_IS(GCC)
|
||||
void BreakPoint() {
|
||||
#if DAWN_PLATFORM_IS(X86)
|
||||
|
@ -27,6 +33,8 @@ void BreakPoint() {
|
|||
__asm__ __volatile__("bkpt 0");
|
||||
#elif DAWN_PLATFORM_IS(ARM64)
|
||||
__asm__ __volatile__("brk 0");
|
||||
#elif DAWN_PLATFORM_IS(LOONGARCH)
|
||||
__asm__ __volatile__("break 0");
|
||||
#elif DAWN_PLATFORM_IS(RISCV)
|
||||
__asm__ __volatile__("ebreak");
|
||||
#elif DAWN_PLATFORM_IS(MIPS)
|
||||
|
@ -41,7 +49,6 @@ void BreakPoint() {
|
|||
}
|
||||
|
||||
#elif DAWN_COMPILER_IS(MSVC)
|
||||
extern void __cdecl __debugbreak(void);
|
||||
void BreakPoint() {
|
||||
__debugbreak();
|
||||
}
|
||||
|
@ -62,3 +69,5 @@ void HandleAssertionFailure(const char* file,
|
|||
BreakPoint();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace dawn
|
||||
|
|
|
@ -41,11 +41,11 @@
|
|||
// expect of an assert and in release it tries to give hints to make the compiler generate better
|
||||
// code.
|
||||
#if defined(DAWN_ENABLE_ASSERTS)
|
||||
#define DAWN_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
HandleAssertionFailure(file, func, line, #condition); \
|
||||
} \
|
||||
#define DAWN_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
dawn::HandleAssertionFailure(file, func, line, #condition); \
|
||||
} \
|
||||
} while (DAWN_ASSERT_LOOP_CONDITION)
|
||||
#else
|
||||
#if DAWN_COMPILER_IS(MSVC)
|
||||
|
@ -72,9 +72,14 @@
|
|||
#define UNREACHABLE DAWN_UNREACHABLE
|
||||
#endif
|
||||
|
||||
namespace dawn {
|
||||
|
||||
void BreakPoint();
|
||||
void HandleAssertionFailure(const char* file,
|
||||
const char* function,
|
||||
int line,
|
||||
const char* condition);
|
||||
|
||||
} // namespace dawn
|
||||
|
||||
#endif // SRC_DAWN_COMMON_ASSERT_H_
|
||||
|
|
|
@ -58,6 +58,9 @@ config("internal_config") {
|
|||
]
|
||||
}
|
||||
|
||||
if (dawn_enable_d3d11) {
|
||||
defines += [ "DAWN_ENABLE_BACKEND_D3D11" ]
|
||||
}
|
||||
if (dawn_enable_d3d12) {
|
||||
defines += [ "DAWN_ENABLE_BACKEND_D3D12" ]
|
||||
}
|
||||
|
@ -80,6 +83,13 @@ config("internal_config") {
|
|||
defines += [ "DAWN_ENABLE_BACKEND_VULKAN" ]
|
||||
}
|
||||
|
||||
# OS_CHROMEOS cannot be autodetected in runtime and
|
||||
# cannot be detected with regular compiler macros either.
|
||||
# Inject it from the build system
|
||||
if (is_chromeos) {
|
||||
defines += [ "DAWN_OS_CHROMEOS" ]
|
||||
}
|
||||
|
||||
if (dawn_use_wayland) {
|
||||
defines += [ "DAWN_USE_WAYLAND" ]
|
||||
}
|
||||
|
@ -236,6 +246,8 @@ if (is_win || is_linux || is_chromeos || is_mac || is_fuchsia || is_android) {
|
|||
"Log.h",
|
||||
"Math.cpp",
|
||||
"Math.h",
|
||||
"Mutex.cpp",
|
||||
"Mutex.h",
|
||||
"NSRef.h",
|
||||
"NonCopyable.h",
|
||||
"Numeric.h",
|
||||
|
@ -253,7 +265,6 @@ if (is_win || is_linux || is_chromeos || is_mac || is_fuchsia || is_android) {
|
|||
"SlabAllocator.cpp",
|
||||
"SlabAllocator.h",
|
||||
"StackContainer.h",
|
||||
"SwapChainUtils.h",
|
||||
"SystemUtils.cpp",
|
||||
"SystemUtils.h",
|
||||
"TypeTraits.h",
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "dawn/common/Math.h"
|
||||
#include "dawn/common/UnderlyingType.h"
|
||||
|
||||
namespace dawn {
|
||||
|
||||
// This is ANGLE's BitSetIterator class with a customizable return type.
|
||||
// Types have been updated to be more specific.
|
||||
// TODO(crbug.com/dawn/306): it could be optimized, in particular when N <= 64
|
||||
|
@ -131,4 +133,6 @@ BitSetIterator<N, uint32_t> IterateBitSet(const std::bitset<N>& bitset) {
|
|||
return BitSetIterator<N, uint32_t>(bitset);
|
||||
}
|
||||
|
||||
} // namespace dawn
|
||||
|
||||
#endif // SRC_DAWN_COMMON_BITSETITERATOR_H_
|
||||
|
|
|
@ -52,6 +52,8 @@ target_sources(dawn_common PRIVATE
|
|||
"Log.h"
|
||||
"Math.cpp"
|
||||
"Math.h"
|
||||
"Mutex.cpp"
|
||||
"Mutex.h"
|
||||
"NSRef.h"
|
||||
"NonCopyable.h"
|
||||
"Numeric.h"
|
||||
|
@ -69,7 +71,6 @@ target_sources(dawn_common PRIVATE
|
|||
"SlabAllocator.cpp"
|
||||
"SlabAllocator.h"
|
||||
"StackContainer.h"
|
||||
"SwapChainUtils.h"
|
||||
"SystemUtils.cpp"
|
||||
"SystemUtils.h"
|
||||
"TypeTraits.h"
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "dawn/common/NonCopyable.h"
|
||||
|
||||
namespace dawn {
|
||||
|
||||
template <typename T>
|
||||
class ConcurrentCache : public NonMovable {
|
||||
public:
|
||||
|
@ -51,4 +53,6 @@ class ConcurrentCache : public NonMovable {
|
|||
std::unordered_set<T*, typename T::HashFunc, typename T::EqualityFunc> mCache;
|
||||
};
|
||||
|
||||
} // namespace dawn
|
||||
|
||||
#endif // SRC_DAWN_COMMON_CONCURRENTCACHE_H_
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue