Implement the stencil8 format.
Rolled in changes made by cwallez@ as part of https://dawn-review.googlesource.com/c/dawn/+/75983, which was originally based on this change. Bug: dawn:666 Change-Id: I5d6ad592294ee8302f3b18f7f31bbfd982297251 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/68280 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Brandon Jones <bajones@chromium.org>
This commit is contained in:
parent
cbdde604b8
commit
0bf63577d2
|
@ -369,15 +369,19 @@ namespace dawn::native {
|
|||
}
|
||||
} else {
|
||||
DAWN_TRY(ValidateLoadOp(depthStencilAttachment->stencilLoadOp));
|
||||
DAWN_INVALID_IF(depthStencilAttachment->stencilLoadOp == wgpu::LoadOp::Undefined,
|
||||
"stencilLoadOp must be set if the attachment (%s) has a stencil "
|
||||
"aspect and stencilReadOnly (%u) is false.",
|
||||
attachment, depthStencilAttachment->stencilReadOnly);
|
||||
DAWN_INVALID_IF(
|
||||
depthStencilAttachment->stencilLoadOp == wgpu::LoadOp::Undefined,
|
||||
"stencilLoadOp (%s) must be set if the attachment (%s) has a stencil "
|
||||
"aspect and stencilReadOnly (%u) is false.",
|
||||
depthStencilAttachment->stencilLoadOp, attachment,
|
||||
depthStencilAttachment->stencilReadOnly);
|
||||
DAWN_TRY(ValidateStoreOp(depthStencilAttachment->stencilStoreOp));
|
||||
DAWN_INVALID_IF(depthStencilAttachment->depthStoreOp == wgpu::StoreOp::Undefined,
|
||||
"stencilStoreOp must be set if the attachment (%s) has a stencil "
|
||||
"aspect and stencilReadOnly (%u) is false.",
|
||||
attachment, depthStencilAttachment->stencilReadOnly);
|
||||
DAWN_INVALID_IF(
|
||||
depthStencilAttachment->stencilStoreOp == wgpu::StoreOp::Undefined,
|
||||
"stencilStoreOp (%s) must be set if the attachment (%s) has a stencil "
|
||||
"aspect and stencilReadOnly (%u) is false.",
|
||||
depthStencilAttachment->stencilStoreOp, attachment,
|
||||
depthStencilAttachment->stencilReadOnly);
|
||||
}
|
||||
|
||||
if (!std::isnan(depthStencilAttachment->clearDepth)) {
|
||||
|
|
|
@ -264,13 +264,22 @@ namespace dawn::native {
|
|||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
AspectInfo* firstAspect = internalFormat.aspectInfo.data();
|
||||
firstAspect->block.byteSize = 1;
|
||||
firstAspect->block.width = 1;
|
||||
firstAspect->block.height = 1;
|
||||
firstAspect->baseType = wgpu::TextureComponentType::Uint;
|
||||
firstAspect->supportedSampleTypes = SampleTypeBit::Uint;
|
||||
firstAspect->format = format;
|
||||
// Duplicate the data for the stencil aspect in both the first and second aspect info.
|
||||
// - aspectInfo[0] is used by AddMultiAspectFormat to copy the info for the whole
|
||||
// stencil8 aspect of depth-stencil8 formats.
|
||||
// - aspectInfo[1] is the actual info used in the rest of Dawn since
|
||||
// GetAspectIndex(Aspect::Stencil) is 1.
|
||||
ASSERT(GetAspectIndex(Aspect::Stencil) == 1);
|
||||
|
||||
internalFormat.aspectInfo[0].block.byteSize = 1;
|
||||
internalFormat.aspectInfo[0].block.width = 1;
|
||||
internalFormat.aspectInfo[0].block.height = 1;
|
||||
internalFormat.aspectInfo[0].baseType = wgpu::TextureComponentType::Uint;
|
||||
internalFormat.aspectInfo[0].supportedSampleTypes = SampleTypeBit::Uint;
|
||||
internalFormat.aspectInfo[0].format = format;
|
||||
|
||||
internalFormat.aspectInfo[1] = internalFormat.aspectInfo[0];
|
||||
|
||||
AddFormat(internalFormat);
|
||||
};
|
||||
|
||||
|
@ -330,9 +339,17 @@ namespace dawn::native {
|
|||
internalFormat.baseFormat = baseFormat;
|
||||
}
|
||||
|
||||
// Multi aspect formats just copy information about single-aspect formats. This
|
||||
// means that the single-plane formats must have been added before multi-aspect
|
||||
// ones. (it is ASSERTed below).
|
||||
const size_t firstFormatIndex = ComputeFormatIndex(firstFormat);
|
||||
const size_t secondFormatIndex = ComputeFormatIndex(secondFormat);
|
||||
|
||||
ASSERT(table[firstFormatIndex].aspectInfo[0].format !=
|
||||
wgpu::TextureFormat::Undefined);
|
||||
ASSERT(table[secondFormatIndex].aspectInfo[0].format !=
|
||||
wgpu::TextureFormat::Undefined);
|
||||
|
||||
internalFormat.aspectInfo[0] = table[firstFormatIndex].aspectInfo[0];
|
||||
internalFormat.aspectInfo[1] = table[secondFormatIndex].aspectInfo[0];
|
||||
|
||||
|
@ -388,8 +405,7 @@ namespace dawn::native {
|
|||
AddColorFormat(wgpu::TextureFormat::RGBA32Float, true, true, false, false, 16, SampleTypeBit::UnfilterableFloat, 4);
|
||||
|
||||
// Depth-stencil formats
|
||||
// TODO(dawn:666): Implement the stencil8 format
|
||||
AddStencilFormat(wgpu::TextureFormat::Stencil8, false);
|
||||
AddStencilFormat(wgpu::TextureFormat::Stencil8, true);
|
||||
AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, true);
|
||||
// TODO(crbug.com/dawn/843): This is 4 because we read this to perform zero initialization,
|
||||
// and textures are always use depth32float. We should improve this to be more robust. Perhaps,
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace dawn::native {
|
|||
// an internal Dawn enum.
|
||||
wgpu::TextureComponentType baseType;
|
||||
SampleTypeBit supportedSampleTypes;
|
||||
wgpu::TextureFormat format;
|
||||
wgpu::TextureFormat format = wgpu::TextureFormat::Undefined;
|
||||
};
|
||||
|
||||
// The number of formats Dawn knows about. Asserts in BuildFormatTable ensure that this is the
|
||||
|
|
|
@ -87,6 +87,10 @@ namespace dawn::native {
|
|||
return 1;
|
||||
} else if (aspects == (Aspect::Plane0 | Aspect::Plane1)) {
|
||||
return 2;
|
||||
} else if (aspects == Aspect::Stencil) {
|
||||
// Fake a the existence of a depth aspect so that the stencil data stays at index 1.
|
||||
ASSERT(GetAspectIndex(Aspect::Stencil) == 1);
|
||||
return 2;
|
||||
} else {
|
||||
ASSERT(aspects == (Aspect::Depth | Aspect::Stencil));
|
||||
return 2;
|
||||
|
|
|
@ -99,6 +99,12 @@ namespace dawn::native {
|
|||
"backend will use D32S8 (toggle to on) but setting the toggle to off will make it "
|
||||
"use the D24S8 format when possible.",
|
||||
"https://crbug.com/dawn/286"}},
|
||||
{Toggle::VulkanUseS8,
|
||||
{"vulkan_use_s8",
|
||||
"Vulkan has a pure stencil8 format but it is not universally available. When this "
|
||||
"toggle is on, the backend will use S8 for the stencil8 format, otherwise it will "
|
||||
"fallback to D32S8 or D24S8.",
|
||||
"https://crbug.com/dawn/666"}},
|
||||
{Toggle::MetalDisableSamplerCompare,
|
||||
{"metal_disable_sampler_compare",
|
||||
"Disables the use of sampler compare on Metal. This is unsupported before A9 "
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace dawn::native {
|
|||
UseD3D12ResidencyManagement,
|
||||
SkipValidation,
|
||||
VulkanUseD32S8,
|
||||
VulkanUseS8,
|
||||
MetalDisableSamplerCompare,
|
||||
MetalUseSharedModeForCounterSampleBuffer,
|
||||
DisableBaseVertex,
|
||||
|
|
|
@ -1327,7 +1327,7 @@ namespace dawn::native::d3d12 {
|
|||
}
|
||||
}
|
||||
|
||||
if (renderPassBuilder->HasDepth()) {
|
||||
if (renderPassBuilder->HasDepthOrStencil()) {
|
||||
D3D12_CLEAR_FLAGS clearFlags = {};
|
||||
float depthClear = 0.0f;
|
||||
uint8_t stencilClear = 0u;
|
||||
|
@ -1359,7 +1359,7 @@ namespace dawn::native::d3d12 {
|
|||
commandList->OMSetRenderTargets(
|
||||
static_cast<uint8_t>(renderPassBuilder->GetHighestColorAttachmentIndexPlusOne()),
|
||||
renderPassBuilder->GetRenderTargetViews(), FALSE,
|
||||
renderPassBuilder->HasDepth()
|
||||
renderPassBuilder->HasDepthOrStencil()
|
||||
? &renderPassBuilder->GetRenderPassDepthStencilDescriptor()->cpuDescriptor
|
||||
: nullptr);
|
||||
}
|
||||
|
@ -1384,7 +1384,7 @@ namespace dawn::native::d3d12 {
|
|||
commandContext->GetCommandList4()->BeginRenderPass(
|
||||
static_cast<uint8_t>(renderPassBuilder.GetHighestColorAttachmentIndexPlusOne()),
|
||||
renderPassBuilder.GetRenderPassRenderTargetDescriptors().data(),
|
||||
renderPassBuilder.HasDepth()
|
||||
renderPassBuilder.HasDepthOrStencil()
|
||||
? renderPassBuilder.GetRenderPassDepthStencilDescriptor()
|
||||
: nullptr,
|
||||
renderPassBuilder.GetRenderPassFlags());
|
||||
|
|
|
@ -136,8 +136,8 @@ namespace dawn::native::d3d12 {
|
|||
return mHighestColorAttachmentIndexPlusOne;
|
||||
}
|
||||
|
||||
bool RenderPassBuilder::HasDepth() const {
|
||||
return mHasDepth;
|
||||
bool RenderPassBuilder::HasDepthOrStencil() const {
|
||||
return mHasDepthOrStencil;
|
||||
}
|
||||
|
||||
ityp::span<ColorAttachmentIndex, const D3D12_RENDER_PASS_RENDER_TARGET_DESC>
|
||||
|
@ -204,7 +204,7 @@ namespace dawn::native::d3d12 {
|
|||
wgpu::StoreOp storeOp,
|
||||
float clearDepth,
|
||||
DXGI_FORMAT format) {
|
||||
mHasDepth = true;
|
||||
mHasDepthOrStencil = true;
|
||||
mRenderPassDepthStencilDesc.DepthBeginningAccess.Type = D3D12BeginningAccessType(loadOp);
|
||||
if (loadOp == wgpu::LoadOp::Clear) {
|
||||
mRenderPassDepthStencilDesc.DepthBeginningAccess.Clear.ClearValue.DepthStencil.Depth =
|
||||
|
@ -218,6 +218,7 @@ namespace dawn::native::d3d12 {
|
|||
wgpu::StoreOp storeOp,
|
||||
uint8_t clearStencil,
|
||||
DXGI_FORMAT format) {
|
||||
mHasDepthOrStencil = true;
|
||||
mRenderPassDepthStencilDesc.StencilBeginningAccess.Type = D3D12BeginningAccessType(loadOp);
|
||||
if (loadOp == wgpu::LoadOp::Clear) {
|
||||
mRenderPassDepthStencilDesc.StencilBeginningAccess.Clear.ClearValue.DepthStencil
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace dawn::native::d3d12 {
|
|||
// Returns attachment RTVs to use with OMSetRenderTargets.
|
||||
const D3D12_CPU_DESCRIPTOR_HANDLE* GetRenderTargetViews() const;
|
||||
|
||||
bool HasDepth() const;
|
||||
bool HasDepthOrStencil() const;
|
||||
|
||||
// Functions that set the appropriate values in the render pass descriptors.
|
||||
void SetDepthAccess(wgpu::LoadOp loadOp,
|
||||
|
@ -83,7 +83,7 @@ namespace dawn::native::d3d12 {
|
|||
|
||||
private:
|
||||
ColorAttachmentIndex mHighestColorAttachmentIndexPlusOne{uint8_t(0)};
|
||||
bool mHasDepth = false;
|
||||
bool mHasDepthOrStencil = false;
|
||||
D3D12_RENDER_PASS_FLAGS mRenderPassFlags = D3D12_RENDER_PASS_FLAG_NONE;
|
||||
D3D12_RENDER_PASS_DEPTH_STENCIL_DESC mRenderPassDepthStencilDesc;
|
||||
ityp::
|
||||
|
|
|
@ -279,7 +279,11 @@ namespace dawn::native::d3d12 {
|
|||
|
||||
D3D12_DEPTH_STENCIL_DESC ComputeDepthStencilDesc(const DepthStencilState* descriptor) {
|
||||
D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor;
|
||||
mDepthStencilDescriptor.DepthEnable = TRUE;
|
||||
mDepthStencilDescriptor.DepthEnable =
|
||||
(descriptor->depthCompare == wgpu::CompareFunction::Always &&
|
||||
!descriptor->depthWriteEnabled)
|
||||
? FALSE
|
||||
: TRUE;
|
||||
mDepthStencilDescriptor.DepthWriteMask = descriptor->depthWriteEnabled
|
||||
? D3D12_DEPTH_WRITE_MASK_ALL
|
||||
: D3D12_DEPTH_WRITE_MASK_ZERO;
|
||||
|
|
|
@ -299,7 +299,8 @@ namespace dawn::native::d3d12 {
|
|||
// incorrectly allocate a mismatched size.
|
||||
if (resourceInfo.SizeInBytes == 0 ||
|
||||
resourceInfo.SizeInBytes == std::numeric_limits<uint64_t>::max()) {
|
||||
return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
|
||||
return DAWN_OUT_OF_MEMORY_ERROR(absl::StrFormat(
|
||||
"Resource allocation size (%u) was invalid.", resourceInfo.SizeInBytes));
|
||||
}
|
||||
|
||||
BuddyMemoryAllocator* allocator =
|
||||
|
|
|
@ -178,6 +178,8 @@ namespace dawn::native::d3d12 {
|
|||
case wgpu::TextureFormat::Depth24Plus:
|
||||
return DXGI_FORMAT_R32_TYPELESS;
|
||||
|
||||
// Depth24UnormStencil8 is the smallest format supported on D3D12 that has stencil.
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
return DXGI_FORMAT_R24G8_TYPELESS;
|
||||
case wgpu::TextureFormat::Depth24PlusStencil8:
|
||||
|
@ -253,8 +255,6 @@ namespace dawn::native::d3d12 {
|
|||
case wgpu::TextureFormat::ASTC12x12UnormSrgb:
|
||||
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -346,6 +346,8 @@ namespace dawn::native::d3d12 {
|
|||
case wgpu::TextureFormat::Depth32Float:
|
||||
case wgpu::TextureFormat::Depth24Plus:
|
||||
return DXGI_FORMAT_D32_FLOAT;
|
||||
// Depth24UnormStencil8 is the smallest format supported on D3D12 that has stencil.
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
case wgpu::TextureFormat::Depth24PlusStencil8:
|
||||
|
@ -424,8 +426,6 @@ namespace dawn::native::d3d12 {
|
|||
case wgpu::TextureFormat::ASTC12x12Unorm:
|
||||
case wgpu::TextureFormat::ASTC12x12UnormSrgb:
|
||||
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -684,6 +684,7 @@ namespace dawn::native::d3d12 {
|
|||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
case wgpu::TextureFormat::Depth24PlusStencil8:
|
||||
case wgpu::TextureFormat::Depth32FloatStencil8:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
switch (aspect) {
|
||||
case Aspect::Depth:
|
||||
return DXGI_FORMAT_R32_FLOAT;
|
||||
|
@ -1179,6 +1180,7 @@ namespace dawn::native::d3d12 {
|
|||
case wgpu::TextureFormat::Depth16Unorm:
|
||||
mSrvDesc.Format = DXGI_FORMAT_R16_UNORM;
|
||||
break;
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
switch (descriptor->aspect) {
|
||||
case wgpu::TextureAspect::DepthOnly:
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace dawn::native::metal {
|
|||
newComputePipelineStateWithFunction:computeData.function.Get()
|
||||
error:&error]);
|
||||
if (error != nullptr) {
|
||||
return DAWN_INTERNAL_ERROR("Error creating pipeline state" +
|
||||
return DAWN_INTERNAL_ERROR("Error creating pipeline state " +
|
||||
std::string([error.localizedDescription UTF8String]));
|
||||
}
|
||||
ASSERT(mMtlComputePipelineState != nil);
|
||||
|
|
|
@ -391,7 +391,7 @@ namespace dawn::native::metal {
|
|||
AcquireNSPRef([mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
|
||||
error:&error]);
|
||||
if (error != nullptr) {
|
||||
return DAWN_INTERNAL_ERROR(std::string("Error creating pipeline state") +
|
||||
return DAWN_INTERNAL_ERROR(std::string("Error creating pipeline state ") +
|
||||
[error.localizedDescription UTF8String]);
|
||||
}
|
||||
ASSERT(mMtlRenderPipelineState != nil);
|
||||
|
|
|
@ -289,6 +289,8 @@ namespace dawn::native::metal {
|
|||
// TODO (dawn:1181): Allow non-conformant implementation on macOS 10.11
|
||||
UNREACHABLE();
|
||||
}
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
return MTLPixelFormatStencil8;
|
||||
|
||||
#if defined(DAWN_PLATFORM_MACOS)
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
|
@ -383,8 +385,6 @@ namespace dawn::native::metal {
|
|||
case wgpu::TextureFormat::ASTC12x12Unorm:
|
||||
case wgpu::TextureFormat::ASTC12x12UnormSrgb:
|
||||
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ namespace dawn::native::opengl {
|
|||
AddFormat(wgpu::TextureFormat::Depth24Plus, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, Type::DepthStencil);
|
||||
AddFormat(wgpu::TextureFormat::Depth24PlusStencil8, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, Type::DepthStencil);
|
||||
AddFormat(wgpu::TextureFormat::Depth16Unorm, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, Type::DepthStencil);
|
||||
AddFormat(wgpu::TextureFormat::Stencil8, GL_STENCIL_INDEX8, GL_STENCIL, GL_UNSIGNED_BYTE, Type::DepthStencil);
|
||||
|
||||
// Block compressed formats
|
||||
AddFormat(wgpu::TextureFormat::BC1RGBAUnorm, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
|
|
|
@ -46,6 +46,9 @@ namespace dawn::native::opengl {
|
|||
GLint GetStencilMaskFromStencilFormat(wgpu::TextureFormat depthStencilFormat) {
|
||||
switch (depthStencilFormat) {
|
||||
case wgpu::TextureFormat::Depth24PlusStencil8:
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
case wgpu::TextureFormat::Depth32FloatStencil8:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
return 0xFF;
|
||||
|
||||
default:
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace dawn::native::vulkan {
|
|||
|
||||
bool Adapter::IsDepthStencilFormatSupported(VkFormat format) {
|
||||
ASSERT(format == VK_FORMAT_D16_UNORM_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT ||
|
||||
format == VK_FORMAT_D32_SFLOAT_S8_UINT);
|
||||
format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_S8_UINT);
|
||||
|
||||
VkFormatProperties properties;
|
||||
mVulkanInstance->GetFunctions().GetPhysicalDeviceFormatProperties(mPhysicalDevice, format,
|
||||
|
|
|
@ -93,9 +93,9 @@ namespace dawn::native::vulkan {
|
|||
|
||||
DAWN_TRY(PrepareRecordingContext());
|
||||
|
||||
// The environment can request to use D32S8 or D24S8 when it's not available. Override
|
||||
// the decision if it is not applicable.
|
||||
ApplyDepth24PlusS8Toggle();
|
||||
// The environment can request to various options for depth-stencil formats that could be
|
||||
// unavailable. Override the decision if it is not applicable.
|
||||
ApplyDepthStencilFormatToggles();
|
||||
|
||||
// The environment can only request to use VK_KHR_zero_initialize_workgroup_memory when the
|
||||
// extension is available. Override the decision if it is no applicable.
|
||||
|
@ -518,13 +518,17 @@ namespace dawn::native::vulkan {
|
|||
// By default try to initialize workgroup memory with OpConstantNull according to the Vulkan
|
||||
// extension VK_KHR_zero_initialize_workgroup_memory.
|
||||
SetToggle(Toggle::VulkanUseZeroInitializeWorkgroupMemoryExtension, true);
|
||||
|
||||
// By default try to use S8 if available.
|
||||
SetToggle(Toggle::VulkanUseS8, true);
|
||||
}
|
||||
|
||||
void Device::ApplyDepth24PlusS8Toggle() {
|
||||
void Device::ApplyDepthStencilFormatToggles() {
|
||||
bool supportsD32s8 =
|
||||
ToBackend(GetAdapter())->IsDepthStencilFormatSupported(VK_FORMAT_D32_SFLOAT_S8_UINT);
|
||||
bool supportsD24s8 =
|
||||
ToBackend(GetAdapter())->IsDepthStencilFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT);
|
||||
bool supportsS8 = ToBackend(GetAdapter())->IsDepthStencilFormatSupported(VK_FORMAT_S8_UINT);
|
||||
|
||||
ASSERT(supportsD32s8 || supportsD24s8);
|
||||
|
||||
|
@ -534,6 +538,9 @@ namespace dawn::native::vulkan {
|
|||
if (!supportsD32s8) {
|
||||
ForceSetToggle(Toggle::VulkanUseD32S8, false);
|
||||
}
|
||||
if (!supportsS8) {
|
||||
ForceSetToggle(Toggle::VulkanUseS8, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::ApplyUseZeroInitializeWorkgroupMemoryExtensionToggle() {
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace dawn::native::vulkan {
|
|||
|
||||
uint32_t FindComputeSubgroupSize() const;
|
||||
void InitTogglesFromDriver();
|
||||
void ApplyDepth24PlusS8Toggle();
|
||||
void ApplyDepthStencilFormatToggles();
|
||||
void ApplyUseZeroInitializeWorkgroupMemoryExtensionToggle();
|
||||
|
||||
void DestroyImpl() override;
|
||||
|
|
|
@ -318,6 +318,14 @@ namespace dawn::native::vulkan {
|
|||
return VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
case wgpu::TextureFormat::Depth32FloatStencil8:
|
||||
return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
// Try to use the stencil8 format if possible, otherwise use whatever format we can
|
||||
// use that contains a stencil8 component.
|
||||
if (device->IsToggleEnabled(Toggle::VulkanUseS8)) {
|
||||
return VK_FORMAT_S8_UINT;
|
||||
} else {
|
||||
return VulkanImageFormat(device, wgpu::TextureFormat::Depth24PlusStencil8);
|
||||
}
|
||||
|
||||
case wgpu::TextureFormat::BC1RGBAUnorm:
|
||||
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
|
||||
|
@ -429,8 +437,6 @@ namespace dawn::native::vulkan {
|
|||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
break;
|
||||
}
|
||||
|
@ -982,6 +988,12 @@ namespace dawn::native::vulkan {
|
|||
// single plane in a new SubresourceStorage<TextureUsage>. The barriers will be produced
|
||||
// for DEPTH | STENCIL since the SubresourceRange uses Aspect::CombinedDepthStencil.
|
||||
bool Texture::ShouldCombineDepthStencilBarriers() const {
|
||||
// If the Stencil8 format is being emulated then memory barriers also need to include
|
||||
// the depth aspect. (See: crbug.com/dawn/1331)
|
||||
if (GetFormat().format == wgpu::TextureFormat::Stencil8 &&
|
||||
!GetDevice()->IsToggleEnabled(Toggle::VulkanUseS8)) {
|
||||
return true;
|
||||
}
|
||||
return GetFormat().aspects == (Aspect::Depth | Aspect::Stencil);
|
||||
}
|
||||
|
||||
|
|
|
@ -126,53 +126,6 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
|
|||
return device.CreateTexture(&texDescriptor);
|
||||
}
|
||||
|
||||
void PopulatePipelineDescriptorWriteDepth(utils::ComboRenderPipelineDescriptor* desc,
|
||||
wgpu::TextureFormat format,
|
||||
float regionDepth) {
|
||||
desc->vertex.module = mVertexModule;
|
||||
|
||||
std::string fsSource = R"(
|
||||
@stage(fragment) fn main() -> @builtin(frag_depth) f32 {
|
||||
return )" + std::to_string(regionDepth) +
|
||||
";\n}";
|
||||
|
||||
desc->cFragment.module = utils::CreateShaderModule(device, fsSource.c_str());
|
||||
wgpu::DepthStencilState* depthStencil = desc->EnableDepthStencil(format);
|
||||
depthStencil->depthWriteEnabled = true;
|
||||
desc->cFragment.targetCount = 0;
|
||||
}
|
||||
|
||||
// Initialize the depth/stencil values for the texture using a render pass.
|
||||
// The texture will be cleared to the "clear" value, and then bottom left corner will
|
||||
// be written with the "region" value.
|
||||
void InitializeDepthTextureRegion(wgpu::Texture texture,
|
||||
wgpu::TextureFormat depthFormat,
|
||||
float clearDepth,
|
||||
float regionDepth,
|
||||
uint32_t mipLevel = 0) {
|
||||
wgpu::TextureViewDescriptor viewDesc = {};
|
||||
viewDesc.baseMipLevel = mipLevel;
|
||||
viewDesc.mipLevelCount = 1;
|
||||
|
||||
utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc));
|
||||
renderPassDesc.UnsetDepthStencilLoadStoreOpsForFormat(depthFormat);
|
||||
renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = clearDepth;
|
||||
|
||||
utils::ComboRenderPipelineDescriptor renderPipelineDesc;
|
||||
PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, GetParam().mTextureFormat,
|
||||
regionDepth);
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPassDesc);
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.Draw(6);
|
||||
pass.End();
|
||||
|
||||
wgpu::CommandBuffer commands = commandEncoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
// Initialize the depth/stencil values for the texture using a render pass.
|
||||
// The texture will be cleared to the "clear" values, and then bottom left corner will
|
||||
// be written with the "region" values.
|
||||
|
@ -182,21 +135,43 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
|
|||
uint8_t clearStencil,
|
||||
uint8_t regionStencil,
|
||||
uint32_t mipLevel = 0) {
|
||||
wgpu::TextureFormat format = GetParam().mTextureFormat;
|
||||
// Create the render pass used for the initialization.
|
||||
utils::ComboRenderPipelineDescriptor renderPipelineDesc;
|
||||
renderPipelineDesc.vertex.module = mVertexModule;
|
||||
renderPipelineDesc.cFragment.targetCount = 0;
|
||||
|
||||
wgpu::DepthStencilState* depthStencil = renderPipelineDesc.EnableDepthStencil(format);
|
||||
|
||||
if (utils::IsStencilOnlyFormat(format)) {
|
||||
depthStencil->depthCompare = wgpu::CompareFunction::Always;
|
||||
renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, R"(
|
||||
@stage(fragment) fn main() {}
|
||||
)");
|
||||
} else {
|
||||
depthStencil->depthWriteEnabled = true;
|
||||
renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, std::string(R"(
|
||||
@stage(fragment) fn main() -> @builtin(frag_depth) f32 {
|
||||
return )" + std::to_string(regionDepth) + R"(;
|
||||
})")
|
||||
.c_str());
|
||||
}
|
||||
if (!utils::IsDepthOnlyFormat(format)) {
|
||||
depthStencil->stencilFront.passOp = wgpu::StencilOperation::Replace;
|
||||
}
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
|
||||
|
||||
// Build the render pass used for initialization.
|
||||
wgpu::TextureViewDescriptor viewDesc = {};
|
||||
viewDesc.baseMipLevel = mipLevel;
|
||||
viewDesc.mipLevelCount = 1;
|
||||
|
||||
utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc));
|
||||
renderPassDesc.UnsetDepthStencilLoadStoreOpsForFormat(format);
|
||||
renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = clearDepth;
|
||||
renderPassDesc.cDepthStencilAttachmentInfo.stencilClearValue = clearStencil;
|
||||
|
||||
utils::ComboRenderPipelineDescriptor renderPipelineDesc;
|
||||
PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, GetParam().mTextureFormat,
|
||||
regionDepth);
|
||||
renderPipelineDesc.cDepthStencil.stencilFront.passOp = wgpu::StencilOperation::Replace;
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
|
||||
|
||||
// Draw the quad (two triangles)
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPassDesc);
|
||||
|
@ -471,7 +446,7 @@ TEST_P(DepthCopyTests, FromDepthAspect) {
|
|||
kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);
|
||||
|
||||
constexpr float kInitDepth = 0.2f;
|
||||
InitializeDepthTextureRegion(texture, GetParam().mTextureFormat, 0.f, kInitDepth);
|
||||
InitializeDepthStencilTextureRegion(texture, 0.f, kInitDepth, 0, 0);
|
||||
|
||||
// This expectation is the test as it performs the CopyTextureToBuffer.
|
||||
if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
|
||||
|
@ -511,7 +486,7 @@ TEST_P(DepthCopyTests, FromNonZeroMipDepthAspect) {
|
|||
9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2);
|
||||
|
||||
constexpr float kInitDepth = 0.4f;
|
||||
InitializeDepthTextureRegion(depthTexture, GetParam().mTextureFormat, 0.f, kInitDepth, 1);
|
||||
InitializeDepthStencilTextureRegion(depthTexture, 0.f, kInitDepth, 0, 0, /*mipLevel*/ 1);
|
||||
|
||||
// This expectation is the test as it performs the CopyTextureToBuffer.
|
||||
if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
|
||||
|
@ -670,17 +645,19 @@ TEST_P(StencilCopyTests, ToStencilAspect) {
|
|||
// Create a stencil texture
|
||||
constexpr uint32_t kWidth = 4;
|
||||
constexpr uint32_t kHeight = 4;
|
||||
const bool hasDepth = !utils::IsStencilOnlyFormat(GetParam().mTextureFormat);
|
||||
|
||||
wgpu::Texture depthStencilTexture =
|
||||
CreateDepthStencilTexture(kWidth, kHeight,
|
||||
wgpu::TextureUsage::RenderAttachment |
|
||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst);
|
||||
|
||||
{
|
||||
if (hasDepth) {
|
||||
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||
|
||||
// Clear depth to 0.7, so we can check that the stencil copy doesn't mutate the depth.
|
||||
utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
|
||||
passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(GetParam().mTextureFormat);
|
||||
passDescriptor.cDepthStencilAttachmentInfo.depthClearValue = 0.7;
|
||||
|
||||
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
|
||||
|
@ -727,10 +704,14 @@ TEST_P(StencilCopyTests, ToStencilAspect) {
|
|||
renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, R"(
|
||||
@stage(fragment) fn main() {
|
||||
})");
|
||||
renderPipelineDesc.cFragment.targetCount = 0;
|
||||
wgpu::DepthStencilState* depthStencil =
|
||||
renderPipelineDesc.EnableDepthStencil(GetParam().mTextureFormat);
|
||||
depthStencil->stencilFront.passOp = wgpu::StencilOperation::DecrementClamp;
|
||||
renderPipelineDesc.cFragment.targetCount = 0;
|
||||
if (!hasDepth) {
|
||||
depthStencil->depthWriteEnabled = false;
|
||||
depthStencil->depthCompare = wgpu::CompareFunction::Always;
|
||||
}
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
|
||||
|
||||
|
@ -739,6 +720,7 @@ TEST_P(StencilCopyTests, ToStencilAspect) {
|
|||
utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
|
||||
passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
|
||||
passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
|
||||
passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(GetParam().mTextureFormat);
|
||||
|
||||
// Draw the quad in the bottom left (two triangles).
|
||||
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
|
||||
|
@ -754,19 +736,23 @@ TEST_P(StencilCopyTests, ToStencilAspect) {
|
|||
EXPECT_TEXTURE_EQ(expectedStencilData.data(), depthStencilTexture, {0, 0}, {kWidth, kHeight}, 0,
|
||||
wgpu::TextureAspect::StencilOnly);
|
||||
|
||||
ExpectAttachmentDepthTestData(depthStencilTexture, GetParam().mTextureFormat, kWidth, kHeight,
|
||||
0, 0,
|
||||
{
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
});
|
||||
if (hasDepth) {
|
||||
ExpectAttachmentDepthTestData(depthStencilTexture, GetParam().mTextureFormat, kWidth,
|
||||
kHeight, 0, 0,
|
||||
{
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
0.7, 0.7, 0.7, 0.7, //
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST_P(DepthStencilCopyTests,
|
||||
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
|
||||
VulkanBackend()},
|
||||
// Test with the vulkan_use_s8 toggle forced on and off.
|
||||
VulkanBackend({"vulkan_use_s8"}, {}),
|
||||
VulkanBackend({}, {"vulkan_use_s8"})},
|
||||
std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
|
||||
utils::kDepthAndStencilFormats.end()));
|
||||
|
||||
|
@ -784,6 +770,8 @@ DAWN_INSTANTIATE_TEST_P(DepthCopyFromBufferTests,
|
|||
|
||||
DAWN_INSTANTIATE_TEST_P(StencilCopyTests,
|
||||
{D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
|
||||
VulkanBackend()},
|
||||
// Test with the vulkan_use_s8 toggle forced on and off.
|
||||
VulkanBackend({"vulkan_use_s8"}, {}),
|
||||
VulkanBackend({}, {"vulkan_use_s8"})},
|
||||
std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(),
|
||||
utils::kStencilFormats.end()));
|
||||
|
|
|
@ -215,12 +215,17 @@ namespace utils {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsStencilOnlyFormat(wgpu::TextureFormat textureFormat) {
|
||||
return textureFormat == wgpu::TextureFormat::Stencil8;
|
||||
}
|
||||
|
||||
uint32_t GetTexelBlockSizeInBytes(wgpu::TextureFormat textureFormat) {
|
||||
switch (textureFormat) {
|
||||
case wgpu::TextureFormat::R8Unorm:
|
||||
case wgpu::TextureFormat::R8Snorm:
|
||||
case wgpu::TextureFormat::R8Uint:
|
||||
case wgpu::TextureFormat::R8Sint:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
return 1u;
|
||||
|
||||
case wgpu::TextureFormat::R16Uint:
|
||||
|
@ -339,8 +344,6 @@ namespace utils {
|
|||
// Block size of a multi-planar format depends on aspect.
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
break;
|
||||
}
|
||||
|
@ -391,6 +394,7 @@ namespace utils {
|
|||
case wgpu::TextureFormat::Depth16Unorm:
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
case wgpu::TextureFormat::Depth32FloatStencil8:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
return 1u;
|
||||
|
||||
case wgpu::TextureFormat::BC1RGBAUnorm:
|
||||
|
@ -457,8 +461,6 @@ namespace utils {
|
|||
// Block size of a multi-planar format depends on aspect.
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
break;
|
||||
}
|
||||
|
@ -509,6 +511,7 @@ namespace utils {
|
|||
case wgpu::TextureFormat::Depth16Unorm:
|
||||
case wgpu::TextureFormat::Depth24UnormStencil8:
|
||||
case wgpu::TextureFormat::Depth32FloatStencil8:
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
return 1u;
|
||||
|
||||
case wgpu::TextureFormat::BC1RGBAUnorm:
|
||||
|
@ -575,8 +578,6 @@ namespace utils {
|
|||
// Block size of a multi-planar format depends on aspect.
|
||||
case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
|
||||
|
||||
// TODO(dawn:666): implement stencil8
|
||||
case wgpu::TextureFormat::Stencil8:
|
||||
case wgpu::TextureFormat::Undefined:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
#include "dawn/common/Assert.h"
|
||||
|
||||
namespace utils {
|
||||
// TODO(dawn:666): Add Stencil8 format when it's implemented.
|
||||
static constexpr std::array<wgpu::TextureFormat, 94> kAllTextureFormats = {
|
||||
static constexpr std::array<wgpu::TextureFormat, 95> kAllTextureFormats = {
|
||||
wgpu::TextureFormat::R8Unorm,
|
||||
wgpu::TextureFormat::R8Snorm,
|
||||
wgpu::TextureFormat::R8Uint,
|
||||
|
@ -66,6 +65,7 @@ namespace utils {
|
|||
wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
wgpu::TextureFormat::Depth24UnormStencil8,
|
||||
wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
wgpu::TextureFormat::Stencil8,
|
||||
wgpu::TextureFormat::BC1RGBAUnorm,
|
||||
wgpu::TextureFormat::BC1RGBAUnormSrgb,
|
||||
wgpu::TextureFormat::BC2RGBAUnorm,
|
||||
|
@ -206,16 +206,16 @@ namespace utils {
|
|||
kBCFormats.size() + kETC2Formats.size() + kASTCFormats.size(),
|
||||
"Number of compressed format must equal number of BC, ETC2, and ASTC formats.");
|
||||
|
||||
// TODO(dawn:666): Add Stencil8 format when it's implemented.
|
||||
static constexpr std::array<wgpu::TextureFormat, 6> kDepthFormats = {
|
||||
wgpu::TextureFormat::Depth16Unorm, wgpu::TextureFormat::Depth32Float,
|
||||
wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
wgpu::TextureFormat::Depth24UnormStencil8, wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
};
|
||||
static constexpr std::array<wgpu::TextureFormat, 3> kStencilFormats = {
|
||||
static constexpr std::array<wgpu::TextureFormat, 4> kStencilFormats = {
|
||||
wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
wgpu::TextureFormat::Depth24UnormStencil8,
|
||||
wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
wgpu::TextureFormat::Stencil8,
|
||||
};
|
||||
static constexpr std::array<wgpu::TextureFormat, 3> kDepthAndStencilFormats = {
|
||||
wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
|
@ -230,6 +230,7 @@ namespace utils {
|
|||
bool IsASTCTextureFormat(wgpu::TextureFormat textureFormat);
|
||||
|
||||
bool IsDepthOnlyFormat(wgpu::TextureFormat textureFormat);
|
||||
bool IsStencilOnlyFormat(wgpu::TextureFormat textureFormat);
|
||||
|
||||
bool TextureFormatSupportsMultisampling(wgpu::TextureFormat textureFormat);
|
||||
bool TextureFormatSupportsResolveTarget(wgpu::TextureFormat textureFormat);
|
||||
|
|
Loading…
Reference in New Issue