Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
856a955
Add D3D12 GPU backend build configuration for Windows.
leiyue123 Mar 26, 2026
737f459
Add D3D12 base types and utility layer with DXGI format mappings and …
leiyue123 Mar 26, 2026
94bcae2
Add D3D12 GPU Device and CommandQueue with Backend enum extension and…
leiyue123 Mar 26, 2026
b3dc420
Implement D3D12Buffer D3D12Texture and D3D12Sampler resource types wi…
leiyue123 Mar 27, 2026
07c9456
Merge remote-tracking branch 'origin/main' into feature/codebuddy_d3d…
leiyue123 May 14, 2026
c6527ae
Add D3D12 test DevicePool to wire up test infrastructure with D3D12 b…
leiyue123 May 14, 2026
04953f8
Add D3D12Semaphore backed by ID3D12Fence to enable GPU semaphore impo…
leiyue123 May 14, 2026
1b4baf0
Add D3D12CommandBuffer and D3D12FrameSession transport plumbing with …
leiyue123 May 14, 2026
5b58a9a
Add D3D12ShaderModule that compiles GLSL through SPIR-V and HLSL into…
leiyue123 May 14, 2026
705be43
Add D3D12RenderPipeline that builds a root signature plus PSO and exp…
leiyue123 May 14, 2026
387d36c
Wire up the D3D12 render path with command encoder render pass per-pa…
leiyue123 May 14, 2026
3792ca3
Stop the test runner from hanging at exit by short-circuiting D3D12 l…
leiyue123 May 14, 2026
cef4184
Dedup descriptor heap allocations per render pass and route unaligned…
leiyue123 May 15, 2026
3fbcdcc
Drop the optimised colour clear value on D3D12 render targets and res…
leiyue123 May 15, 2026
7249946
Add Device Removed Extended Data plumbing so future GPU hangs print t…
leiyue123 May 15, 2026
a4f0a9b
Add a compute-shader mipmap generator backed by an 8x8 box-filter ker…
leiyue123 May 15, 2026
5a92d17
Emit synchronised varying location qualifiers and disable shaderc dea…
leiyue123 May 15, 2026
e762ac9
Resolve MSAA color attachments to their single-sample resolveTexture …
leiyue123 May 15, 2026
d5a32f7
Implicitly enable RT capability on renderable D3D12 textures so Surfa…
leiyue123 May 15, 2026
e86b75b
Treat depth-stencil DXGI formats as renderable in D3D12GPU::isFormatR…
leiyue123 May 15, 2026
fef9781
Replace per-render-pass shader-visible descriptor heap creation with …
leiyue123 May 15, 2026
d42a391
Pool D3D12 command allocator and graphics command list pairs across e…
leiyue123 May 15, 2026
2e953bb
Sub-allocate writeTexture staging buffers from a permanently mapped 6…
leiyue123 May 15, 2026
1f41413
Batch D3D12 resource transitions in render pass setup, draw flush, en…
leiyue123 May 18, 2026
508bf52
Cache D3D12 root signatures keyed by their binding-shape so pipelines…
leiyue123 May 18, 2026
288017c
Cache D3D12 shader modules keyed by stage and source hash so two prog…
leiyue123 May 18, 2026
e1038dc
Merge branch 'main' into feature/codebuddy_d3d12_backend
leiyue123 May 18, 2026
711ae9b
Merge branch 'main' into feature/codebuddy_d3d12_backend
leiyue123 May 18, 2026
c4c205c
Merge branch 'main' into feature/codebuddy_d3d12_backend
leiyue123 May 18, 2026
550a757
Stop emitting layout(location) on varyings so desktop OpenGL GLSL 150…
leiyue123 May 19, 2026
8019cf4
Track real GPU completion time on D3D12 so multi flush submissions st…
leiyue123 May 19, 2026
0f42381
Disable textureBarrier feature on D3D12 so advanced blend modes route…
leiyue123 May 19, 2026
d9bc637
Stop the D3D12 upload ring from silently overwriting uncommitted stag…
leiyue123 May 19, 2026
4196821
Use a single hardware linear tap to generate D3D12 mip levels so they…
leiyue123 May 19, 2026
6017691
Clamp D3D12 sampler MaxLOD to zero when mipmap mode is None so the dr…
leiyue123 May 19, 2026
ca8d0b6
Add D3D12Window with IDXGISwapChain3 and a Hello2D shim so D3D12 can …
leiyue123 May 19, 2026
2990e3a
Re-query the D3D12 swap chain backbuffer each frame so Hello2D actual…
leiyue123 May 19, 2026
d6bba62
Drain the cache and the GPU return queue before destroying the D3D12 …
leiyue123 May 19, 2026
f29a771
Also clear the D3D12 command list pool before destroying the swap cha…
leiyue123 May 19, 2026
2c98ae8
Drain Present-driven GPU work via a fresh fence before releasing the …
leiyue123 May 19, 2026
811538d
Merge branch 'main' into feature/thunderllei_d3d12_backend
leiyue123 May 19, 2026
748de81
Make the shaderc dead-code stripping bypass an opt-in, so only D3D12 …
leiyue123 May 19, 2026
65a826e
Add cstddef include and D3D12 backend switch case so non-Windows buil…
leiyue123 May 19, 2026
59ff859
Honor BindingEntry visibility for D3D12 SRV and Sampler root paramete…
leiyue123 May 20, 2026
5e70c07
Remove the redundant D3D12ExternalTexture and let one D3D12Texture pa…
leiyue123 May 20, 2026
15c2f50
Assign D3D12 CBV registers per stage by uniform block declaration ord…
leiyue123 May 20, 2026
1b4abe2
Mark the D3D12 BackendTexture, BackendRenderTarget, and BackendSemaph…
leiyue123 May 20, 2026
b9a1ba6
Track an explicit outstanding-slots counter in D3D12DescriptorRing an…
leiyue123 May 20, 2026
b3b30a9
Document the upload heap shortcut for D3D12 buffers and the future st…
leiyue123 May 20, 2026
736d205
Always drain inflight submissions in D3D12GPU::releaseAll so the no-G…
leiyue123 May 20, 2026
57f2901
Explain why the D3D12 PSO topology type and strip cut value stay hard…
leiyue123 May 20, 2026
59c1408
Reject out of range offsets in D3D12 setVertexBuffer and empty buffer…
leiyue123 May 20, 2026
db31bb9
Reject mipmapped multisample textures up front in D3D12 because the U…
leiyue123 May 20, 2026
2980c4a
Memoise sampler creation failures too so a hypothetically exhausted D…
leiyue123 May 20, 2026
e71ba93
Document why D3D12 writeTexture, copyTextureToTexture, and ResolveSub…
leiyue123 May 20, 2026
8b145e0
Sub-allocate D3D12 RTV and DSV descriptors from GPU-wide fence-tracke…
leiyue123 May 20, 2026
7da907c
Static assert that D3D12TextureInfo and D3D12SyncInfo stay trivially …
leiyue123 May 20, 2026
31c89d0
Snapshot the original D3D12 texture state on first touch in a session…
leiyue123 May 20, 2026
4b3cc37
Reset the D3D12 SRV RTV DSV and UPLOAD ring bookkeeping when context …
leiyue123 May 20, 2026
748c856
Cache the D3D12 swap chain proxy as a typed raw pointer so onPresent …
leiyue123 May 20, 2026
79d5f7a
Document why D3D12 samplers hardcode a transparent black border colou…
leiyue123 May 20, 2026
721b4b6
Apply clang-format 14 to the four D3D12 source files flagged by codef…
leiyue123 May 21, 2026
74ba7d6
Drop the D3D12 ring tail and InflightRange newHead fields that became…
leiyue123 May 25, 2026
def43d2
Clear inflight entries and outstanding bytes in D3D12 ring init so a …
leiyue123 May 25, 2026
6d93b44
Point the D3D12 mismatched VertexFragment UBO LOGE at workable fixes …
leiyue123 May 25, 2026
f3c8e07
Add D3D12Device::MakeWarp() and TGFX_D3D12_USE_WARP CMake flag so hea…
leiyue123 May 25, 2026
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
70 changes: 66 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ option(TGFX_BUILD_LAYERS "Enable building the layers module" OFF)
option(TGFX_BUILD_HELLO2D "Enable building the tgfx-hello2d library for testing" OFF)
option(TGFX_USE_OPENGL "Use OpenGL as the GPU backend" ON)
option(TGFX_USE_METAL "Use Metal as the GPU backend on Apple platforms" OFF)
option(TGFX_USE_D3D12 "Use D3D12 as the GPU backend on Windows" OFF)
option(TGFX_D3D12_USE_WARP "Force the D3D12 backend onto the WARP software rasterizer (CI only)" OFF)
option(TGFX_USE_QT "Enable building with the Qt framework." OFF)
option(TGFX_USE_SWIFTSHADER "Enable building with the SwiftShader library" OFF)
option(TGFX_USE_ANGLE "Enable building with the ANGLE library" OFF)
Expand Down Expand Up @@ -97,6 +99,16 @@ if (TGFX_USE_VULKAN)
endif ()
set(TGFX_USE_OPENGL OFF)
set(TGFX_USE_METAL OFF)
set(TGFX_USE_D3D12 OFF)
set(TGFX_USE_QT OFF)
set(TGFX_USE_SWIFTSHADER OFF)
set(TGFX_USE_ANGLE OFF)
elseif (TGFX_USE_D3D12)
if (NOT WIN32)
message(FATAL_ERROR "TGFX_USE_D3D12 is only supported on Windows.")
endif ()
set(TGFX_USE_OPENGL OFF)
set(TGFX_USE_METAL OFF)
set(TGFX_USE_QT OFF)
set(TGFX_USE_SWIFTSHADER OFF)
set(TGFX_USE_ANGLE OFF)
Expand Down Expand Up @@ -124,8 +136,8 @@ else ()
endif ()
endif ()

if (NOT TGFX_USE_METAL AND NOT TGFX_USE_OPENGL AND NOT TGFX_USE_VULKAN)
message(FATAL_ERROR "At least one GPU backend (TGFX_USE_METAL, TGFX_USE_OPENGL, or TGFX_USE_VULKAN) must be enabled.")
if (NOT TGFX_USE_METAL AND NOT TGFX_USE_OPENGL AND NOT TGFX_USE_VULKAN AND NOT TGFX_USE_D3D12)
message(FATAL_ERROR "At least one GPU backend (TGFX_USE_METAL, TGFX_USE_OPENGL, TGFX_USE_VULKAN, or TGFX_USE_D3D12) must be enabled.")
endif ()

message("TGFX_VERSION: ${TGFX_VERSION}")
Expand All @@ -135,6 +147,8 @@ message("TGFX_BUILD_LAYERS: ${TGFX_BUILD_LAYERS}")
message("TGFX_USE_OPENGL: ${TGFX_USE_OPENGL}")
message("TGFX_USE_METAL: ${TGFX_USE_METAL}")
message("TGFX_USE_VULKAN: ${TGFX_USE_VULKAN}")
message("TGFX_USE_D3D12: ${TGFX_USE_D3D12}")
message("TGFX_D3D12_USE_WARP: ${TGFX_D3D12_USE_WARP}")
message("TGFX_USE_QT: ${TGFX_USE_QT}")
message("TGFX_USE_SWIFTSHADER: ${TGFX_USE_SWIFTSHADER}")
message("TGFX_USE_ANGLE: ${TGFX_USE_ANGLE}")
Expand Down Expand Up @@ -192,7 +206,7 @@ file(GLOB PLATFORM_COMMON_FILES
src/platform/*.*)
list(APPEND TGFX_FILES ${PLATFORM_COMMON_FILES})

if (NOT TGFX_USE_METAL AND NOT TGFX_USE_VULKAN)
if (NOT TGFX_USE_METAL AND NOT TGFX_USE_VULKAN AND NOT TGFX_USE_D3D12)
file(GLOB SHADER_COMPILER_FILES src/gpu/ShaderCompiler.*)
if (SHADER_COMPILER_FILES)
list(REMOVE_ITEM TGFX_FILES ${SHADER_COMPILER_FILES})
Expand Down Expand Up @@ -371,6 +385,22 @@ elseif (APPLE)
endif ()
endif ()

if (TGFX_USE_D3D12)
file(GLOB_RECURSE GFX_PLATFORM_FILES src/gpu/d3d12/*.*)
list(APPEND TGFX_FILES ${GFX_PLATFORM_FILES})
list(APPEND TGFX_DEFINES TGFX_USE_D3D12)
if (TGFX_D3D12_USE_WARP)
# CI / headless opt-in: route DevicePool::Make() onto D3D12Device::MakeWarp() so the
# tests run on the WARP software rasterizer instead of expecting a hardware GPU.
list(APPEND TGFX_DEFINES TGFX_D3D12_USE_WARP)
endif ()
# Add shaderc and SPIRV-Cross for GLSL to HLSL conversion
list(APPEND TGFX_STATIC_VENDORS shaderc SPIRV-Cross)
list(APPEND TGFX_INCLUDES third_party/shaderc/libshaderc/include)
list(APPEND TGFX_INCLUDES third_party/SPIRV-Cross)
list(APPEND TGFX_DEFINES SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
endif ()

# Auto-sync shaderc sub-dependencies (glslang, SPIRV-Tools, etc.) if any backend needs shaderc.
# This runs at configure time; for offline builds, run manually before cmake:
# python third_party/shaderc/utils/git-sync-deps
Expand Down Expand Up @@ -596,7 +626,14 @@ elseif (WIN32)
file(GLOB_RECURSE PLATFORM_FILES src/platform/win/*.*)
list(APPEND TGFX_FILES ${PLATFORM_FILES})

if (TGFX_USE_NATIVE_GL)
if (TGFX_USE_D3D12)
find_library(D3D12_LIB d3d12)
list(APPEND TGFX_STATIC_LIBS ${D3D12_LIB})
find_library(DXGI_LIB dxgi)
list(APPEND TGFX_STATIC_LIBS ${DXGI_LIB})
find_library(D3DCOMPILER_LIB d3dcompiler)
list(APPEND TGFX_STATIC_LIBS ${D3DCOMPILER_LIB})
elseif (TGFX_USE_NATIVE_GL)
file(GLOB_RECURSE GPU_PLATFORM_FILES src/gpu/opengl/wgl/*.*)
find_library(OPENGL_LIB opengl32)
list(APPEND TGFX_STATIC_LIBS ${OPENGL_LIB})
Expand Down Expand Up @@ -715,6 +752,10 @@ if (TGFX_BUILD_TESTS)
if (TGFX_TEST_VULKAN_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_VULKAN_FILES})
endif ()
file(GLOB_RECURSE TGFX_TEST_D3D12_FILES test/src/d3d12/*.*)
if (TGFX_TEST_D3D12_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_D3D12_FILES})
endif ()
elseif (TGFX_USE_VULKAN)
file(GLOB_RECURSE TGFX_TEST_OPENGL_FILES test/src/opengl/*.*)
if (TGFX_TEST_OPENGL_FILES)
Expand All @@ -724,13 +765,34 @@ if (TGFX_BUILD_TESTS)
if (TGFX_TEST_METAL_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_METAL_FILES})
endif ()
file(GLOB_RECURSE TGFX_TEST_D3D12_FILES test/src/d3d12/*.*)
if (TGFX_TEST_D3D12_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_D3D12_FILES})
endif ()
elseif (TGFX_USE_D3D12)
file(GLOB_RECURSE TGFX_TEST_OPENGL_FILES test/src/opengl/*.*)
if (TGFX_TEST_OPENGL_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_OPENGL_FILES})
endif ()
file(GLOB_RECURSE TGFX_TEST_METAL_FILES test/src/metal/*.*)
if (TGFX_TEST_METAL_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_METAL_FILES})
endif ()
file(GLOB_RECURSE TGFX_TEST_VULKAN_FILES test/src/vulkan/*.*)
if (TGFX_TEST_VULKAN_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_VULKAN_FILES})
endif ()
else ()
file(GLOB_RECURSE TGFX_TEST_METAL_FILES test/src/metal/*.*)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_METAL_FILES})
file(GLOB_RECURSE TGFX_TEST_VULKAN_FILES test/src/vulkan/*.*)
if (TGFX_TEST_VULKAN_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_VULKAN_FILES})
endif ()
file(GLOB_RECURSE TGFX_TEST_D3D12_FILES test/src/d3d12/*.*)
if (TGFX_TEST_D3D12_FILES)
list(REMOVE_ITEM TGFX_TEST_FILES ${TGFX_TEST_D3D12_FILES})
endif ()
endif ()

file(GLOB_RECURSE TGFX_TEST_WEBGL_FILES test/src/webgl/*.*)
Expand Down
45 changes: 44 additions & 1 deletion include/tgfx/gpu/Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include "tgfx/gpu/PixelFormat.h"
#include "tgfx/gpu/d3d12/D3D12Types.h"
#include "tgfx/gpu/metal/MetalTypes.h"
#include "tgfx/gpu/opengl/GLTypes.h"
#include "tgfx/gpu/vulkan/VulkanTypes.h"
Expand All @@ -27,7 +28,7 @@ namespace tgfx {
/**
* Possible GPU backend APIs that may be used by TGFX.
*/
enum class Backend { Unknown, OpenGL, Metal, Vulkan, WebGPU };
enum class Backend { Unknown, OpenGL, Metal, Vulkan, WebGPU, D3D12 };

/**
* Wrapper class for passing into and receiving data from TGFX about a backend texture object.
Expand Down Expand Up @@ -61,6 +62,13 @@ class BackendTexture {
: _backend(Backend::Vulkan), _width(width), _height(height), vulkanInfo(vulkanInfo) {
}

/**
* Creates a D3D12 backend texture.
*/
explicit BackendTexture(const D3D12TextureInfo& d3d12Info, int width, int height)
: _backend(Backend::D3D12), _width(width), _height(height), d3d12Info(d3d12Info) {
}

BackendTexture(const BackendTexture& that) {
*this = that;
}
Expand Down Expand Up @@ -118,6 +126,12 @@ class BackendTexture {
*/
bool getVulkanImageInfo(VulkanImageInfo* vulkanImageInfo) const;

/**
* If the backend API is D3D12, copies a snapshot of the D3D12TextureInfo struct into the passed
* in pointer and returns true. Otherwise, returns false if the backend API is not D3D12.
*/
bool getD3D12TextureInfo(D3D12TextureInfo* d3d12TextureInfo) const;

private:
Backend _backend = Backend::Unknown;
int _width = 0;
Expand All @@ -127,6 +141,7 @@ class BackendTexture {
GLTextureInfo glInfo;
MetalTextureInfo metalInfo;
VulkanImageInfo vulkanInfo;
D3D12TextureInfo d3d12Info;
};
};

Expand Down Expand Up @@ -162,6 +177,13 @@ class BackendRenderTarget {
: _backend(Backend::Vulkan), _width(width), _height(height), vulkanInfo(vulkanInfo) {
}

/**
* Creates a D3D12 backend render target.
*/
explicit BackendRenderTarget(const D3D12TextureInfo& d3d12Info, int width, int height)
: _backend(Backend::D3D12), _width(width), _height(height), d3d12Info(d3d12Info) {
}

BackendRenderTarget(const BackendRenderTarget& that) {
*this = that;
}
Expand Down Expand Up @@ -219,6 +241,12 @@ class BackendRenderTarget {
*/
bool getVulkanImageInfo(VulkanImageInfo* vulkanImageInfo) const;

/**
* If the backend API is D3D12, copies a snapshot of the D3D12TextureInfo struct into the passed
* in pointer and returns true. Otherwise, returns false if the backend API is not D3D12.
*/
bool getD3D12TextureInfo(D3D12TextureInfo* d3d12TextureInfo) const;

private:
Backend _backend = Backend::Unknown;
int _width = 0;
Expand All @@ -227,6 +255,7 @@ class BackendRenderTarget {
GLFrameBufferInfo glInfo;
MetalTextureInfo metalInfo;
VulkanImageInfo vulkanInfo;
D3D12TextureInfo d3d12Info;
};
};

Expand Down Expand Up @@ -262,6 +291,13 @@ class BackendSemaphore {
: _backend(Backend::Vulkan), vulkanSyncInfo(vulkanInfo) {
}

/**
* Creates a D3D12 backend semaphore.
*/
explicit BackendSemaphore(const D3D12SyncInfo& d3d12Info)
: _backend(Backend::D3D12), d3d12SyncInfo(d3d12Info) {
}

BackendSemaphore(const BackendSemaphore& that) {
*this = that;
}
Expand Down Expand Up @@ -298,12 +334,19 @@ class BackendSemaphore {
*/
bool getVulkanSync(VulkanSyncInfo* vulkanSyncInfo) const;

/**
* If the backend API is D3D12, copies a snapshot of the D3D12SyncInfo struct into the passed in
* pointer and returns true. Otherwise, returns false if the backend API is not D3D12.
*/
bool getD3D12Sync(D3D12SyncInfo* d3d12Info) const;

private:
Backend _backend = Backend::Unknown;
union {
GLSyncInfo glSyncInfo;
MetalSyncInfo metalSyncInfo;
VulkanSyncInfo vulkanSyncInfo;
D3D12SyncInfo d3d12SyncInfo;
};
};
} // namespace tgfx
66 changes: 66 additions & 0 deletions include/tgfx/gpu/d3d12/D3D12Device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2026 Tencent. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#include "tgfx/gpu/Device.h"

namespace tgfx {

/**
* The D3D12 interface for drawing graphics.
*/
class D3D12Device : public Device {
public:
/**
* Creates a new D3D12Device using the default hardware adapter. Returns nullptr if D3D12 is not
* available.
*/
static std::shared_ptr<D3D12Device> Make();

/**
* Creates a new D3D12Device backed by the WARP software rasterizer. WARP is a CPU-based D3D12
* implementation that ships with Windows; it is functionally complete (feature level 12_1) but
* orders of magnitude slower than a real GPU. Intended for headless CI runners and other
* environments without a usable hardware adapter — do not rely on it for performance work.
* Returns nullptr if WARP is unavailable on the current system.
*/
static std::shared_ptr<D3D12Device> MakeWarp();

/**
* Creates a new D3D12Device from an existing ID3D12Device. The device parameter is a pointer to
* an ID3D12Device object. Returns nullptr if the device is invalid.
*/
static std::shared_ptr<D3D12Device> MakeFrom(void* device);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注释未说明 device 参数的具体类型(ID3D12Device*)和所有权语义。调用者不清楚:1)void* 实际指向何种类型;2)tgfx 是否对该对象调用 AddRef,以及何时/是否调用 Release。建议补全,例如:@param device A pointer to an existing ID3D12Device. The caller retains ownership; tgfx internally calls QueryInterface (AddRef) and releases its own reference when the D3D12Device is destroyed.


~D3D12Device() override;

/**
* Returns the underlying ID3D12Device as a raw pointer.
*/
void* d3d12Device() const;

protected:
bool onLockContext() override;
void onUnlockContext() override;

private:
explicit D3D12Device(std::unique_ptr<class D3D12GPU> gpu);
};

} // namespace tgfx
60 changes: 60 additions & 0 deletions include/tgfx/gpu/d3d12/D3D12Types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2026 Tencent. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#include <cstdint>
#include <type_traits>

namespace tgfx {
/**
* Types for interacting with D3D12 textures created externally to TGFX.
*/
struct D3D12TextureInfo {
/**
* Pointer to an ID3D12Resource object representing a texture.
*/
const void* resource = nullptr;

/**
* The pixel format of this texture (DXGI_FORMAT value).
*/
unsigned format = 0; // DXGI_FORMAT_UNKNOWN
};

/**
* Types for interacting with D3D12 synchronization objects created externally to TGFX.
*/
struct D3D12SyncInfo {
/**
* Pointer to an ID3D12Fence object.
*/
const void* fence = nullptr;

/**
* The signal value for the fence.
*/
uint64_t value = 0;
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【P14 中】缺少与 VulkanTypes.h 对齐的 static_assert

证据:include/tgfx/gpu/vulkan/VulkanTypes.h:64-67 有:

static_assert(std::is_trivially_copyable_v<VulkanImageInfo>);
static_assert(std::is_trivially_copyable_v<VulkanSyncInfo>);
static_assert(std::is_standard_layout_v<VulkanImageInfo>);
static_assert(std::is_standard_layout_v<VulkanSyncInfo>);

本文件没有等价校验。

影响:未来若有人为 D3D12TextureInfo 加了 std::string 等非 trivially-copyable 字段,编译期不会报错;但 BackendTexture 把它放进 union 里(Backend.h:140-145),运行时拷贝/析构会 UB。

建议:在文件结尾加四条:

static_assert(std::is_trivially_copyable_v<D3D12TextureInfo>);
static_assert(std::is_trivially_copyable_v<D3D12SyncInfo>);
static_assert(std::is_standard_layout_v<D3D12TextureInfo>);
static_assert(std::is_standard_layout_v<D3D12SyncInfo>);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


static_assert(std::is_trivially_copyable_v<D3D12TextureInfo>);
static_assert(std::is_trivially_copyable_v<D3D12SyncInfo>);
static_assert(std::is_standard_layout_v<D3D12TextureInfo>);
static_assert(std::is_standard_layout_v<D3D12SyncInfo>);

} // namespace tgfx
Loading
Loading