mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[d3d9] Add ID3D9VkInteropDevice::CreateImage to create custom texture/surfaces
This commit is contained in:
parent
98fa338be0
commit
a044c639f7
@ -306,7 +306,8 @@ namespace dxvk {
|
||||
imageInfo.numLayers = m_desc.ArraySize;
|
||||
imageInfo.mipLevels = m_desc.MipLevels;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||
| m_desc.ImageUsage;
|
||||
imageInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
| m_device->GetEnabledShaderStages();
|
||||
imageInfo.access = VK_ACCESS_TRANSFER_READ_BIT
|
||||
|
@ -48,6 +48,9 @@ namespace dxvk {
|
||||
bool IsBackBuffer;
|
||||
bool IsAttachmentOnly;
|
||||
bool IsLockable;
|
||||
|
||||
// Additional paramters for ID3D9VkInteropDevice
|
||||
VkImageUsageFlags ImageUsage = 0;
|
||||
};
|
||||
|
||||
struct D3D9ColorView {
|
||||
|
@ -34,7 +34,7 @@ ID3D9VkInteropInterface : public IUnknown {
|
||||
* \brief D3D9 texture interface for Vulkan interop
|
||||
*
|
||||
* Provides access to the backing resource of a
|
||||
* D3D9 texture.
|
||||
* D3D9 texture or surface.
|
||||
*/
|
||||
MIDL_INTERFACE("d56344f5-8d35-46fd-806d-94c351b472c1")
|
||||
ID3D9VkInteropTexture : public IUnknown {
|
||||
@ -74,6 +74,27 @@ ID3D9VkInteropTexture : public IUnknown {
|
||||
VkImageCreateInfo* pInfo) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief D3D9 image description
|
||||
*/
|
||||
struct D3D9VkExtImageDesc {
|
||||
D3DRESOURCETYPE Type; // Can be SURFACE, TEXTURE, CUBETEXTURE, VOLUMETEXTURE
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
UINT Depth; // Can be > 1 for VOLUMETEXTURE
|
||||
UINT MipLevels; // Can be > 1 for TEXTURE, CUBETEXTURE, VOLUMETEXTURE
|
||||
DWORD Usage;
|
||||
D3DFORMAT Format;
|
||||
D3DPOOL Pool;
|
||||
D3DMULTISAMPLE_TYPE MultiSample; // Must be NONE unless Type is SURFACE
|
||||
DWORD MultisampleQuality;
|
||||
bool Discard; // Depth stencils only
|
||||
bool IsAttachmentOnly; // If false, then VK_IMAGE_USAGE_SAMPLED_BIT will be added
|
||||
bool IsLockable;
|
||||
VkImageUsageFlags ImageUsage; // Additional image usage flags
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief D3D9 device interface for Vulkan interop
|
||||
*
|
||||
@ -194,6 +215,17 @@ ID3D9VkInteropDevice : public IUnknown {
|
||||
virtual bool STDMETHODCALLTYPE WaitForResource(
|
||||
IDirect3DResource9* pResource,
|
||||
DWORD MapFlags) = 0;
|
||||
|
||||
/**
|
||||
* \brief Creates a custom image/surface/texture
|
||||
*
|
||||
* \param [in] desc Image description
|
||||
* \param [out, retval] ppResult Pointer to a resource of the D3DRESOURCETYPE given by desc.Type
|
||||
* \returns D3D_OK, D3DERR_INVALIDCALL, or D3DERR_OUTOFVIDEOMEMORY
|
||||
*/
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateImage(
|
||||
const D3D9VkExtImageDesc* desc,
|
||||
IDirect3DResource9** ppResult) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "d3d9_device.h"
|
||||
#include "d3d9_texture.h"
|
||||
#include "d3d9_buffer.h"
|
||||
#include "d3d9_initializer.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
@ -239,4 +240,103 @@ namespace dxvk {
|
||||
return m_device->WaitForResource(GetDxvkResource(pResource), DxvkCsThread::SynchronizeAll, MapFlags);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D9VkInteropDevice::CreateImage(
|
||||
const D3D9VkExtImageDesc* params,
|
||||
IDirect3DResource9** ppResult) {
|
||||
InitReturnPtr(ppResult);
|
||||
|
||||
if (unlikely(ppResult == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
if (unlikely(params == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
/////////////////////////////
|
||||
// Image desc validation
|
||||
|
||||
// Cannot create a volume by itself, use D3DRTYPE_VOLUMETEXTURE
|
||||
if (unlikely(params->Type == D3DRTYPE_VOLUME))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
// Only allowed: SURFACE, TEXTURE, CUBETEXTURE, VOLUMETEXTURE
|
||||
if (unlikely(params->Type < D3DRTYPE_SURFACE || params->Type > D3DRTYPE_CUBETEXTURE))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
// Only volume textures can have depth > 1
|
||||
if (unlikely(params->Type != D3DRTYPE_VOLUMETEXTURE && params->Depth > 1))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
if (params->Type == D3DRTYPE_SURFACE) {
|
||||
// Surfaces can only have 1 mip level
|
||||
if (unlikely(params->MipLevels > 1))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
if (unlikely(params->MultiSample > D3DMULTISAMPLE_16_SAMPLES))
|
||||
return D3DERR_INVALIDCALL;
|
||||
} else {
|
||||
// Textures can't be multisampled
|
||||
if (unlikely(params->MultiSample != D3DMULTISAMPLE_NONE))
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
D3D9_COMMON_TEXTURE_DESC desc;
|
||||
desc.Width = params->Width;
|
||||
desc.Height = params->Height;
|
||||
desc.Depth = params->Depth;
|
||||
desc.ArraySize = params->Type == D3DRTYPE_CUBETEXTURE ? 6 : 1;
|
||||
desc.MipLevels = params->MipLevels;
|
||||
desc.Usage = params->Usage;
|
||||
desc.Format = EnumerateFormat(params->Format);
|
||||
desc.Pool = params->Pool;
|
||||
desc.Discard = params->Discard;
|
||||
desc.MultiSample = params->MultiSample;
|
||||
desc.MultisampleQuality = params->MultisampleQuality;
|
||||
desc.IsBackBuffer = FALSE;
|
||||
desc.IsAttachmentOnly = params->IsAttachmentOnly;
|
||||
desc.IsLockable = params->IsLockable;
|
||||
desc.ImageUsage = params->ImageUsage;
|
||||
|
||||
D3DRESOURCETYPE textureType = params->Type == D3DRTYPE_SURFACE ? D3DRTYPE_TEXTURE : params->Type;
|
||||
|
||||
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(m_device, textureType, &desc)))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
switch (params->Type) {
|
||||
case D3DRTYPE_SURFACE:
|
||||
return CreateTextureResource<D3D9Surface>(desc, ppResult);
|
||||
|
||||
case D3DRTYPE_TEXTURE:
|
||||
return CreateTextureResource<D3D9Texture2D>(desc, ppResult);
|
||||
|
||||
case D3DRTYPE_VOLUMETEXTURE:
|
||||
return CreateTextureResource<D3D9Texture3D>(desc, ppResult);
|
||||
|
||||
case D3DRTYPE_CUBETEXTURE:
|
||||
return CreateTextureResource<D3D9TextureCube>(desc, ppResult);
|
||||
|
||||
default:
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ResourceType>
|
||||
HRESULT D3D9VkInteropDevice::CreateTextureResource(
|
||||
const D3D9_COMMON_TEXTURE_DESC& desc,
|
||||
IDirect3DResource9** ppResult) {
|
||||
try {
|
||||
const Com<ResourceType> texture = new ResourceType(m_device, &desc);
|
||||
m_device->m_initializer->InitTexture(texture->GetCommonTexture());
|
||||
*ppResult = texture.ref();
|
||||
|
||||
if (desc.Pool == D3DPOOL_DEFAULT)
|
||||
m_device->m_losableResourceCounter++;
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
return D3DERR_OUTOFVIDEOMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ namespace dxvk {
|
||||
class D3D9InterfaceEx;
|
||||
class D3D9CommonTexture;
|
||||
class D3D9DeviceEx;
|
||||
struct D3D9_COMMON_TEXTURE_DESC;
|
||||
|
||||
class D3D9VkInteropInterface final : public ID3D9VkInteropInterface {
|
||||
|
||||
@ -118,8 +119,17 @@ namespace dxvk {
|
||||
IDirect3DResource9* pResource,
|
||||
DWORD MapFlags);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CreateImage(
|
||||
const D3D9VkExtImageDesc* desc,
|
||||
IDirect3DResource9** ppResult);
|
||||
|
||||
private:
|
||||
|
||||
template <typename ResourceType>
|
||||
HRESULT CreateTextureResource(
|
||||
const D3D9_COMMON_TEXTURE_DESC& desc,
|
||||
IDirect3DResource9** ppResult);
|
||||
|
||||
D3D9DeviceEx* m_device;
|
||||
D3D9DeviceLock m_lock;
|
||||
|
||||
|
@ -20,8 +20,8 @@ namespace dxvk {
|
||||
D3D9Surface(
|
||||
D3D9DeviceEx* pDevice,
|
||||
const D3D9_COMMON_TEXTURE_DESC* pDesc,
|
||||
IUnknown* pContainer,
|
||||
HANDLE* pSharedHandle);
|
||||
IUnknown* pContainer = nullptr,
|
||||
HANDLE* pSharedHandle = nullptr);
|
||||
|
||||
D3D9Surface(
|
||||
D3D9DeviceEx* pDevice,
|
||||
|
@ -132,7 +132,7 @@ namespace dxvk {
|
||||
D3D9Texture2D(
|
||||
D3D9DeviceEx* pDevice,
|
||||
const D3D9_COMMON_TEXTURE_DESC* pDesc,
|
||||
HANDLE* pSharedHandle);
|
||||
HANDLE* pSharedHandle = nullptr);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user