Skip to content

Commit

Permalink
D3D11: add _createShared2DTex() for WPF interop
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthurfernades authored and paroj committed Jan 19, 2025
1 parent 7ade80b commit 4d8caa7
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 1 deletion.
6 changes: 6 additions & 0 deletions OgreMain/include/OgreTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ namespace Ogre {
*/
TextureType getTextureType(void) const { return mTextureType; }

/** D3D11 only: set a shared surface to use for this texture before loading
*
* Useful for WPF interop
*/
virtual void _setSurface(void* surface) {}

/** Gets the number of mipmaps to be used for this texture.
*/
uint32 getNumMipmaps(void) const {return mNumMipmaps;}
Expand Down
6 changes: 6 additions & 0 deletions RenderSystems/Direct3D11/include/OgreD3D11Texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ namespace Ogre {
void _create1DTex();
/// internal method, create a blank normal 2D texture
void _create2DTex();
/// internal method to create a normal 2D texture with an already existing surface
void _createShared2DTex();
/// internal method, create a blank cube texture
void _create3DTex();

Expand All @@ -108,6 +110,8 @@ namespace Ogre {
/// mipmap level. This method must be called after the D3D texture object was created
void _createSurfaceList(void);

void _setSurface(void* surface) override;

void notifyDeviceLost(D3D11Device* device);
void notifyDeviceRestored(D3D11Device* device);

Expand All @@ -128,6 +132,8 @@ namespace Ogre {

D3D11_SHADER_RESOURCE_VIEW_DESC mSRVDesc;
bool mAutoMipMapGeneration;

void* mSurface;
};

/// RenderTexture implementation for D3D11
Expand Down
92 changes: 91 additions & 1 deletion RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ namespace Ogre
//---------------------------------------------------------------------
void D3D11Texture::_create2DTex()
{
if (mSurface)
{
_createShared2DTex();
return;
}
// we must have those defined here
assert(mSrcWidth > 0 || mSrcHeight > 0);

Expand Down Expand Up @@ -303,7 +308,90 @@ namespace Ogre

_create2DResourceView();
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void D3D11Texture::_createShared2DTex()
{
HRESULT hr = S_OK;

IUnknown* pUnk = (IUnknown*)mSurface;

IDXGIResource* pDXGIResource;
hr = pUnk->QueryInterface(__uuidof(IDXGIResource), (void**)&pDXGIResource);
if (FAILED(hr))
{
this->unloadImpl();
OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr,
"Error creating texture\nError Description: Failed to query IDXGIResource interface from "
"the provided object.",
"D3D11Texture::_create2DTex");
}

HANDLE sharedHandle;
hr = pDXGIResource->GetSharedHandle(&sharedHandle);
if (FAILED(hr))
{
this->unloadImpl();
OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr,
"Error creating texture\nError Description: Failed to retrieve the shared handle from "
"IDXGIResource. Ensure the resource was "
"created with the D3D11_RESOURCE_MISC_SHARED flag.",
"D3D11Texture::_create2DTex");
}

pDXGIResource->Release();

IUnknown* tempResource11;
hr = mDevice->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), (void**)(&tempResource11));
if (FAILED(hr))
{
this->unloadImpl();
OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr,
"Error creating texture\nError Description: Failed to open shared resource using the shared "
"handle. Ensure the handle is "
"valid and the device supports shared resources.",
"D3D11Texture::_create2DTex");
}

ID3D11Texture2D* pOutputResource;
hr = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&pOutputResource));
if (FAILED(hr))
{
this->unloadImpl();
OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr,
"Error creating texture\nError Description: Failed to query ID3D11Texture2D interface from "
"the shared resource. Ensure the "
"resource is of the correct type.",
"D3D11Texture::_create2DTex");
}
tempResource11->Release();

mp2DTex = pOutputResource;

D3D11_TEXTURE2D_DESC desc;
mp2DTex->GetDesc(&desc);

D3D11_RENDER_TARGET_VIEW_DESC rtDesc;
rtDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtDesc.Texture2D.MipSlice = 0;

ComPtr<ID3D11RenderTargetView> renderTargetView;
hr = mDevice->CreateRenderTargetView(mp2DTex.Get(), nullptr, renderTargetView.GetAddressOf());
if (FAILED(hr))
{
this->unloadImpl();
OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr,
"Error creating texture\nError Description: Failed to create ID3D11RenderTargetView. Verify "
"that the texture is valid, "
"properly initialized, and compatible with RenderTargetView creation.",
"D3D11Texture::_create2DTex");
}

_queryInterface<ID3D11Texture2D, ID3D11Resource>(mp2DTex, &mpTex);

_create2DResourceView();
}
//----------------------------------------------------------------------------
void D3D11Texture::_create2DResourceView()
{
// set final tex. attributes from tex. description
Expand Down Expand Up @@ -506,6 +594,8 @@ namespace Ogre
}
}
//---------------------------------------------------------------------
void D3D11Texture ::_setSurface(void* surface) { mSurface = surface; }
//---------------------------------------------------------------------
// D3D11RenderTexture
//---------------------------------------------------------------------
void D3D11RenderTexture::rebind( D3D11HardwarePixelBuffer *buffer )
Expand Down

0 comments on commit 4d8caa7

Please sign in to comment.