d3d11: use Texture::Copy for copy data to staging texture used in CopyTextureToBuffer
Bug: dawn:1768 Change-Id: I7f6488cf54764585eef61766c3d2a829ef186783 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/128580 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Peng Huang <penghuang@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
20a24c9419
commit
c1b3c74316
|
@ -367,54 +367,29 @@ MaybeError CommandBuffer::Execute() {
|
||||||
DAWN_TRY(ToBackend(src.texture)
|
DAWN_TRY(ToBackend(src.texture)
|
||||||
->EnsureSubresourceContentInitialized(commandContext, subresources));
|
->EnsureSubresourceContentInitialized(commandContext, subresources));
|
||||||
|
|
||||||
// Create a staging texture.
|
TextureDescriptor desc = {};
|
||||||
// TODO(dawn:1768): use compute shader to copy data from texture to buffer.
|
desc.label = "CopyTextureToBufferStaging";
|
||||||
D3D11_TEXTURE2D_DESC stagingTextureDesc;
|
desc.dimension = src.texture->GetDimension();
|
||||||
stagingTextureDesc.Width = copy->copySize.width;
|
desc.size.width = copy->copySize.width;
|
||||||
stagingTextureDesc.Height = copy->copySize.height;
|
desc.size.height = copy->copySize.height;
|
||||||
stagingTextureDesc.MipLevels = 1;
|
desc.size.depthOrArrayLayers = copy->copySize.depthOrArrayLayers;
|
||||||
stagingTextureDesc.ArraySize = copy->copySize.depthOrArrayLayers;
|
desc.format = src.texture->GetFormat().format;
|
||||||
stagingTextureDesc.Format = ToBackend(src.texture)->GetD3D11Format();
|
desc.mipLevelCount = 1;
|
||||||
stagingTextureDesc.SampleDesc.Count = 1;
|
desc.sampleCount = 1;
|
||||||
stagingTextureDesc.SampleDesc.Quality = 0;
|
|
||||||
stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
|
|
||||||
stagingTextureDesc.BindFlags = 0;
|
|
||||||
stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
|
||||||
stagingTextureDesc.MiscFlags = 0;
|
|
||||||
|
|
||||||
ComPtr<ID3D11Texture2D> stagingTexture;
|
Ref<Texture> stagingTexture;
|
||||||
DAWN_TRY(CheckHRESULT(commandContext->GetD3D11Device()->CreateTexture2D(
|
DAWN_TRY_ASSIGN(stagingTexture,
|
||||||
&stagingTextureDesc, nullptr, &stagingTexture),
|
Texture::CreateStaging(ToBackend(GetDevice()), &desc));
|
||||||
"D3D11 create staging texture"));
|
|
||||||
|
|
||||||
uint32_t subresource =
|
CopyTextureToTextureCmd copyTextureToBufferCmd;
|
||||||
src.texture->GetSubresourceIndex(src.mipLevel, src.origin.z, src.aspect);
|
copyTextureToBufferCmd.source = src;
|
||||||
|
copyTextureToBufferCmd.destination.texture = stagingTexture.Get();
|
||||||
|
copyTextureToBufferCmd.destination.origin = {0, 0, 0};
|
||||||
|
copyTextureToBufferCmd.destination.mipLevel = 0;
|
||||||
|
copyTextureToBufferCmd.destination.aspect = src.aspect;
|
||||||
|
copyTextureToBufferCmd.copySize = copy->copySize;
|
||||||
|
|
||||||
if (src.texture->GetDimension() != wgpu::TextureDimension::e2D) {
|
DAWN_TRY(Texture::Copy(commandContext, ©TextureToBufferCmd));
|
||||||
return DAWN_UNIMPLEMENTED_ERROR(
|
|
||||||
"CopyTextureToBuffer is not implemented for non-2D textures");
|
|
||||||
} else {
|
|
||||||
for (uint32_t z = 0; z < copy->copySize.depthOrArrayLayers; ++z) {
|
|
||||||
// Copy the texture to the staging texture.
|
|
||||||
if (src.texture->GetFormat().HasDepthOrStencil()) {
|
|
||||||
d3d11DeviceContext1->CopySubresourceRegion(
|
|
||||||
stagingTexture.Get(), z, 0, 0, 0,
|
|
||||||
ToBackend(src.texture)->GetD3D11Resource(), subresource, nullptr);
|
|
||||||
} else {
|
|
||||||
D3D11_BOX srcBox;
|
|
||||||
srcBox.left = src.origin.x;
|
|
||||||
srcBox.right = src.origin.x + copy->copySize.width;
|
|
||||||
srcBox.top = src.origin.y;
|
|
||||||
srcBox.bottom = src.origin.y + copy->copySize.height;
|
|
||||||
srcBox.front = 0;
|
|
||||||
srcBox.back = 1;
|
|
||||||
|
|
||||||
d3d11DeviceContext1->CopySubresourceRegion(
|
|
||||||
stagingTexture.Get(), z, 0, 0, 0,
|
|
||||||
ToBackend(src.texture)->GetD3D11Resource(), subresource, &srcBox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer* buffer = ToBackend(dst.buffer.Get());
|
Buffer* buffer = ToBackend(dst.buffer.Get());
|
||||||
Buffer::ScopedMap scopedDstMap;
|
Buffer::ScopedMap scopedDstMap;
|
||||||
|
@ -428,7 +403,7 @@ MaybeError CommandBuffer::Execute() {
|
||||||
// TODO(dawn:1705): avoid blocking the CPU.
|
// TODO(dawn:1705): avoid blocking the CPU.
|
||||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||||
DAWN_TRY(
|
DAWN_TRY(
|
||||||
CheckHRESULT(d3d11DeviceContext1->Map(stagingTexture.Get(), z,
|
CheckHRESULT(d3d11DeviceContext1->Map(stagingTexture->GetD3D11Resource(), z,
|
||||||
D3D11_MAP_READ, 0, &mappedResource),
|
D3D11_MAP_READ, 0, &mappedResource),
|
||||||
"D3D11 map staging texture"));
|
"D3D11 map staging texture"));
|
||||||
|
|
||||||
|
@ -462,7 +437,7 @@ MaybeError CommandBuffer::Execute() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d3d11DeviceContext1->Unmap(stagingTexture.Get(), z);
|
d3d11DeviceContext1->Unmap(stagingTexture->GetD3D11Resource(), z);
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.buffer->MarkUsedInPendingCommands();
|
dst.buffer->MarkUsedInPendingCommands();
|
||||||
|
|
|
@ -53,7 +53,8 @@ UINT D3D11TextureBindFlags(wgpu::TextureUsage usage, const Format& format) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ResultOrError<Ref<Texture>> Texture::Create(Device* device, const TextureDescriptor* descriptor) {
|
ResultOrError<Ref<Texture>> Texture::Create(Device* device, const TextureDescriptor* descriptor) {
|
||||||
Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));
|
Ref<Texture> texture = AcquireRef(
|
||||||
|
new Texture(device, descriptor, TextureState::OwnedInternal, /*isStaging=*/false));
|
||||||
DAWN_TRY(texture->InitializeAsInternalTexture());
|
DAWN_TRY(texture->InitializeAsInternalTexture());
|
||||||
return std::move(texture);
|
return std::move(texture);
|
||||||
}
|
}
|
||||||
|
@ -62,73 +63,83 @@ ResultOrError<Ref<Texture>> Texture::Create(Device* device, const TextureDescrip
|
||||||
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
|
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
|
||||||
const TextureDescriptor* descriptor,
|
const TextureDescriptor* descriptor,
|
||||||
ComPtr<ID3D11Resource> d3d11Texture) {
|
ComPtr<ID3D11Resource> d3d11Texture) {
|
||||||
Ref<Texture> dawnTexture =
|
Ref<Texture> dawnTexture = AcquireRef(
|
||||||
AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
|
new Texture(device, descriptor, TextureState::OwnedExternal, /*isStaging=*/false));
|
||||||
DAWN_TRY(dawnTexture->InitializeAsSwapChainTexture(std::move(d3d11Texture)));
|
DAWN_TRY(dawnTexture->InitializeAsSwapChainTexture(std::move(d3d11Texture)));
|
||||||
return std::move(dawnTexture);
|
return std::move(dawnTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultOrError<Ref<Texture>> Texture::CreateStaging(Device* device,
|
||||||
|
const TextureDescriptor* descriptor) {
|
||||||
|
Ref<Texture> texture = AcquireRef(
|
||||||
|
new Texture(device, descriptor, TextureState::OwnedInternal, /*isStaging=*/true));
|
||||||
|
DAWN_TRY(texture->InitializeAsInternalTexture());
|
||||||
|
return std::move(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Texture::GetD3D11TextureDesc() const {
|
||||||
|
T desc;
|
||||||
|
|
||||||
|
if constexpr (std::is_same<T, D3D11_TEXTURE1D_DESC>::value) {
|
||||||
|
desc.Width = GetSize().width;
|
||||||
|
desc.ArraySize = GetArrayLayers();
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
} else if constexpr (std::is_same<T, D3D11_TEXTURE2D_DESC>::value) {
|
||||||
|
desc.Width = GetSize().width;
|
||||||
|
desc.Height = GetSize().height;
|
||||||
|
desc.ArraySize = GetArrayLayers();
|
||||||
|
desc.SampleDesc.Count = GetSampleCount();
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
if (GetArrayLayers() >= 6 && desc.Width == desc.Height) {
|
||||||
|
// Texture layers are more than 6. It can be used as a cube map.
|
||||||
|
desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
|
||||||
|
}
|
||||||
|
} else if constexpr (std::is_same<T, D3D11_TEXTURE3D_DESC>::value) {
|
||||||
|
desc.Width = GetSize().width;
|
||||||
|
desc.Height = GetSize().height;
|
||||||
|
desc.Depth = GetSize().depthOrArrayLayers;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc.MipLevels = static_cast<UINT16>(GetNumMipLevels());
|
||||||
|
desc.Format = d3d::DXGITextureFormat(GetFormat().format);
|
||||||
|
desc.Usage = mIsStaging ? D3D11_USAGE_STAGING : D3D11_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = D3D11TextureBindFlags(GetUsage(), GetFormat());
|
||||||
|
constexpr UINT kCPUReadWriteFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.CPUAccessFlags = mIsStaging ? kCPUReadWriteFlags : 0;
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError Texture::InitializeAsInternalTexture() {
|
MaybeError Texture::InitializeAsInternalTexture() {
|
||||||
Device* device = ToBackend(GetDevice());
|
Device* device = ToBackend(GetDevice());
|
||||||
|
|
||||||
DXGI_FORMAT dxgiFormat = d3d::DXGITextureFormat(GetFormat().format);
|
|
||||||
|
|
||||||
switch (GetDimension()) {
|
switch (GetDimension()) {
|
||||||
case wgpu::TextureDimension::e1D: {
|
case wgpu::TextureDimension::e1D: {
|
||||||
D3D11_TEXTURE1D_DESC textureDescriptor;
|
D3D11_TEXTURE1D_DESC desc = GetD3D11TextureDesc<D3D11_TEXTURE1D_DESC>();
|
||||||
textureDescriptor.Width = GetSize().width;
|
|
||||||
textureDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
|
|
||||||
textureDescriptor.ArraySize = 1;
|
|
||||||
textureDescriptor.Format = dxgiFormat;
|
|
||||||
textureDescriptor.Usage = D3D11_USAGE_DEFAULT;
|
|
||||||
textureDescriptor.BindFlags = D3D11TextureBindFlags(GetUsage(), GetFormat());
|
|
||||||
textureDescriptor.CPUAccessFlags = 0;
|
|
||||||
textureDescriptor.MiscFlags = 0;
|
|
||||||
ComPtr<ID3D11Texture1D> d3d11Texture1D;
|
ComPtr<ID3D11Texture1D> d3d11Texture1D;
|
||||||
DAWN_TRY(CheckOutOfMemoryHRESULT(device->GetD3D11Device()->CreateTexture1D(
|
DAWN_TRY(CheckOutOfMemoryHRESULT(
|
||||||
&textureDescriptor, nullptr, &d3d11Texture1D),
|
device->GetD3D11Device()->CreateTexture1D(&desc, nullptr, &d3d11Texture1D),
|
||||||
"D3D11 create texture1d"));
|
"D3D11 create texture1d"));
|
||||||
mD3d11Resource = std::move(d3d11Texture1D);
|
mD3d11Resource = std::move(d3d11Texture1D);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case wgpu::TextureDimension::e2D: {
|
case wgpu::TextureDimension::e2D: {
|
||||||
D3D11_TEXTURE2D_DESC textureDescriptor;
|
D3D11_TEXTURE2D_DESC desc = GetD3D11TextureDesc<D3D11_TEXTURE2D_DESC>();
|
||||||
textureDescriptor.Width = GetSize().width;
|
|
||||||
textureDescriptor.Height = GetSize().height;
|
|
||||||
textureDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
|
|
||||||
textureDescriptor.ArraySize = GetArrayLayers();
|
|
||||||
textureDescriptor.Format = dxgiFormat;
|
|
||||||
textureDescriptor.SampleDesc.Count = GetSampleCount();
|
|
||||||
textureDescriptor.SampleDesc.Quality = 0;
|
|
||||||
textureDescriptor.Usage = D3D11_USAGE_DEFAULT;
|
|
||||||
textureDescriptor.BindFlags = D3D11TextureBindFlags(GetUsage(), GetFormat());
|
|
||||||
textureDescriptor.CPUAccessFlags = 0;
|
|
||||||
textureDescriptor.MiscFlags = 0;
|
|
||||||
if (GetArrayLayers() >= 6) {
|
|
||||||
// Texture layers are more than 6. It can be used as a cube map.
|
|
||||||
textureDescriptor.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
|
|
||||||
}
|
|
||||||
ComPtr<ID3D11Texture2D> d3d11Texture2D;
|
ComPtr<ID3D11Texture2D> d3d11Texture2D;
|
||||||
DAWN_TRY(CheckOutOfMemoryHRESULT(device->GetD3D11Device()->CreateTexture2D(
|
DAWN_TRY(CheckOutOfMemoryHRESULT(
|
||||||
&textureDescriptor, nullptr, &d3d11Texture2D),
|
device->GetD3D11Device()->CreateTexture2D(&desc, nullptr, &d3d11Texture2D),
|
||||||
"D3D11 create texture2d"));
|
"D3D11 create texture2d"));
|
||||||
mD3d11Resource = std::move(d3d11Texture2D);
|
mD3d11Resource = std::move(d3d11Texture2D);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case wgpu::TextureDimension::e3D: {
|
case wgpu::TextureDimension::e3D: {
|
||||||
D3D11_TEXTURE3D_DESC textureDescriptor;
|
D3D11_TEXTURE3D_DESC desc = GetD3D11TextureDesc<D3D11_TEXTURE3D_DESC>();
|
||||||
textureDescriptor.Width = GetSize().width;
|
|
||||||
textureDescriptor.Height = GetSize().height;
|
|
||||||
textureDescriptor.Depth = GetSize().depthOrArrayLayers;
|
|
||||||
textureDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
|
|
||||||
textureDescriptor.Format = dxgiFormat;
|
|
||||||
textureDescriptor.Usage = D3D11_USAGE_DEFAULT;
|
|
||||||
textureDescriptor.BindFlags = D3D11TextureBindFlags(GetUsage(), GetFormat());
|
|
||||||
textureDescriptor.CPUAccessFlags = 0;
|
|
||||||
textureDescriptor.MiscFlags = 0;
|
|
||||||
ComPtr<ID3D11Texture3D> d3d11Texture3D;
|
ComPtr<ID3D11Texture3D> d3d11Texture3D;
|
||||||
DAWN_TRY(CheckOutOfMemoryHRESULT(device->GetD3D11Device()->CreateTexture3D(
|
DAWN_TRY(CheckOutOfMemoryHRESULT(
|
||||||
&textureDescriptor, nullptr, &d3d11Texture3D),
|
device->GetD3D11Device()->CreateTexture3D(&desc, nullptr, &d3d11Texture3D),
|
||||||
"D3D11 create texture3d"));
|
"D3D11 create texture3d"));
|
||||||
mD3d11Resource = std::move(d3d11Texture3D);
|
mD3d11Resource = std::move(d3d11Texture3D);
|
||||||
break;
|
break;
|
||||||
|
@ -152,8 +163,11 @@ MaybeError Texture::InitializeAsSwapChainTexture(ComPtr<ID3D11Resource> d3d11Tex
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(Device* device, const TextureDescriptor* descriptor, TextureState state)
|
Texture::Texture(Device* device,
|
||||||
: TextureBase(device, descriptor, state) {}
|
const TextureDescriptor* descriptor,
|
||||||
|
TextureState state,
|
||||||
|
bool isStaging)
|
||||||
|
: TextureBase(device, descriptor, state), mIsStaging(isStaging) {}
|
||||||
|
|
||||||
Texture::~Texture() = default;
|
Texture::~Texture() = default;
|
||||||
|
|
||||||
|
@ -386,10 +400,17 @@ MaybeError Texture::Copy(CommandRecordingContext* commandContext, CopyTextureToT
|
||||||
if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel)) {
|
if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel)) {
|
||||||
dst.texture->SetIsSubresourceContentInitialized(true, subresources);
|
dst.texture->SetIsSubresourceContentInitialized(true, subresources);
|
||||||
} else {
|
} else {
|
||||||
|
// Partial update subresource of a depth/stencil texture is not allowed.
|
||||||
|
DAWN_ASSERT(!dst.texture->GetFormat().HasDepthOrStencil());
|
||||||
DAWN_TRY(ToBackend(dst.texture)
|
DAWN_TRY(ToBackend(dst.texture)
|
||||||
->EnsureSubresourceContentInitialized(commandContext, subresources));
|
->EnsureSubresourceContentInitialized(commandContext, subresources));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isWholeTextureCopy =
|
||||||
|
src.texture->GetSize() == copy->copySize && dst.texture->GetSize() == copy->copySize;
|
||||||
|
// Partial update subresource of a depth/stencil texture is not allowed.
|
||||||
|
DAWN_ASSERT(isWholeTextureCopy || !dst.texture->GetFormat().HasDepthOrStencil());
|
||||||
|
|
||||||
D3D11_BOX srcBox;
|
D3D11_BOX srcBox;
|
||||||
srcBox.left = src.origin.x;
|
srcBox.left = src.origin.x;
|
||||||
srcBox.right = src.origin.x + copy->copySize.width;
|
srcBox.right = src.origin.x + copy->copySize.width;
|
||||||
|
@ -402,7 +423,8 @@ MaybeError Texture::Copy(CommandRecordingContext* commandContext, CopyTextureToT
|
||||||
|
|
||||||
commandContext->GetD3D11DeviceContext1()->CopySubresourceRegion(
|
commandContext->GetD3D11DeviceContext1()->CopySubresourceRegion(
|
||||||
ToBackend(dst.texture)->GetD3D11Resource(), dst.mipLevel, dst.origin.x, dst.origin.y,
|
ToBackend(dst.texture)->GetD3D11Resource(), dst.mipLevel, dst.origin.x, dst.origin.y,
|
||||||
dst.origin.z, ToBackend(src.texture)->GetD3D11Resource(), subresource, &srcBox);
|
dst.origin.z, ToBackend(src.texture)->GetD3D11Resource(), subresource,
|
||||||
|
isWholeTextureCopy ? nullptr : &srcBox);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ class Texture final : public TextureBase {
|
||||||
static ResultOrError<Ref<Texture>> Create(Device* device,
|
static ResultOrError<Ref<Texture>> Create(Device* device,
|
||||||
const TextureDescriptor* descriptor,
|
const TextureDescriptor* descriptor,
|
||||||
ComPtr<ID3D11Resource> d3d11Texture);
|
ComPtr<ID3D11Resource> d3d11Texture);
|
||||||
|
static ResultOrError<Ref<Texture>> CreateStaging(Device* device,
|
||||||
|
const TextureDescriptor* descriptor);
|
||||||
|
|
||||||
DXGI_FORMAT GetD3D11Format() const;
|
DXGI_FORMAT GetD3D11Format() const;
|
||||||
ID3D11Resource* GetD3D11Resource() const;
|
ID3D11Resource* GetD3D11Resource() const;
|
||||||
|
@ -62,9 +64,14 @@ class Texture final : public TextureBase {
|
||||||
static MaybeError Copy(CommandRecordingContext* commandContext, CopyTextureToTextureCmd* copy);
|
static MaybeError Copy(CommandRecordingContext* commandContext, CopyTextureToTextureCmd* copy);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Texture(Device* device, const TextureDescriptor* descriptor, TextureState state);
|
Texture(Device* device,
|
||||||
|
const TextureDescriptor* descriptor,
|
||||||
|
TextureState state,
|
||||||
|
bool isStaging);
|
||||||
~Texture() override;
|
~Texture() override;
|
||||||
using TextureBase::TextureBase;
|
|
||||||
|
template <typename T>
|
||||||
|
T GetD3D11TextureDesc() const;
|
||||||
|
|
||||||
MaybeError InitializeAsInternalTexture();
|
MaybeError InitializeAsInternalTexture();
|
||||||
MaybeError InitializeAsSwapChainTexture(ComPtr<ID3D11Resource> d3d11Texture);
|
MaybeError InitializeAsSwapChainTexture(ComPtr<ID3D11Resource> d3d11Texture);
|
||||||
|
@ -79,6 +86,7 @@ class Texture final : public TextureBase {
|
||||||
const SubresourceRange& range,
|
const SubresourceRange& range,
|
||||||
TextureBase::ClearValue clearValue);
|
TextureBase::ClearValue clearValue);
|
||||||
|
|
||||||
|
const bool mIsStaging = false;
|
||||||
ComPtr<ID3D11Resource> mD3d11Resource;
|
ComPtr<ID3D11Resource> mD3d11Resource;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue