Create texture view with descriptor on D3D12 and Metal - Part I

This patch is the first part to implement creating a texture view
with a texture view descriptor on D3D12 and Metal back-ends. With
this patch the texture views created with descriptor can be bound
as sampledTextures on D3D12 and Metal back-ends.

Note that the support of rendering into a layer or a mipmap level of
a texture on D3D12 and Metal back-ends is not included in this patch.

BUG=dawn:16
TEST=dawn_end2end_tests

Change-Id: I62473ec5a4bb6b84d797ef7fd9cb98689ff763f4
Reviewed-on: https://dawn-review.googlesource.com/c/1940
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Jiawei Shao 2018-10-26 06:29:38 +00:00 committed by Commit Bot service account
parent aa7109c148
commit e8d12b44b6
5 changed files with 74 additions and 29 deletions

View File

@ -187,28 +187,28 @@ namespace dawn_native { namespace d3d12 {
mLastUsage = usage; mLastUsage = usage;
} }
// TODO(jiawei.shao@intel.com): create texture view by TextureViewDescriptor
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor) TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
: TextureViewBase(texture, descriptor) { : TextureViewBase(texture, descriptor) {
mSrvDesc.Format = D3D12TextureFormat(GetTexture()->GetFormat()); mSrvDesc.Format = D3D12TextureFormat(descriptor->format);
mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
switch (GetTexture()->GetDimension()) {
case dawn::TextureDimension::e2D: // Currently we always use D3D12_TEX2D_ARRAY_SRV because we cannot specify base array layer
if (GetTexture()->GetArrayLayers() == 1) { // and layer count in D3D12_TEX2D_SRV. For 2D texture views, we treat them as 1-layer 2D
mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; // array textures.
mSrvDesc.Texture2D.MostDetailedMip = 0; // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_srv
mSrvDesc.Texture2D.MipLevels = GetTexture()->GetNumMipLevels(); // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array_srv
mSrvDesc.Texture2D.PlaneSlice = 0; // TODO(jiawei.shao@intel.com): support more texture view dimensions.
mSrvDesc.Texture2D.ResourceMinLODClamp = 0; switch (descriptor->dimension) {
} else { case dawn::TextureViewDimension::e2D:
mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; case dawn::TextureViewDimension::e2DArray:
mSrvDesc.Texture2DArray.ArraySize = GetTexture()->GetArrayLayers(); ASSERT(texture->GetDimension() == dawn::TextureDimension::e2D);
mSrvDesc.Texture2DArray.FirstArraySlice = 0; mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
mSrvDesc.Texture2DArray.MipLevels = GetTexture()->GetNumMipLevels(); mSrvDesc.Texture2DArray.ArraySize = descriptor->layerCount;
mSrvDesc.Texture2DArray.MostDetailedMip = 0; mSrvDesc.Texture2DArray.FirstArraySlice = descriptor->baseArrayLayer;
mSrvDesc.Texture2DArray.PlaneSlice = 0; mSrvDesc.Texture2DArray.MipLevels = descriptor->levelCount;
mSrvDesc.Texture2DArray.ResourceMinLODClamp = 0; mSrvDesc.Texture2DArray.MostDetailedMip = descriptor->baseMipLevel;
} mSrvDesc.Texture2DArray.PlaneSlice = 0;
mSrvDesc.Texture2DArray.ResourceMinLODClamp = 0;
break; break;
default: default:
@ -220,6 +220,7 @@ namespace dawn_native { namespace d3d12 {
return mSrvDesc; return mSrvDesc;
} }
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() { D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() {
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc; D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
rtvDesc.Format = ToBackend(GetTexture())->GetD3D12Format(); rtvDesc.Format = ToBackend(GetTexture())->GetD3D12Format();
@ -229,6 +230,7 @@ namespace dawn_native { namespace d3d12 {
return rtvDesc; return rtvDesc;
} }
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() { D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() {
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc; D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
dsvDesc.Format = ToBackend(GetTexture())->GetD3D12Format(); dsvDesc.Format = ToBackend(GetTexture())->GetD3D12Format();

View File

@ -63,6 +63,7 @@ namespace dawn_native { namespace metal {
descriptor.colorAttachments[i].loadAction = MTLLoadActionLoad; descriptor.colorAttachments[i].loadAction = MTLLoadActionLoad;
} }
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
descriptor.colorAttachments[i].texture = descriptor.colorAttachments[i].texture =
ToBackend(attachmentInfo.view->GetTexture())->GetMTLTexture(); ToBackend(attachmentInfo.view->GetTexture())->GetMTLTexture();
descriptor.colorAttachments[i].storeAction = MTLStoreActionStore; descriptor.colorAttachments[i].storeAction = MTLStoreActionStore;
@ -71,6 +72,7 @@ namespace dawn_native { namespace metal {
if (desc->HasDepthStencilAttachment()) { if (desc->HasDepthStencilAttachment()) {
auto& attachmentInfo = desc->GetDepthStencilAttachment(); auto& attachmentInfo = desc->GetDepthStencilAttachment();
// TODO(jiawei.shao@intel.com): support rendering into a layer of a texture.
id<MTLTexture> texture = id<MTLTexture> texture =
ToBackend(attachmentInfo.view->GetTexture())->GetMTLTexture(); ToBackend(attachmentInfo.view->GetTexture())->GetMTLTexture();
dawn::TextureFormat format = attachmentInfo.view->GetTexture()->GetFormat(); dawn::TextureFormat format = attachmentInfo.view->GetTexture()->GetFormat();
@ -187,16 +189,17 @@ namespace dawn_native { namespace metal {
} break; } break;
case dawn::BindingType::SampledTexture: { case dawn::BindingType::SampledTexture: {
auto texture = auto textureView = ToBackend(group->GetBindingAsTextureView(binding));
ToBackend(group->GetBindingAsTextureView(binding)->GetTexture());
if (hasVertStage) { if (hasVertStage) {
[render setVertexTexture:texture->GetMTLTexture() atIndex:vertIndex]; [render setVertexTexture:textureView->GetMTLTexture()
atIndex:vertIndex];
} }
if (hasFragStage) { if (hasFragStage) {
[render setFragmentTexture:texture->GetMTLTexture() atIndex:fragIndex]; [render setFragmentTexture:textureView->GetMTLTexture()
atIndex:fragIndex];
} }
if (hasComputeStage) { if (hasComputeStage) {
[compute setTexture:texture->GetMTLTexture() atIndex:computeIndex]; [compute setTexture:textureView->GetMTLTexture() atIndex:computeIndex];
} }
} break; } break;
} }

View File

@ -40,6 +40,12 @@ namespace dawn_native { namespace metal {
class TextureView : public TextureViewBase { class TextureView : public TextureViewBase {
public: public:
TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor); TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);
~TextureView();
id<MTLTexture> GetMTLTexture();
private:
id<MTLTexture> mMtlTextureView = nil;
}; };
}} // namespace dawn_native::metal }} // namespace dawn_native::metal

View File

@ -55,6 +55,10 @@ namespace dawn_native { namespace metal {
result |= MTLTextureUsageRenderTarget; result |= MTLTextureUsageRenderTarget;
} }
// TODO(jiawei.shao@intel.com): investigate if we should skip setting this flag when the
// texture is only used as a render target.
result |= MTLTextureUsagePixelFormatView;
return result; return result;
} }
@ -65,6 +69,18 @@ namespace dawn_native { namespace metal {
return (arrayLayers > 1) ? MTLTextureType2DArray : MTLTextureType2D; return (arrayLayers > 1) ? MTLTextureType2DArray : MTLTextureType2D;
} }
} }
MTLTextureType MetalTextureViewType(dawn::TextureViewDimension dimension) {
switch (dimension) {
case dawn::TextureViewDimension::e2D:
return MTLTextureType2D;
case dawn::TextureViewDimension::e2DArray:
return MTLTextureType2DArray;
default:
UNREACHABLE();
return MTLTextureType2D;
}
}
} }
Texture::Texture(Device* device, const TextureDescriptor* descriptor) Texture::Texture(Device* device, const TextureDescriptor* descriptor)
@ -101,9 +117,27 @@ namespace dawn_native { namespace metal {
return mMtlTexture; return mMtlTexture;
} }
// TODO(jiawei.shao@intel.com): create texture view by texture view descriptor // TODO(jiawei.shao@intel.com): use the original texture directly when the descriptor covers the
// whole texture in the same format (for example, when CreateDefaultTextureView() is called).
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor) TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
: TextureViewBase(texture, descriptor) { : TextureViewBase(texture, descriptor) {
MTLPixelFormat format = MetalPixelFormat(descriptor->format);
MTLTextureType textureViewType = MetalTextureViewType(descriptor->dimension);
auto mipLevelRange = NSMakeRange(descriptor->baseMipLevel, descriptor->levelCount);
auto arrayLayerRange = NSMakeRange(descriptor->baseArrayLayer, descriptor->layerCount);
id<MTLTexture> mtlTexture = ToBackend(texture)->GetMTLTexture();
mMtlTextureView = [mtlTexture newTextureViewWithPixelFormat:format
textureType:textureViewType
levels:mipLevelRange
slices:arrayLayerRange];
} }
TextureView::~TextureView() {
[mMtlTextureView release];
}
id<MTLTexture> TextureView::GetMTLTexture() {
return mMtlTextureView;
}
}} // namespace dawn_native::metal }} // namespace dawn_native::metal

View File

@ -164,8 +164,8 @@ protected:
uint32_t textureViewBaseLayer, uint32_t textureViewBaseLayer,
uint32_t textureViewBaseMipLevel) { uint32_t textureViewBaseMipLevel) {
// TODO(jiawei.shao@intel.com): support creating texture view with a texture view descriptor // TODO(jiawei.shao@intel.com): support creating texture view with a texture view descriptor
// on D3D12, Metal and OpenGL. // on OpenGL.
DAWN_SKIP_TEST_IF(IsD3D12() || IsMetal() || IsOpenGL()); DAWN_SKIP_TEST_IF(IsOpenGL());
ASSERT(textureViewBaseLayer < textureArrayLayers); ASSERT(textureViewBaseLayer < textureArrayLayers);
ASSERT(textureViewBaseMipLevel < textureMipLevels); ASSERT(textureViewBaseMipLevel < textureMipLevels);
@ -201,8 +201,8 @@ protected:
uint32_t textureViewBaseLayer, uint32_t textureViewBaseLayer,
uint32_t textureViewBaseMipLevel) { uint32_t textureViewBaseMipLevel) {
// TODO(jiawei.shao@intel.com): support creating texture view with a texture view descriptor // TODO(jiawei.shao@intel.com): support creating texture view with a texture view descriptor
// on D3D12, Metal and OpenGL. // on OpenGL.
DAWN_SKIP_TEST_IF(IsD3D12() || IsMetal() || IsOpenGL()); DAWN_SKIP_TEST_IF(IsOpenGL());
ASSERT(textureViewBaseLayer < textureArrayLayers); ASSERT(textureViewBaseLayer < textureArrayLayers);
ASSERT(textureViewBaseMipLevel < textureMipLevels); ASSERT(textureViewBaseMipLevel < textureMipLevels);