Skip to content

Commit d650c92

Browse files
committed
✨ Add mip map generation
1 parent e8c2735 commit d650c92

File tree

9 files changed

+128
-50
lines changed

9 files changed

+128
-50
lines changed

Plugin/PluginInteropUnityCUDA/include/RenderAPI/renderAPI_D3D11.h

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#pragma once
2-
#include "renderAPI.h"
32
#include "framework.h"
43
#include "log.h"
4+
#include "renderAPI.h"
55
// Direct3D 11 implementation of RenderAPI.
66

77
#if SUPPORT_D3D11
88

9-
#include "d3d11.h"
109
#include "IUnityGraphicsD3D11.h"
10+
#include "d3d11.h"
1111
#include <assert.h>
1212

1313
class RenderAPI_D3D11 : public RenderAPI
@@ -17,31 +17,57 @@ class RenderAPI_D3D11 : public RenderAPI
1717
virtual ~RenderAPI_D3D11();
1818
virtual void ProcessDeviceEvent(UnityGfxDeviceEventType type,
1919
IUnityInterfaces *interfaces);
20-
2120

21+
/**
22+
* @brief Creates a shader resource with current context
23+
*
24+
* @param resource The resource which is associated to shader
25+
* resource
26+
* @param shaderResource The shader resource to create (out param)
27+
*
28+
* @return -1, if device has not been set, -2 if dx11 failed to create
29+
* the texture, else 0
30+
*/
31+
int createShaderResource(ID3D11Resource *resource,
32+
ID3D11ShaderResourceView **shaderResource);
2233

23-
/// <summary>
24-
/// Create a 2D texture with the given paramaters
25-
/// return -1, if device has not been set, -2 if dx11
26-
/// failed to create the texture, else 0
27-
/// </summary>
34+
/**
35+
* @brief Create a 2D texture with the given paramaters
36+
*
37+
* @param[in] textureWidth The texture width
38+
* @param[in] textureHeight The texture height
39+
* @param[in] textureDepth The texture depth
40+
* @param textureHandle The texture handle
41+
*
42+
* @return -1, if device has not been set, -2 if dx11 failed to create
43+
* the texture, else 0
44+
*/
2845
int createTexture2D(int textureWidth, int textureHeight, int textureDepth,
29-
ID3D11Texture2D **textureHandle);
30-
31-
/// <summary>
32-
/// Copy the content of texture 2D src to texture 2D dest
33-
/// This method is UNSAFE, because for efficiency reason it
34-
/// doesn't check if src and dest textures are compatible
35-
/// Therefore, make sure to have compatible textures. See
36-
/// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-copyresource
37-
/// for more details
38-
/// </summary>
39-
void copyTextures2D(ID3D11Texture2D* dest, ID3D11Texture2D* src);
40-
46+
ID3D11Texture2D **textureHandle);
47+
48+
/**
49+
* @brief Copy the content of texture 2D src to texture 2D dest
50+
This method is UNSAFE, because for efficiency reason it
51+
doesn't check if src and dest textures are compatible
52+
Therefore, make sure to have compatible textures. See
53+
https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-copyresource
54+
for more details
55+
*
56+
* @param dest The destination texture
57+
* @param src The source texture
58+
*/
59+
void copyTextures2D(ID3D11Texture2D *dest, ID3D11Texture2D *src);
60+
61+
/**
62+
* @brief Gets the current context.
63+
*
64+
* @return The current context.
65+
*/
66+
ID3D11DeviceContext * getCurrentContext();
4167

4268
private:
4369
ID3D11Device *_device;
44-
ID3D11DeviceContext* _context{};
70+
ID3D11DeviceContext *_context{};
4571
};
4672

4773
RenderAPI *CreateRenderAPI_D3D11();

Plugin/PluginInteropUnityCUDA/include/Texture/texture.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ class Texture
7474
*/
7575
UNITY_INTERFACE_EXPORT int unmapTextureToSurfaceObject();
7676

77+
/**
78+
* Generate the mips maps of the texture
79+
*/
80+
UNITY_INTERFACE_EXPORT virtual int generateMips() = 0;
81+
82+
7783
/**
7884
* Get the default dimension block (8,8,1)
7985
*/

Plugin/PluginInteropUnityCUDA/include/Texture/texture_D3D11.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33

44
#if SUPPORT_D3D11
55

6+
#include "IUnityGraphicsD3D11.h"
7+
#include "d3d11.h"
68
#include "renderAPI_D3D11.h"
79
#include <assert.h>
810
#include <cuda_d3d11_interop.h>
9-
#include "IUnityGraphicsD3D11.h"
10-
#include "d3d11.h"
11-
1211

1312
/**
14-
* @brief This class handles interoperability for texture from Unity to CUDA, with
15-
* dx11 graphics API. With dx11 interoperability work differently, texture
16-
* created in Unity, cannot be directly registered in CUDA, therefore we need
17-
* to create another texture
13+
* @brief This class handles interoperability for texture from Unity to
14+
* CUDA, with dx11 graphics API. With dx11 interoperability work differently,
15+
* texture created in Unity, cannot be directly registered in CUDA, therefore we
16+
* need to create another texture
1817
* (_texBufferInterop) that will be used as a buffer. We will copy the content
1918
* of the texture created in Unity and then we will registered this new texture
2019
* in CUDA see issue #2 on github for more details
@@ -28,6 +27,7 @@ class Texture_D3D11 : public Texture
2827

2928
virtual int registerTextureInCUDA();
3029
virtual int unregisterTextureInCUDA();
30+
virtual int generateMips();
3131

3232
protected:
3333
virtual int copyUnityTextureToAPITexture();
@@ -37,6 +37,7 @@ class Texture_D3D11 : public Texture
3737
int copyUnityTextureToBuffer();
3838

3939
ID3D11Texture2D *_texBufferInterop{};
40+
ID3D11ShaderResourceView *_shaderResources;
4041
ID3D11Texture2D *_texUnityDX11{};
4142
RenderAPI_D3D11 *_renderAPI;
4243
};

Plugin/PluginInteropUnityCUDA/include/Texture/texture_OpenGLCoreES.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@ class Texture_OpenGLCoreES : public Texture
1717
~Texture_OpenGLCoreES();
1818
virtual int registerTextureInCUDA();
1919
virtual int unregisterTextureInCUDA();
20+
virtual int generateMips();
21+
2022
protected:
2123
virtual int copyUnityTextureToAPITexture();
2224
virtual int copyAPITextureToUnityTexture();
25+
private:
26+
GLuint _texUnityGL;
27+
GLenum _texTarget;
2328
};
2429

2530
#endif

Plugin/PluginInteropUnityCUDA/src/RenderAPI/renderAPI_D3D11.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,35 @@ int RenderAPI_D3D11::createTexture2D(int textureWidth, int textureHeight,
5151
return 0;
5252
}
5353

54+
int RenderAPI_D3D11::createShaderResource(
55+
ID3D11Resource *resource, ID3D11ShaderResourceView **shaderResource)
56+
{
57+
if (_device == NULL)
58+
{
59+
Log::log().debugLogError(
60+
"m_Device has not been initialized in RenderAPI_D3D11, please make "
61+
"sure event kUnityGfxDeviceEventInitialize has been called "
62+
"before.");
63+
return -1;
64+
}
65+
66+
_device->CreateShaderResourceView(resource, NULL, shaderResource);
67+
return 0;
68+
}
69+
5470
void RenderAPI_D3D11::copyTextures2D(ID3D11Texture2D *dest,
5571
ID3D11Texture2D *src)
5672
{
5773
_device->GetImmediateContext(&_context);
5874
_context->CopyResource(dest, src);
5975
}
6076

77+
ID3D11DeviceContext *RenderAPI_D3D11::getCurrentContext()
78+
{
79+
_device->GetImmediateContext(&_context);
80+
return _context;
81+
}
82+
6183

6284
void RenderAPI_D3D11::ProcessDeviceEvent(UnityGfxDeviceEventType type,
6385
IUnityInterfaces *interfaces)

Plugin/PluginInteropUnityCUDA/src/Texture/texture_D3D11.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,11 @@ Texture_D3D11::~Texture_D3D11()
2323
int Texture_D3D11::registerTextureInCUDA()
2424
{
2525
// texture2D and texture2D array are ID3D11Texture2D in Unity for DX11
26-
ID3D11Texture2D *texUnityDX11 = (ID3D11Texture2D *)_textureHandle;
26+
_texUnityDX11 = (ID3D11Texture2D *)_textureHandle;
2727

2828
D3D11_TEXTURE2D_DESC texDesc;
29-
texUnityDX11->GetDesc(&texDesc);
30-
29+
_texUnityDX11->GetDesc(&texDesc);
3130
DXGI_FORMAT format = texDesc.Format;
32-
3331
// We check if the format is correct see
3432
// https://github.com/davidAlgis/InteropUnityCUDA/issues/2
3533
if (format == DXGI_FORMAT_R8G8B8A8_TYPELESS ||
@@ -48,19 +46,30 @@ int Texture_D3D11::registerTextureInCUDA()
4846
return -1;
4947
}
5048

49+
// we generate the shader resource in case the user want to use them (eg. for mips generation)
50+
_renderAPI->createShaderResource(_texUnityDX11, &_shaderResources);
51+
5152
// register the texture to cuda : it initialize the _pGraphicsResource
5253
CUDA_CHECK_RETURN(cudaGraphicsD3D11RegisterResource(
53-
&_graphicsResource, texUnityDX11, cudaGraphicsRegisterFlagsNone));
54+
&_graphicsResource, _texUnityDX11, cudaGraphicsRegisterFlagsNone));
5455

5556
return SUCCESS_INTEROP_CODE;
5657
}
5758

59+
5860
int Texture_D3D11::unregisterTextureInCUDA()
5961
{
6062
CUDA_CHECK_RETURN(cudaGraphicsUnregisterResource(_graphicsResource));
6163
return SUCCESS_INTEROP_CODE;
6264
}
6365

66+
int Texture_D3D11::generateMips()
67+
{
68+
_renderAPI->getCurrentContext()->GenerateMips(_shaderResources);
69+
return SUCCESS_INTEROP_CODE;
70+
}
71+
72+
6473
int Texture_D3D11::copyUnityTextureToAPITexture()
6574
{
6675
_renderAPI->copyTextures2D(_texBufferInterop, _texUnityDX11);

Plugin/PluginInteropUnityCUDA/src/Texture/texture_OpenGLCoreES.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ Texture_OpenGLCoreES::~Texture_OpenGLCoreES()
2020
int Texture_OpenGLCoreES::registerTextureInCUDA()
2121
{
2222
// if depth is < 2 it's a texture2D, else it's a texture2DArray
23-
GLenum target = _textureDepth < 2 ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY;
23+
_texTarget = _textureDepth < 2 ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY;
2424

2525
// cast the pointer on the texture of unity to gluint
26-
GLuint gltex = (GLuint)(size_t)(_textureHandle);
27-
// glBindTexture(target, gltex);
26+
_texUnityGL = (GLuint)(size_t)(_textureHandle);
2827
GL_CHECK();
2928
// register the texture to cuda : it initialize the _pGraphicsResource
3029
CUDA_CHECK_RETURN(
31-
cudaGraphicsGLRegisterImage(&_graphicsResource, gltex, target,
30+
cudaGraphicsGLRegisterImage(&_graphicsResource, _texUnityGL, _texTarget,
3231
cudaGraphicsRegisterFlagsWriteDiscard));
3332
return SUCCESS_INTEROP_CODE;
3433
}
@@ -41,14 +40,21 @@ int Texture_OpenGLCoreES::unregisterTextureInCUDA()
4140

4241
int Texture_OpenGLCoreES::copyUnityTextureToAPITexture()
4342
{
44-
return SUCCESS_INTEROP_CODE;
43+
Log::log().debugLogError("copyUnityTextureToAPITexture - Not implemented yet");
44+
return -1;
4545
}
4646

4747
int Texture_OpenGLCoreES::copyAPITextureToUnityTexture()
4848
{
49-
return SUCCESS_INTEROP_CODE;
49+
Log::log().debugLogError("copyAPITextureToUnityTexture - Not implemented yet");
50+
return -1;
5051
}
5152

52-
53+
int Texture_OpenGLCoreES::generateMips()
54+
{
55+
glGenerateMipmap(_texUnityGL);
56+
GL_CHECK();
57+
return SUCCESS_INTEROP_CODE;
58+
}
5359

5460
#endif // #if SUPPORT_OPENGL_UNIFIED

Plugin/PluginInteropUnityCUDA/thirdParty/unity/include/IUnityGraphicsD3D11.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22
#include "IUnityInterface.h"
3-
3+
#include "d3d11.h"
44

55
// Should only be used on the rendering thread unless noted otherwise.
66
UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D11)

Plugin/SampleBasic/src/action_sample_texture.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ inline int ActionSampleTexture::Start()
1616
{
1717
int ret = _texture->registerTextureInCUDA();
1818
GRUMBLE(ret, "There has been an error during the registration of "
19-
"the texture in CUDA. Abort ActionSampleTexture !");
19+
"the texture in CUDA. Abort ActionSampleTexture !");
2020
ret = _texture->mapTextureToSurfaceObject();
2121
GRUMBLE(ret, "There has been an error during the map of "
22-
"the texture to surface object in CUDA. Abort "
23-
"ActionSampleTexture !");
22+
"the texture to surface object in CUDA. Abort "
23+
"ActionSampleTexture !");
2424
return 0;
2525
}
2626

@@ -30,21 +30,24 @@ int ActionSampleTexture::Update()
3030
_texture->getSurfaceObject(), GetTime(),
3131
_texture->getWidth(), _texture->getHeight());
3232
cudaDeviceSynchronize();
33-
int ret = CUDA_CHECK(cudaGetLastError());
34-
GRUMBLE(ret, "There has been an error during the update. "
35-
"Abort ActionSampleTexture !");
33+
// GRUMBLE(_texture->generateMips(),
34+
// "There has been an error during the mip map generation."
35+
// "Abord ActionSampleTexture !");
36+
GRUMBLE(CUDA_CHECK(cudaGetLastError()),
37+
"There has been an error during the update. "
38+
"Abort ActionSampleTexture !");
3639
return 0;
3740
}
3841

3942
inline int ActionSampleTexture::OnDestroy()
4043
{
4144
int ret = _texture->unmapTextureToSurfaceObject();
4245
GRUMBLE(ret, "There has been an error during the unmap of "
43-
"the texture to surface object in CUDA. Abort "
44-
"ActionSampleTexture !");
46+
"the texture to surface object in CUDA. Abort "
47+
"ActionSampleTexture !");
4548
ret = _texture->unregisterTextureInCUDA();
4649
GRUMBLE(ret, "There has been an error during the unregistration of "
47-
"the texture in CUDA. Abort ActionSampleTexture !");
50+
"the texture in CUDA. Abort ActionSampleTexture !");
4851
return 0;
4952
}
5053

0 commit comments

Comments
 (0)