Skip to content

Commit c1e60f3

Browse files
committed
✨🚧 Support DX11 on textures by adding a copy (see #2 (comment))
1 parent 969d0c6 commit c1e60f3

File tree

10 files changed

+344
-235
lines changed

10 files changed

+344
-235
lines changed

InteropUnityCUDA/Assets/Actions/InteropHandlerSample.cs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,39 @@ protected override void InitializeActions()
127127
Debug.LogError("Set particles drawer in inspector !");
128128
return;
129129
}
130+
InitSampleTexture();
131+
// InitSampleTextureArray();
132+
// InitSampleVertexBuffer();
130133

131-
CreateBuffer();
134+
}
135+
136+
private void InitSampleTexture()
137+
{
132138
CreateTexture();
133-
CreateTextureArray();
134139
ActionUnitySampleTexture actionUnitySampleTexture = new ActionUnitySampleTexture(_renderTexture);
135-
ActionUnitySampleVertexBuffer actionUnitySampleVertexBuffer = new ActionUnitySampleVertexBuffer(_computeBuffer, _sizeBuffer);
136-
ActionUnitySampleTextureArray actionUnitySampleTextureArray = new ActionUnitySampleTextureArray(_renderTextureArray);
137140
RegisterActionUnity(actionUnitySampleTexture, _ActionTextureName);
138-
RegisterActionUnity(actionUnitySampleVertexBuffer, _ActionVertexBufferName);
139-
RegisterActionUnity(actionUnitySampleTextureArray, _ActionTextureArrayName);
140141
CallFunctionStartInAction(_ActionTextureName);
141-
CallFunctionStartInAction(_ActionVertexBufferName);
142+
143+
}
144+
145+
private void InitSampleTextureArray()
146+
{
147+
CreateTextureArray();
148+
ActionUnitySampleTextureArray actionUnitySampleTextureArray = new ActionUnitySampleTextureArray(_renderTextureArray);
149+
RegisterActionUnity(actionUnitySampleTextureArray, _ActionTextureArrayName);
142150
CallFunctionStartInAction(_ActionTextureArrayName);
151+
143152
}
144153

154+
private void InitSampleVertexBuffer()
155+
{
156+
CreateBuffer();
157+
ActionUnitySampleVertexBuffer actionUnitySampleVertexBuffer = new ActionUnitySampleVertexBuffer(_computeBuffer, _sizeBuffer);
158+
RegisterActionUnity(actionUnitySampleVertexBuffer, _ActionVertexBufferName);
159+
CallFunctionStartInAction(_ActionVertexBufferName);
160+
161+
}
162+
145163
public void Update()
146164
{
147165
UpdateInteropHandler();
@@ -153,18 +171,18 @@ public void Update()
153171
protected override void UpdateActions()
154172
{
155173
base.UpdateActions();
156-
CallFunctionUpdateInAction(_ActionTextureArrayName);
174+
// CallFunctionUpdateInAction(_ActionTextureArrayName);
157175
CallFunctionUpdateInAction(_ActionTextureName);
158-
CallFunctionUpdateInAction(_ActionVertexBufferName);
159-
Graphics.CopyTexture(_renderTextureArray,0,_renderTextureForDisplay0,0);
160-
Graphics.CopyTexture(_renderTextureArray,1,_renderTextureForDisplay1,0);
161-
_rawImageTextureArray0.texture = _renderTextureForDisplay0;
162-
_rawImageTextureArray1.texture = _renderTextureForDisplay1;
176+
// CallFunctionUpdateInAction(_ActionVertexBufferName);
177+
// Graphics.CopyTexture(_renderTextureArray,0,_renderTextureForDisplay0,0);
178+
// Graphics.CopyTexture(_renderTextureArray,1,_renderTextureForDisplay1,0);
179+
// _rawImageTextureArray0.texture = _renderTextureForDisplay0;
180+
// _rawImageTextureArray1.texture = _renderTextureForDisplay1;
163181
}
164182

165183
public void OnDestroy()
166184
{
167-
OnDestroyInteropHandler();
185+
// OnDestroyInteropHandler();
168186
}
169187

170188
/// <summary>
@@ -173,9 +191,9 @@ public void OnDestroy()
173191
protected override void OnDestroyActions()
174192
{
175193
base.OnDestroyActions();
176-
CallFunctionOnDestroyInAction(_ActionTextureArrayName);
177194
CallFunctionOnDestroyInAction(_ActionTextureName);
178-
CallFunctionOnDestroyInAction(_ActionVertexBufferName);
195+
// CallFunctionOnDestroyInAction(_ActionTextureArrayName);
196+
// CallFunctionOnDestroyInAction(_ActionVertexBufferName);
179197
}
180198
}
181199

Plugin/PluginInteropUnityCUDA/include/Texture/texture.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,34 @@ class Texture
3131
/// </summary>
3232
UNITY_INTERFACE_EXPORT virtual void unRegisterTextureInCUDA() = 0;
3333

34+
35+
/// <summary>
36+
/// For some API (DX11) CUDA cannot edit the texture created by Unity
37+
/// therefore, we have to create a new texture that will used as a buffer
38+
/// between the unity texture and the surface object that is modify by CUDA
39+
/// For these API, this function will copy the content of the unity texture
40+
/// to this buffer, for the other API. It'll do nothing.
41+
/// If Unity texture has been modify in Unity, you have to do the copy before
42+
/// reading it in CUDA. It's not necessary if you only write into the texture
43+
/// in CUDA, or if the texture has not been modify in Unity.
44+
/// Tips : not necessary for write only in CUDA or read only in Unity
45+
/// </summary>
46+
UNITY_INTERFACE_EXPORT virtual void copyUnityTextureToAPITexture() = 0;
47+
48+
49+
/// <summary>
50+
/// For some API (DX11) CUDA cannot edit the texture created by Unity
51+
/// therefore, we have to create a new texture that will used as a buffer
52+
/// between the unity texture and the surface object that is modify by CUDA
53+
/// For these API, this function will copy the content of the buffer texture
54+
/// to the unity texture, for the other API. It'll do nothing.
55+
/// If API texture has been modify by, you have to do the copy before
56+
/// reading it in Unity. It's not necessary if you only read into the texture
57+
/// in CUDA, or if the texture is only write only in Unity.
58+
/// Tips : not necessary for read only in CUDA or write only in Unity
59+
/// </summary>
60+
UNITY_INTERFACE_EXPORT virtual void copyAPITextureToUnityTexture() = 0;
61+
3462
/// <summary>
3563
/// Map a cuda array to the graphics resources and wrap it into a surface
3664
/// object of cuda
Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
11
#pragma once
2-
// Direct3D 11 implementation of Texture API
32
#include "texture.h"
43

5-
64
#if SUPPORT_D3D11
75

8-
#include <d3d11.h>
6+
#include "renderAPI_D3D11.h"
7+
#include <assert.h>
98
#include <cuda_d3d11_interop.h>
109
#include "IUnityGraphicsD3D11.h"
11-
#include <assert.h>
10+
#include "d3d11.h"
1211

12+
/// <summary>
13+
/// This class handles interoperability for texture from Unity to CUDA, with
14+
/// dx11 graphics API. With dx11 interoperability work differently, texture
15+
/// created in Unity, cannot be directly registered in CUDA, therefore we need
16+
/// to create another texture
17+
/// (_texBufferInterop) that will be used as a buffer. We will copy the content
18+
/// of the texture created in Unity and then we will registered this new texture
19+
/// in CUDA see issue #2 on github for more details
20+
/// </summary>
1321
class Texture_D3D11 : public Texture
1422
{
15-
public:
16-
Texture_D3D11(void* textureHandle, int textureWidth, int textureHeight, int textureDepth);
17-
~Texture_D3D11();
18-
virtual void registerTextureInCUDA();
19-
virtual void unRegisterTextureInCUDA();
23+
public:
24+
Texture_D3D11(void *textureHandle, int textureWidth, int textureHeight,
25+
int textureDepth, RenderAPI *renderAPI);
26+
~Texture_D3D11();
27+
virtual void registerTextureInCUDA();
28+
virtual void unRegisterTextureInCUDA();
29+
30+
protected:
31+
virtual void copyUnityTextureToAPITexture();
32+
virtual void copyAPITextureToUnityTexture();
33+
34+
private:
35+
int copyUnityTextureToBuffer();
2036

37+
ID3D11Texture2D *_texBufferInterop{};
38+
ID3D11Texture2D *_texUnityDX11{};
39+
RenderAPI_D3D11 *_renderAPI;
2140
};
2241

2342
#endif

Plugin/PluginInteropUnityCUDA/include/Texture/texture_OpenGLCoreES.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ class Texture_OpenGLCoreES : public Texture
1717
~Texture_OpenGLCoreES();
1818
virtual void registerTextureInCUDA();
1919
virtual void unRegisterTextureInCUDA();
20-
20+
protected:
21+
virtual void copyUnityTextureToAPITexture();
22+
virtual void copyAPITextureToUnityTexture();
2123
};
2224

2325
#endif
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
#pragma once
2-
class VertexBuffer;
3-
class Texture;
2+
#include "texture_OpenGLCoreES.h"
3+
#include "vertex_buffer_OpenGLCoreES.h"
4+
#include "texture_D3D11.h"
5+
#include "vertex_buffer_D3D11.h"
6+
#include "renderAPI.h"
7+
48

59
/// <summary>
610
/// Simple factory template to create some vertex buffer or texture in function of API type
711
/// </summary>
812
namespace Factory
913
{
10-
VertexBuffer* createBuffer(void* bufferHandle, int size, UnityGfxRenderer apiType);
11-
Texture* createTexture(void* textureHandle, int textureWidth, int textureHeight, int textureDepth, UnityGfxRenderer apiType);
14+
VertexBuffer* createBuffer(void* bufferHandle, int size, UnityGfxRenderer apiType, RenderAPI* renderAPI);
15+
Texture* createTexture(void* textureHandle, int textureWidth, int textureHeight, int textureDepth, UnityGfxRenderer apiType, RenderAPI* renderAPI);
1216
}
1317

Plugin/PluginInteropUnityCUDA/src/Texture/texture_D3D11.cpp

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,73 @@
44
#if SUPPORT_D3D11
55

66
Texture_D3D11::Texture_D3D11(void *textureHandle, int textureWidth,
7-
int textureHeight, int textureDepth)
7+
int textureHeight, int textureDepth,
8+
RenderAPI *renderAPI)
89
: Texture(textureHandle, textureWidth, textureHeight, textureDepth)
910
{
11+
12+
// we need the render api associated to dx11, because we need device to
13+
// initialize texture
14+
_renderAPI = (RenderAPI_D3D11 *)renderAPI;
1015
}
1116

1217
Texture_D3D11::~Texture_D3D11()
1318
{
19+
_texBufferInterop->Release();
1420
CUDA_CHECK(cudaGetLastError());
1521
};
1622

1723
/// <summary>
1824
/// Has to be call after the first issue plugin event
1925
/// see. https://docs.unity3d.com/ScriptReference/GL.IssuePluginEvent.html
20-
/// register a graphics resources defined from the texture openGL
26+
/// register a graphics resources defined from the texture dx11
2127
/// </summary>
2228
void Texture_D3D11::registerTextureInCUDA()
2329
{
2430

25-
Log::log().debugLog("try register");
26-
ID3D11Texture2D *d3dtex = (ID3D11Texture2D *)_textureHandle;
27-
assert(d3dtex);
28-
// ID3D11DeviceContext* ctx = NULL;
29-
// m_Device->GetImmediateContext(&ctx);
30-
// ID3D11Resource* tex = (ID3D11Resource*)(_textureHandle);
31-
// HRESULT result = tex->GetDevice()->GetDeviceRemovedReason();
31+
// This method initialize the buffer textures that will be registered in
32+
// CUDA This method will use m_device attributes in RenderAPI_D3D11, make
33+
// sure it has been well initialized.
34+
int retCodeCreate = _renderAPI->createTexture2D(
35+
_textureWidth, _textureHeight, _textureDepth, &_texBufferInterop);
36+
// we initialize
37+
if (retCodeCreate < 0)
38+
{
39+
Log::log().debugLogError("Could not initialize texture on DX11 for "
40+
"copy. Interoperability has failed.");
41+
}
42+
43+
44+
// we cast it here, to make it only once.
45+
_texUnityDX11 = (ID3D11Texture2D *)_textureHandle;
46+
// assert(_texBufferInterop);
47+
// D3D11_TEXTURE2D_DESC texDesc;
48+
// _texBufferInterop->GetDesc(&texDesc);
49+
50+
// DXGI_FORMAT format = texDesc.Format;
51+
// Log::log().debugLog(std::to_string(format));
52+
53+
// CUDA_CHECK(cudaGetLastError());
3254
// register the texture to cuda : it initialize the _pGraphicsResource
3355
CUDA_CHECK(cudaGraphicsD3D11RegisterResource(
34-
&_pGraphicsResource, d3dtex, cudaGraphicsRegisterFlagsWriteDiscard));
35-
Log::log().debugLog("register");
56+
&_pGraphicsResource, _texBufferInterop, cudaGraphicsRegisterFlagsNone));
57+
CUDA_CHECK(cudaGetLastError());
3658
}
3759

3860
void Texture_D3D11::unRegisterTextureInCUDA()
3961
{
62+
4063
CUDA_CHECK(cudaGraphicsUnregisterResource(_pGraphicsResource));
4164
}
4265

66+
void Texture_D3D11::copyUnityTextureToAPITexture()
67+
{
68+
_renderAPI->copyTextures2D(_texBufferInterop, _texUnityDX11);
69+
}
70+
71+
void Texture_D3D11::copyAPITextureToUnityTexture()
72+
{
73+
_renderAPI->copyTextures2D(_texUnityDX11, _texBufferInterop);
74+
}
75+
4376
#endif // #if SUPPORT_D3D11

Plugin/PluginInteropUnityCUDA/src/Texture/texture_OpenGLCoreES.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,54 @@
33

44
#if SUPPORT_OPENGL_UNIFIED
55

6-
7-
Texture_OpenGLCoreES::Texture_OpenGLCoreES(void* textureHandle, int textureWidth, int textureHeight, int textureDepth)
8-
: Texture(textureHandle, textureWidth, textureHeight, textureDepth)
9-
{}
6+
Texture_OpenGLCoreES::Texture_OpenGLCoreES(void *textureHandle,
7+
int textureWidth, int textureHeight,
8+
int textureDepth)
9+
: Texture(textureHandle, textureWidth, textureHeight, textureDepth)
10+
{
11+
}
1012

1113
Texture_OpenGLCoreES::~Texture_OpenGLCoreES()
1214
{
13-
GL_CHECK();
14-
CUDA_CHECK(cudaGetLastError());
15+
GL_CHECK();
16+
CUDA_CHECK(cudaGetLastError());
1517
};
1618

1719
/// <summary>
18-
/// Has to be call after the first issue plugin event
19-
/// see. https://docs.unity3d.com/ScriptReference/GL.IssuePluginEvent.html
20+
/// Has to be call after the first issue plugin event
21+
/// see. https://docs.unity3d.com/ScriptReference/GL.IssuePluginEvent.html
2022
/// register a graphics resources defined from the texture openGL
2123
/// </summary>
2224
void Texture_OpenGLCoreES::registerTextureInCUDA()
2325
{
24-
// if depth is < 2 it's a texture2D, else it's a texture2DArray
25-
GLenum target = _textureDepth < 2 ? GL_TEXTURE_2D : GL_TEXTURE_3D;
26-
27-
// cast the pointer on the texture of unity to gluint
28-
GLuint gltex = (GLuint)(size_t)(_textureHandle);
29-
//glBindTexture(target, gltex);
30-
GL_CHECK();
31-
// register the texture to cuda : it initialize the _pGraphicsResource
32-
CUDA_CHECK(cudaGraphicsGLRegisterImage(&_pGraphicsResource, gltex, target, cudaGraphicsRegisterFlagsWriteDiscard));
26+
// if depth is < 2 it's a texture2D, else it's a texture2DArray
27+
GLenum target = _textureDepth < 2 ? GL_TEXTURE_2D : GL_TEXTURE_3D;
28+
29+
// cast the pointer on the texture of unity to gluint
30+
GLuint gltex = (GLuint)(size_t)(_textureHandle);
31+
// glBindTexture(target, gltex);
32+
GL_CHECK();
33+
// register the texture to cuda : it initialize the _pGraphicsResource
34+
CUDA_CHECK(
35+
cudaGraphicsGLRegisterImage(&_pGraphicsResource, gltex, target,
36+
cudaGraphicsRegisterFlagsWriteDiscard));
3337
}
3438

35-
3639
void Texture_OpenGLCoreES::unRegisterTextureInCUDA()
3740
{
38-
CUDA_CHECK(cudaGraphicsUnregisterResource(_pGraphicsResource));
41+
CUDA_CHECK(cudaGraphicsUnregisterResource(_pGraphicsResource));
42+
}
43+
44+
void Texture_OpenGLCoreES::copyUnityTextureToAPITexture()
45+
{
46+
47+
}
48+
49+
void Texture_OpenGLCoreES::copyAPITextureToUnityTexture()
50+
{
51+
3952
}
4053

54+
55+
4156
#endif // #if SUPPORT_OPENGL_UNIFIED

0 commit comments

Comments
 (0)