Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ option(IGL_WITH_OPENGLES "Enable IGL/OpenGL ES" OFF)
option(IGL_WITH_VULKAN "Enable IGL/Vulkan" ON)
option(IGL_WITH_METAL "Enable IGL/Metal" ON)
option(IGL_WITH_WEBGL "Enable IGL/WebGL" OFF)
option(IGL_WITH_D3D12 "Enable IGL/DirectX 12" OFF)

option(IGL_WITH_IGLU "Enable IGLU utils" ON)
option(IGL_WITH_SHELL "Enable Shell utils" ON)
Expand Down Expand Up @@ -49,6 +50,10 @@ if(NOT APPLE)
set(IGL_WITH_METAL OFF)
endif()

if(NOT WIN32)
set(IGL_WITH_D3D12 OFF)
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# disable for all targets due to warnings in third-party code
add_definitions(-Wno-nullability-completeness)
Expand Down Expand Up @@ -100,6 +105,7 @@ message(STATUS "IGL_WITH_OPENGLES = ${IGL_WITH_OPENGLES}")
message(STATUS "IGL_WITH_VULKAN = ${IGL_WITH_VULKAN}")
message(STATUS "IGL_WITH_METAL = ${IGL_WITH_METAL}")
message(STATUS "IGL_WITH_WEBGL = ${IGL_WITH_WEBGL}")
message(STATUS "IGL_WITH_D3D12 = ${IGL_WITH_D3D12}")

message(STATUS "IGL_WITH_IGLU = ${IGL_WITH_IGLU}")
message(STATUS "IGL_WITH_SHELL = ${IGL_WITH_SHELL}")
Expand All @@ -120,8 +126,8 @@ if(APPLE)
message(FATAL_ERROR "At least one rendering backend should be defined (OpenGL, Vulkan or Metal).")
endif()
else()
if(NOT (IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_OPENGLES OR IGL_WITH_WEBGL))
message(FATAL_ERROR "At least one rendering backend should be defined (OpenGL or Vulkan).")
if(NOT (IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_OPENGLES OR IGL_WITH_WEBGL OR IGL_WITH_D3D12))
message(FATAL_ERROR "At least one rendering backend should be defined (OpenGL, Vulkan, or DirectX 12).")
endif()
endif()

Expand Down Expand Up @@ -193,6 +199,16 @@ if(IGL_WITH_OPENXR)
igl_set_folder(openxr_loader "third-party/OpenXR")
endif()

if(WIN32 AND IGL_WITH_D3D12)
set(DIRECTX_HEADERS_ROOT "${IGL_ROOT_DIR}/third-party/deps/src/DirectX-Headers")
if(EXISTS "${DIRECTX_HEADERS_ROOT}/CMakeLists.txt")
add_subdirectory("${DIRECTX_HEADERS_ROOT}" "${CMAKE_BINARY_DIR}/DirectX-Headers")
set(DIRECTX_HEADERS_INCLUDE_DIR "${DIRECTX_HEADERS_ROOT}/include/directx")
else()
message(FATAL_ERROR "DirectX-Headers dependency not found. Run deploy_deps.py to download third-party/deps/src/DirectX-Headers.")
endif()
endif()

add_subdirectory(src/igl)

if(IGL_WITH_TRACY)
Expand Down Expand Up @@ -234,11 +250,20 @@ endif()
if(APPLE AND IGL_WITH_METAL)
target_compile_definitions(IGLLibrary PUBLIC "IGL_BACKEND_ENABLE_METAL=1")
endif()
if(WIN32 AND IGL_WITH_D3D12)
target_compile_definitions(IGLLibrary PUBLIC "IGL_BACKEND_ENABLE_D3D12=1")
endif()

target_compile_definitions(IGLLibrary PUBLIC "IGL_CMAKE_BUILD=1")

include_directories(.)

# Enable CTest at top-level when tests are requested so `ctest` can discover tests
if(IGL_WITH_TESTS)
include(CTest)
enable_testing()
endif()

if(IGL_WITH_IGLU OR IGL_WITH_SAMPLES)
add_library(IGLstb third-party/deps/patches/stb_impl/stb_image.c third-party/deps/patches/stb_impl/stb_image_resize.c
third-party/deps/patches/stb_impl/stb_image_write.c)
Expand Down
45 changes: 39 additions & 6 deletions samples/desktop/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,52 @@ macro(ADD_DEMO app)
target_link_libraries(${app} PRIVATE EGL)
endif()
target_link_libraries(${app} PRIVATE IGLstb)

# For D3D12 builds on Windows, ensure dxil.dll is deployed next to sample
# executables so that DXC/DXIL validation and signed DXIL shaders work in
# both Debug and Release configurations. This mirrors the behavior used for
# render sessions (shell/windows/CMakeLists.txt) and unit tests
# (test_all_unittests.bat).
if(IGL_WITH_D3D12 AND WIN32 AND MSVC)
find_file(DXIL_DLL_FOR_${app}
NAMES dxil.dll
PATHS
"C:/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64"
"C:/Program Files (x86)/Windows Kits/10/bin/10.0.22000.0/x64"
"C:/Program Files (x86)/Windows Kits/10/bin/10.0.19041.0/x64"
"$ENV{WindowsSdkBinPath}/x64"
NO_DEFAULT_PATH
)
if(DXIL_DLL_FOR_${app})
add_custom_command(TARGET ${app} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${DXIL_DLL_FOR_${app}}"
"$<TARGET_FILE_DIR:${app}>/"
COMMENT "Copying dxil.dll for ${app}"
)
endif()
endif()
endmacro()

add_demo("Tiny")
if(IGL_WITH_OPENGL OR IGL_WITH_VULKAN)
add_demo("Tiny")
endif()

if(IGL_WITH_VULKAN)
# this demo app does not work without Vulkan (yet)
add_demo("Tiny_Mesh")
endif()

add_demo("Tiny_MeshLarge")
# Tiny_MeshLarge can run on Vulkan/OpenGL; expose it for D3D12 configs too so the binary is available.
if(IGL_WITH_OPENGL OR IGL_WITH_VULKAN OR IGL_WITH_D3D12)
add_demo("Tiny_MeshLarge")

target_sources(Tiny_MeshLarge
PUBLIC "${IGL_ROOT_DIR}/third-party/deps/src/3D-Graphics-Rendering-Cookbook/shared/UtilsCubemap.cpp")
if(NOT IGL_WITH_VULKAN)
target_sources(Tiny_MeshLarge PUBLIC "${IGL_ROOT_DIR}/src/igl/vulkan/util/TextureFormat.cpp")
target_sources(
Tiny_MeshLarge
PUBLIC "${IGL_ROOT_DIR}/third-party/deps/src/3D-Graphics-Rendering-Cookbook/shared/UtilsCubemap.cpp")
if(NOT IGL_WITH_VULKAN)
target_sources(Tiny_MeshLarge PUBLIC "${IGL_ROOT_DIR}/src/igl/vulkan/util/TextureFormat.cpp")
endif()
else()
message(STATUS "Skipping Tiny_MeshLarge: no compatible backend enabled (needs OpenGL/Vulkan/D3D12)")
endif()
1 change: 1 addition & 0 deletions shell/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ if(IGL_WITH_OPENXR)
add_subdirectory(openxr)
endif()


macro(ADD_SHELL_SESSION target libs)
set(shell_srcs apps/SessionApp.cpp renderSessions/${target}.cpp renderSessions/${target}.h)
add_shell_session_with_srcs(${target} "${shell_srcs}" "${libs}")
Expand Down
30 changes: 30 additions & 0 deletions shell/windows/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ endif()
if(IGL_WITH_OPENGLES)
add_shell_app(opengles)
endif()
# Only add D3D12 shell app if the sources are present (removed in this branch)
set(IGL_D3D12_APP_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/../windows/d3d12/App.cpp")
if(IGL_WITH_D3D12 AND EXISTS "${IGL_D3D12_APP_SOURCE}")
add_shell_app(d3d12)
target_link_libraries(IGLShellApp_d3d12 PUBLIC IGLD3D12)
endif()

function(ADD_SHELL_SESSION_BACKEND targetApp backend srcs libs)
set(target ${targetApp}_${backend})
Expand All @@ -50,6 +56,27 @@ function(ADD_SHELL_SESSION_BACKEND targetApp backend srcs libs)
target_compile_definitions(${target} PRIVATE "IGL_SHELL_SESSION=${targetApp}")
target_link_libraries(${target} PUBLIC ${libs})
target_link_libraries(${target} PUBLIC IGLShellApp_${backend})

# Copy dxil.dll for D3D12 executables (required for DXIL signing)
if(backend STREQUAL "d3d12" AND WIN32 AND MSVC)
find_file(DXIL_DLL_FOR_${target}
NAMES dxil.dll
PATHS
"C:/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64"
"C:/Program Files (x86)/Windows Kits/10/bin/10.0.22000.0/x64"
"C:/Program Files (x86)/Windows Kits/10/bin/10.0.19041.0/x64"
"$ENV{WindowsSdkBinPath}/x64"
NO_DEFAULT_PATH
)
if(DXIL_DLL_FOR_${target})
add_custom_command(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${DXIL_DLL_FOR_${target}}"
"$<TARGET_FILE_DIR:${target}>/"
COMMENT "Copying dxil.dll for ${target}"
)
endif()
endif()
endfunction()

function(ADD_SHELL_SESSION_BACKEND_OPENXR_SIM targetApp backend srcs libs compileDefs)
Expand All @@ -72,4 +99,7 @@ macro(ADD_SHELL_SESSION_WITH_SRCS target srcs libs)
if(IGL_WITH_OPENGLES)
add_shell_session_backend(${target} opengles "${srcs}" "${libs}")
endif()
if(IGL_WITH_D3D12 AND TARGET IGLShellApp_d3d12)
add_shell_session_backend(${target} d3d12 "${srcs}" "${libs}")
endif()
endmacro()
15 changes: 15 additions & 0 deletions src/igl/Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ struct BufferDesc {
/** @brief Identifier used for debugging */
std::string debugName;

/**
* @brief Element stride in bytes for storage buffers.
*
* For buffers created with BufferTypeBits::Storage, this describes the size of a single
* structured element when the buffer is viewed as a StructuredBuffer / RWStructuredBuffer.
*
* Backends that create structured SRV/UAV views (such as D3D12) use this value to populate
* D3D12_BUFFER_SRV / D3D12_BUFFER_UAV StructureByteStride and to compute NumElements.
*
* A value of 0 means "unknown/unspecified" and backends may fall back to a default
* element size (typically 4 bytes) for compatibility with existing code that assumes
* float / uint elements.
*/
size_t storageStride = 0;

BufferDesc(BufferType type = 0,
const void* IGL_NULLABLE data = nullptr,
size_t length = 0,
Expand Down
9 changes: 8 additions & 1 deletion src/igl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,16 @@ if(IGL_WITH_METAL)
target_link_libraries(IGLLibrary PUBLIC IGLMetal)
endif()

if(IGL_WITH_D3D12)
add_subdirectory(d3d12)
target_link_libraries(IGLLibrary PUBLIC IGLD3D12)
endif()

# OpenGL tests use GLES on Windows and we do not use Angle with CMake - so OGL
# tests are disabled for now on Windows
if(IGL_WITH_TESTS AND IGL_WITH_IGLU AND (IGL_WITH_VULKAN OR (NOT WIN32)))
# Enable tests when requested. On Windows, allow tests if either Vulkan or D3D12 is enabled
# (previously required Vulkan on Windows, which blocked D3D12-only test runs).
if(IGL_WITH_TESTS AND IGL_WITH_IGLU AND (IGL_WITH_VULKAN OR IGL_WITH_D3D12 OR (NOT WIN32)))
add_subdirectory(tests)
if((IGL_WITH_OPENGL OR IGL_WITH_OPENGLES) AND NOT APPLE)
target_sources(IGLTests PRIVATE opengl/egl/Context.cpp opengl/egl/Device.cpp opengl/egl/HWDevice.cpp
Expand Down
11 changes: 10 additions & 1 deletion src/igl/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ using Deleter = void (*)(void* IGL_NULLABLE);

/// Device Capabilities or Metal Features
constexpr uint32_t IGL_TEXTURE_SAMPLERS_MAX = 16;
constexpr uint32_t IGL_VERTEX_ATTRIBUTES_MAX = 24;

// Maximum vertex attributes across all backends
// - D3D12: D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32
// - Vulkan: VkPhysicalDeviceLimits::maxVertexInputAttributes (typically >= 16, commonly 32)
// - Metal: 31 (Metal Feature Set Tables)
// - OpenGL: GL_MAX_VERTEX_ATTRIBS (typically >= 16)
// Setting to 32 ensures compatibility with D3D12 (the most widely-supported modern API)
constexpr uint32_t IGL_VERTEX_ATTRIBUTES_MAX = 32;

// maximum number of buffers that can be bound to a shader stage
// See maximum number of entries in the buffer argument table, per graphics or kernel function
Expand Down Expand Up @@ -136,6 +143,7 @@ enum class BackendType {
OpenGL,
Metal,
Vulkan,
D3D12,
// @fb-only
Custom,
};
Expand All @@ -146,6 +154,7 @@ enum class BackendFlavor : uint8_t {
OpenGL_ES,
Metal,
Vulkan,
D3D12,
// @fb-only
};

Expand Down
2 changes: 2 additions & 0 deletions src/igl/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Color IDevice::backendDebugColor() const noexcept {
return {1.f, 0.f, 1.f, 1.f};
case BackendType::Vulkan:
return {0.f, 1.f, 1.f, 1.f};
case BackendType::D3D12:
return {0.f, 1.f, 1.f, 1.f}; // Match Vulkan for parity testing
// @fb-only
// @fb-only
case BackendType::Custom:
Expand Down
50 changes: 37 additions & 13 deletions src/igl/DeviceFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,30 @@ enum class DeviceRequirement {
* @brief DeviceFeatureLimits provides specific limitations on certain features supported on the
* device
*
* BufferAlignment Required byte alignment for buffer data
* BufferNoCopyAlignment Required byte alignment for no copy buffer data
* MaxBindBytesBytes Maximum number of bytes that can be bound with bindBytes
* MaxCubeMapDimension Maximum cube map dimensions
* MaxFragmentUniformVectors Maximum fragment uniform vectors
* MaxMultisampleCount Maximum number of samples
* MaxPushConstantBytes Maximum number of bytes for Push Constants
* MaxTextureDimension1D2D Maximum texture dimensions
* MaxUniformBufferBytes Maximum number of bytes for a uniform buffer
* MaxStorageBufferBytes Maximum number of bytes for storage buffers
* MaxVertexUniformVectors Maximum vertex uniform vectors
* PushConstantsAlignment Required byte alignment for push constants data
* BufferAlignment Required byte alignment for buffer data
* BufferNoCopyAlignment Required byte alignment for no copy buffer data
* MaxBindBytesBytes Maximum number of bytes that can be bound with bindBytes
* MaxCubeMapDimension Maximum cube map dimensions
* MaxFragmentUniformVectors Maximum fragment uniform vectors
* MaxMultisampleCount Maximum number of samples
* MaxPushConstantBytes Maximum number of bytes for Push Constants
* MaxTextureDimension1D2D Maximum texture dimensions for 1D and 2D textures
* MaxTextureDimension3D Maximum texture dimensions for 3D textures
* MaxStorageBufferBytes Maximum number of bytes for storage buffers
* MaxUniformBufferBytes Maximum number of bytes for a uniform buffer
* MaxVertexUniformVectors Maximum vertex uniform vectors
* PushConstantsAlignment Required byte alignment for push constants data
* ShaderStorageBufferOffsetAlignment Required byte alignment for shader storage buffer offset
* MaxComputeWorkGroupSizeX Maximum compute work group size in X dimension
* MaxComputeWorkGroupSizeY Maximum compute work group size in Y dimension
* MaxComputeWorkGroupSizeZ Maximum compute work group size in Z dimension
* MaxComputeWorkGroupInvocations Maximum total compute work group invocations
* MaxVertexInputAttributes Maximum number of vertex input attributes
* MaxColorAttachments Maximum number of color attachments (render targets)
* MaxDescriptorHeapCbvSrvUav Maximum CBV/SRV/UAV descriptors in shader-visible heap (I-005)
* MaxDescriptorHeapSamplers Maximum sampler descriptors in shader-visible heap (I-005)
* MaxDescriptorHeapRtvs Maximum RTV descriptors in CPU-visible heap (I-005)
* MaxDescriptorHeapDsvs Maximum DSV descriptors in CPU-visible heap (I-005)
*/
enum class DeviceFeatureLimits {
BufferAlignment = 0,
Expand All @@ -176,11 +188,23 @@ enum class DeviceFeatureLimits {
MaxMultisampleCount,
MaxPushConstantBytes,
MaxTextureDimension1D2D,
MaxTextureDimension3D,
MaxStorageBufferBytes,
MaxUniformBufferBytes,
MaxVertexUniformVectors,
PushConstantsAlignment,
ShaderStorageBufferOffsetAlignment,
MaxComputeWorkGroupSizeX,
MaxComputeWorkGroupSizeY,
MaxComputeWorkGroupSizeZ,
MaxComputeWorkGroupInvocations,
MaxVertexInputAttributes,
MaxColorAttachments,
// I-005: Descriptor heap size limits for cross-platform compatibility
MaxDescriptorHeapCbvSrvUav,
MaxDescriptorHeapSamplers,
MaxDescriptorHeapRtvs,
MaxDescriptorHeapDsvs,
};

/**
Expand All @@ -192,7 +216,7 @@ enum class DeviceFeatureLimits {
* Metal Metal API (macOS, iOS, etc.)
* SpirV Standard Portable Intermediate Representation open standard format
*/
enum class ShaderFamily : uint8_t { Unknown, Glsl, GlslEs, Metal, SpirV };
enum class ShaderFamily : uint8_t { Unknown, Glsl, GlslEs, Metal, SpirV, Hlsl };

/**
* @brief ShaderVersion provides information on the shader family type and version
Expand Down
1 change: 1 addition & 0 deletions src/igl/PlatformDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum class PlatformDeviceType {
OpenGLMacOS,
OpenGLWebGL,
Vulkan,
D3D12,
// @fb-only
};

Expand Down
Loading
Loading