Commit 0cec82a5 by Jamie Madill Committed by Commit Bot

Vulkan: Implement basic depth/stencil buffers.

This implements basic depth/stencil states and clearing. This also implements "fallback" texture formats in the texture generation. Fallback formats are those that are chosen at runtime for replacements for main formats which lack driver support. They are different from override formats, which are always used because we assume there is no driver support. The Vulkan spec only asserts that one of the two of D32 or D24 has mandatory support. In the case of AMD, D24 is not supported fully, and we need the fallback format support emulation. Bug: angleproject:2357 Change-Id: Ic86cede3c69ff9893a06b3a55c3b5d2d897fa55f Reviewed-on: https://chromium-review.googlesource.com/916701 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent d92d9dd1
...@@ -568,10 +568,10 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits ...@@ -568,10 +568,10 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
WARN() << "DIRTY_BIT_SAMPLE_MASK unimplemented"; WARN() << "DIRTY_BIT_SAMPLE_MASK unimplemented";
break; break;
case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
WARN() << "DIRTY_BIT_DEPTH_TEST_ENABLED unimplemented"; mPipelineDesc->updateDepthTestEnabled(glState.getDepthStencilState());
break; break;
case gl::State::DIRTY_BIT_DEPTH_FUNC: case gl::State::DIRTY_BIT_DEPTH_FUNC:
WARN() << "DIRTY_BIT_DEPTH_FUNC unimplemented"; mPipelineDesc->updateDepthFunc(glState.getDepthStencilState());
break; break;
case gl::State::DIRTY_BIT_DEPTH_MASK: case gl::State::DIRTY_BIT_DEPTH_MASK:
WARN() << "DIRTY_BIT_DEPTH_MASK unimplemented"; WARN() << "DIRTY_BIT_DEPTH_MASK unimplemented";
......
...@@ -115,21 +115,50 @@ gl::Error FramebufferVk::invalidateSub(const gl::Context *context, ...@@ -115,21 +115,50 @@ gl::Error FramebufferVk::invalidateSub(const gl::Context *context,
gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
{ {
if (mState.getDepthAttachment() && (mask & GL_DEPTH_BUFFER_BIT) != 0) ContextVk *contextVk = vk::GetImpl(context);
{ RendererVk *renderer = contextVk->getRenderer();
// TODO(jmadill): Depth clear Serial currentSerial = renderer->getCurrentQueueSerial();
UNIMPLEMENTED();
}
if (mState.getStencilAttachment() && (mask & GL_STENCIL_BUFFER_BIT) != 0) // This command buffer is only started once.
{ vk::CommandBuffer *commandBuffer = nullptr;
// TODO(jmadill): Stencil clear vk::CommandGraphNode *writingNode = nullptr;
UNIMPLEMENTED();
}
if ((mask & GL_COLOR_BUFFER_BIT) == 0) const gl::FramebufferAttachment *depthAttachment = mState.getDepthAttachment();
bool clearDepth = (depthAttachment && (mask & GL_DEPTH_BUFFER_BIT) != 0);
ASSERT(!clearDepth || depthAttachment->isAttached());
const gl::FramebufferAttachment *stencilAttachment = mState.getStencilAttachment();
bool clearStencil = (stencilAttachment && (mask & GL_STENCIL_BUFFER_BIT) != 0);
ASSERT(!clearStencil || stencilAttachment->isAttached());
// Depth/stencil clear.
if (clearDepth || clearStencil)
{ {
return gl::NoError(); ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
writingNode = getCurrentWritingNode(currentSerial);
const VkClearDepthStencilValue &clearDepthStencilValue =
contextVk->getClearDepthStencilValue().depthStencil;
// We only support packed depth/stencil, not separate.
ASSERT(!(clearDepth && clearStencil) || mState.getDepthStencilAttachment());
const VkImageAspectFlags aspectFlags = (clearDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(clearDepth ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
renderTarget->resource->onWriteResource(writingNode, currentSerial);
renderTarget->image->changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(*renderTarget->image, aspectFlags,
clearDepthStencilValue);
if ((mask & GL_COLOR_BUFFER_BIT) == 0)
{
return gl::NoError();
}
} }
if (context->getGLState().isScissorTestEnabled()) if (context->getGLState().isScissorTestEnabled())
...@@ -143,16 +172,12 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -143,16 +172,12 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
const auto *attachment = mState.getFirstNonNullAttachment(); const auto *attachment = mState.getFirstNonNullAttachment();
ASSERT(attachment && attachment->isAttached()); ASSERT(attachment && attachment->isAttached());
const auto &size = attachment->getSize();
const gl::Rectangle renderArea(0, 0, size.width, size.height);
ContextVk *contextVk = vk::GetImpl(context); if (!commandBuffer)
RendererVk *renderer = contextVk->getRenderer(); {
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
vk::CommandBuffer *commandBuffer = nullptr; writingNode = getCurrentWritingNode(currentSerial);
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer)); }
Serial currentSerial = renderer->getCurrentQueueSerial();
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394 // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
...@@ -160,8 +185,7 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -160,8 +185,7 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
{ {
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget); ASSERT(colorRenderTarget);
colorRenderTarget->resource->onWriteResource(getCurrentWritingNode(currentSerial), colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
currentSerial);
colorRenderTarget->image->changeLayoutWithStages( colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
...@@ -171,8 +195,6 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -171,8 +195,6 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
contextVk->getClearColorValue().color); contextVk->getClearColorValue().color);
} }
// TODO(jmadill): Depth/stencil clear.
return gl::NoError(); return gl::NoError();
} }
......
...@@ -74,7 +74,34 @@ format_entry_template = """{space}case angle::Format::ID::{format_id}: ...@@ -74,7 +74,34 @@ format_entry_template = """{space}case angle::Format::ID::{format_id}:
{space}}} {space}}}
""" """
def gen_format_case(angle, internal_format, vk_map, vk_overrides): # This currently only handles texture fallback formats.
fallback_format_entry_template = """{space}case angle::Format::ID::{format_id}:
{space}{{
{space} internalFormat = {internal_format};
{space} if (!HasFullFormatSupport(physicalDevice, {vk_texture_format}))
{space} {{
{space} textureFormatID = angle::Format::ID::{fallback_texture};
{space} vkTextureFormat = {fallback_vk_texture_format};
{space} dataInitializerFunction = {fallback_initializer};
{space} ASSERT(HasFullFormatSupport(physicalDevice, {fallback_vk_texture_format}));
{space} }}
{space} else
{space} {{
{space} textureFormatID = angle::Format::ID::{texture};
{space} vkTextureFormat = {vk_texture_format};
{space} dataInitializerFunction = {initializer};
{space} }}
{space} bufferFormatID = angle::Format::ID::{buffer};
{space} vkBufferFormat = {vk_buffer_format};
{space} break;
{space}}}
"""
def gen_format_case(angle, internal_format, vk_json_data):
vk_map = vk_json_data["map"]
vk_overrides = vk_json_data["overrides"]
vk_fallbacks = vk_json_data["fallbacks"]
args = { args = {
"space": " ", "space": " ",
...@@ -82,9 +109,12 @@ def gen_format_case(angle, internal_format, vk_map, vk_overrides): ...@@ -82,9 +109,12 @@ def gen_format_case(angle, internal_format, vk_map, vk_overrides):
"internal_format": internal_format "internal_format": internal_format
} }
if (angle not in vk_map and angle not in vk_overrides) or angle == 'NONE': if ((angle not in vk_map) and (angle not in vk_overrides) and
(angle not in vk_fallbacks)) or angle == 'NONE':
return empty_format_entry_template.format(**args) return empty_format_entry_template.format(**args)
template = format_entry_template
if angle in vk_map: if angle in vk_map:
args["buffer"] = angle args["buffer"] = angle
args["texture"] = angle args["texture"] = angle
...@@ -92,6 +122,17 @@ def gen_format_case(angle, internal_format, vk_map, vk_overrides): ...@@ -92,6 +122,17 @@ def gen_format_case(angle, internal_format, vk_map, vk_overrides):
if angle in vk_overrides: if angle in vk_overrides:
args.update(vk_overrides[angle]) args.update(vk_overrides[angle])
if angle in vk_fallbacks:
template = fallback_format_entry_template
fallback = vk_fallbacks[angle]
assert not "buffer" in fallback, "Buffer fallbacks not yet supported"
assert "texture" in fallback, "Fallback must have a texture fallback"
args["fallback_texture"] = fallback["texture"]
args["fallback_vk_texture_format"] = vk_map[fallback["texture"]]
args["fallback_initializer"] = angle_format.get_internal_format_initializer(
internal_format, fallback["texture"])
assert "buffer" in args, "Missing buffer format for " + angle assert "buffer" in args, "Missing buffer format for " + angle
assert "texture" in args, "Missing texture format for " + angle assert "texture" in args, "Missing texture format for " + angle
...@@ -101,16 +142,15 @@ def gen_format_case(angle, internal_format, vk_map, vk_overrides): ...@@ -101,16 +142,15 @@ def gen_format_case(angle, internal_format, vk_map, vk_overrides):
args["initializer"] = angle_format.get_internal_format_initializer( args["initializer"] = angle_format.get_internal_format_initializer(
internal_format, args["texture"]) internal_format, args["texture"])
return format_entry_template.format(**args) return template.format(**args)
input_file_name = 'vk_format_map.json' input_file_name = 'vk_format_map.json'
out_file_name = 'vk_format_table' out_file_name = 'vk_format_table'
angle_to_gl = angle_format.load_inverse_table(os.path.join('..', 'angle_format_map.json')) angle_to_gl = angle_format.load_inverse_table(os.path.join('..', 'angle_format_map.json'))
vk_json_data = angle_format.load_json(input_file_name) vk_json_data = angle_format.load_json(input_file_name)
vk_map = vk_json_data["map"] vk_cases = [gen_format_case(angle, gl, vk_json_data)
vk_overrides = vk_json_data["overrides"] for angle, gl in sorted(angle_to_gl.iteritems())]
vk_cases = [gen_format_case(angle, gl, vk_map, vk_overrides) for angle, gl in sorted(angle_to_gl.iteritems())]
output_cpp = template_table_autogen_cpp.format( output_cpp = template_table_autogen_cpp.format(
copyright_year = date.today().year, copyright_year = date.today().year,
......
...@@ -81,6 +81,32 @@ uint8_t PackGLBlendFactor(GLenum blendFactor) ...@@ -81,6 +81,32 @@ uint8_t PackGLBlendFactor(GLenum blendFactor)
} }
} }
uint8_t PackGLCompareFunc(GLenum compareFunc)
{
switch (compareFunc)
{
case GL_NEVER:
return VK_COMPARE_OP_NEVER;
case GL_ALWAYS:
return VK_COMPARE_OP_ALWAYS;
case GL_LESS:
return VK_COMPARE_OP_LESS;
case GL_LEQUAL:
return VK_COMPARE_OP_LESS_OR_EQUAL;
case GL_EQUAL:
return VK_COMPARE_OP_EQUAL;
case GL_GREATER:
return VK_COMPARE_OP_GREATER;
case GL_GEQUAL:
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case GL_NOTEQUAL:
return VK_COMPARE_OP_NOT_EQUAL;
default:
UNREACHABLE();
return 0;
}
}
VkSampleCountFlagBits ConvertSamples(GLint sampleCount) VkSampleCountFlagBits ConvertSamples(GLint sampleCount)
{ {
switch (sampleCount) switch (sampleCount)
...@@ -694,6 +720,16 @@ void PipelineDesc::updateBlendFuncs(const gl::BlendState &blendState) ...@@ -694,6 +720,16 @@ void PipelineDesc::updateBlendFuncs(const gl::BlendState &blendState)
} }
} }
void PipelineDesc::updateDepthTestEnabled(const gl::DepthStencilState &depthStencilState)
{
mDepthStencilStateInfo.depthTestEnable = static_cast<uint8_t>(depthStencilState.depthTest);
}
void PipelineDesc::updateDepthFunc(const gl::DepthStencilState &depthStencilState)
{
mDepthStencilStateInfo.depthCompareOp = PackGLCompareFunc(depthStencilState.depthFunc);
}
void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc) void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc)
{ {
mRenderPassDesc = renderPassDesc; mRenderPassDesc = renderPassDesc;
......
...@@ -298,9 +298,11 @@ class PipelineDesc final ...@@ -298,9 +298,11 @@ class PipelineDesc final
void updateBlendFuncs(const gl::BlendState &blend_state); void updateBlendFuncs(const gl::BlendState &blend_state);
void updateBlendEquations(const gl::BlendState &blend_state); void updateBlendEquations(const gl::BlendState &blend_state);
private: // Depth/stencil states.
void fillAllColorAttachments(PackedColorBlendAttachmentState blendAttachmentState); void updateDepthTestEnabled(const gl::DepthStencilState &depthStencilState);
void updateDepthFunc(const gl::DepthStencilState &depthStencilState);
private:
// TODO(jmadill): Handle Geometry/Compute shaders when necessary. // TODO(jmadill): Handle Geometry/Compute shaders when necessary.
ShaderStageInfo mShaderStageInfo; ShaderStageInfo mShaderStageInfo;
VertexInputBindings mVertexInputBindings; VertexInputBindings mVertexInputBindings;
......
...@@ -14,12 +14,7 @@ ...@@ -14,12 +14,7 @@
namespace namespace
{ {
constexpr unsigned int kComponentsPerVector = 4; constexpr unsigned int kComponentsPerVector = 4;
bool HasFormatFeatureBits(const VkFormatFeatureFlags featureBits, } // anonymous namespace
const VkFormatProperties &formatProperties)
{
return (formatProperties.optimalTilingFeatures & featureBits) == featureBits;
}
}
namespace rx namespace rx
{ {
...@@ -127,17 +122,5 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties, ...@@ -127,17 +122,5 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
// TODO(jmadill): count reserved varyings // TODO(jmadill): count reserved varyings
outCaps->maxVaryingVectors = physicalDeviceProperties.limits.maxVertexOutputComponents / 4; outCaps->maxVaryingVectors = physicalDeviceProperties.limits.maxVertexOutputComponents / 4;
} }
void FillTextureFormatCaps(const VkFormatProperties &formatProperties,
gl::TextureCaps *outTextureCaps)
{
outTextureCaps->texturable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, formatProperties);
outTextureCaps->filterable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, formatProperties);
outTextureCaps->renderable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, formatProperties) ||
HasFormatFeatureBits(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, formatProperties);
}
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
...@@ -26,17 +26,11 @@ namespace rx ...@@ -26,17 +26,11 @@ namespace rx
namespace vk namespace vk
{ {
class FormatTable;
void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties, void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
const gl::TextureCapsMap &textureCaps, const gl::TextureCapsMap &textureCaps,
gl::Caps *outCaps, gl::Caps *outCaps,
gl::Extensions *outExtensions, gl::Extensions *outExtensions,
gl::Limitations * /* outLimitations */); gl::Limitations * /* outLimitations */);
void FillTextureFormatCaps(const VkFormatProperties &formatProperties,
gl::TextureCaps *outTextureCaps);
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
......
...@@ -13,9 +13,14 @@ ...@@ -13,9 +13,14 @@
"formats use the overrides table for emulation.", "formats use the overrides table for emulation.",
"", "",
"We implement formats that aren't natively supported in Vulkan using", "We implement formats that aren't natively supported in Vulkan using",
"overrides. The overrides are specified by a second dictionary (also keyed on", "fallback and override formats. These are specified as dictionaries (also keyed on",
"the angle format ID), with two optional entries for Buffer and Texture/Image", "the angle format ID), with two optional entries for Buffer and Texture/Image",
"formats overrides. Each entry specifies a format.", "formats. Each entry specifies a fallback or override format.",
"",
"Override formats are used for emulated support for formats we assume are never",
"supported by any Vulkan device, although they might exist. Fallback formats",
"differ in that they are tested at runtime for support, and we only fall back",
"if the main format is not available on this device.",
"", "",
"Also see gen_vk_format_table.py for the code generation step." "Also see gen_vk_format_table.py for the code generation step."
], ],
...@@ -124,7 +129,7 @@ ...@@ -124,7 +129,7 @@
"S8_UINT": "VK_FORMAT_S8_UINT", "S8_UINT": "VK_FORMAT_S8_UINT",
"D16_UNORM_S8_UINT": "VK_FORMAT_D16_UNORM_S8_UINT", "D16_UNORM_S8_UINT": "VK_FORMAT_D16_UNORM_S8_UINT",
"D24_UNORM_S8_UINT": "VK_FORMAT_D24_UNORM_S8_UINT", "D24_UNORM_S8_UINT": "VK_FORMAT_D24_UNORM_S8_UINT",
"D32_SFLOAT_S8_UINT": "VK_FORMAT_D32_SFLOAT_S8_UINT", "D32_FLOAT_S8X24_UINT": "VK_FORMAT_D32_SFLOAT_S8_UINT",
"BC1_RGB_UNORM_BLOCK": "VK_FORMAT_BC1_RGB_UNORM_BLOCK", "BC1_RGB_UNORM_BLOCK": "VK_FORMAT_BC1_RGB_UNORM_BLOCK",
"BC1_RGB_SRGB_BLOCK": "VK_FORMAT_BC1_RGB_SRGB_BLOCK", "BC1_RGB_SRGB_BLOCK": "VK_FORMAT_BC1_RGB_SRGB_BLOCK",
"BC1_RGBA_UNORM_BLOCK": "VK_FORMAT_BC1_RGBA_UNORM_BLOCK", "BC1_RGBA_UNORM_BLOCK": "VK_FORMAT_BC1_RGBA_UNORM_BLOCK",
...@@ -192,5 +197,13 @@ ...@@ -192,5 +197,13 @@
"R8G8B8_UNORM": { "R8G8B8_UNORM": {
"texture": "R8G8B8A8_UNORM" "texture": "R8G8B8A8_UNORM"
} }
},
"fallbacks": {
"D32_FLOAT_S8X24_UINT": {
"texture": "D24_UNORM_S8_UINT"
},
"D24_UNORM_S8_UINT": {
"texture": "D32_FLOAT_S8X24_UINT"
}
} }
} }
...@@ -462,12 +462,22 @@ void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &an ...@@ -462,12 +462,22 @@ void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &an
case angle::Format::ID::D24_UNORM_S8_UINT: case angle::Format::ID::D24_UNORM_S8_UINT:
{ {
internalFormat = GL_DEPTH24_STENCIL8; internalFormat = GL_DEPTH24_STENCIL8;
textureFormatID = angle::Format::ID::D24_UNORM_S8_UINT; if (!HasFullFormatSupport(physicalDevice, VK_FORMAT_D24_UNORM_S8_UINT))
vkTextureFormat = VK_FORMAT_D24_UNORM_S8_UINT; {
bufferFormatID = angle::Format::ID::D24_UNORM_S8_UINT; textureFormatID = angle::Format::ID::D32_FLOAT_S8X24_UINT;
vkBufferFormat = VK_FORMAT_D24_UNORM_S8_UINT; vkTextureFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
dataInitializerFunction = nullptr; dataInitializerFunction = nullptr;
ASSERT(HasFullFormatSupport(physicalDevice, VK_FORMAT_D32_SFLOAT_S8_UINT));
}
else
{
textureFormatID = angle::Format::ID::D24_UNORM_S8_UINT;
vkTextureFormat = VK_FORMAT_D24_UNORM_S8_UINT;
dataInitializerFunction = nullptr;
}
bufferFormatID = angle::Format::ID::D24_UNORM_S8_UINT;
vkBufferFormat = VK_FORMAT_D24_UNORM_S8_UINT;
break; break;
} }
...@@ -483,8 +493,25 @@ void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &an ...@@ -483,8 +493,25 @@ void Format::initialize(VkPhysicalDevice physicalDevice, const angle::Format &an
} }
case angle::Format::ID::D32_FLOAT_S8X24_UINT: case angle::Format::ID::D32_FLOAT_S8X24_UINT:
// This format is not implemented in Vulkan. {
internalFormat = GL_DEPTH32F_STENCIL8;
if (!HasFullFormatSupport(physicalDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
{
textureFormatID = angle::Format::ID::D24_UNORM_S8_UINT;
vkTextureFormat = VK_FORMAT_D24_UNORM_S8_UINT;
dataInitializerFunction = nullptr;
ASSERT(HasFullFormatSupport(physicalDevice, VK_FORMAT_D24_UNORM_S8_UINT));
}
else
{
textureFormatID = angle::Format::ID::D32_FLOAT_S8X24_UINT;
vkTextureFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
dataInitializerFunction = nullptr;
}
bufferFormatID = angle::Format::ID::D32_FLOAT_S8X24_UINT;
vkBufferFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
break; break;
}
case angle::Format::ID::D32_UNORM: case angle::Format::ID::D32_UNORM:
// This format is not implemented in Vulkan. // This format is not implemented in Vulkan.
......
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/load_functions_table.h" #include "libANGLE/renderer/load_functions_table.h"
#include "vk_caps_utils.h" #include "libANGLE/renderer/vulkan/vk_caps_utils.h"
namespace rx
{
namespace namespace
{ {
constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportDepthStencil = constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportDepthStencil =
...@@ -20,13 +22,64 @@ constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportDepthStencil = ...@@ -20,13 +22,64 @@ constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportDepthStencil =
constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportColor = constexpr VkFormatFeatureFlags kNecessaryBitsFullSupportColor =
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
} // anonymous namespace
namespace rx bool HasFormatFeatureBits(const VkFormatFeatureFlags featureBits,
const VkFormatProperties &formatProperties)
{
return IsMaskFlagSet(formatProperties.optimalTilingFeatures, featureBits);
}
void FillTextureFormatCaps(const VkFormatProperties &formatProperties,
gl::TextureCaps *outTextureCaps)
{ {
outTextureCaps->texturable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, formatProperties);
outTextureCaps->filterable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, formatProperties);
outTextureCaps->renderable =
HasFormatFeatureBits(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, formatProperties) ||
HasFormatFeatureBits(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, formatProperties);
}
void GetFormatProperties(VkPhysicalDevice physicalDevice,
VkFormat vkFormat,
VkFormatProperties *propertiesOut)
{
// Try filling out the info from our hard coded format data, if we can't find the
// information we need, we'll make the call to Vulkan.
const VkFormatProperties &formatProperties = vk::GetMandatoryFormatSupport(vkFormat);
// Once we filled what we could with the mandatory texture caps, we verify if
// all the bits we need to satify all our checks are present, and if so we can
// skip the device call.
if (!IsMaskFlagSet(formatProperties.optimalTilingFeatures, kNecessaryBitsFullSupportColor) &&
!IsMaskFlagSet(formatProperties.optimalTilingFeatures,
kNecessaryBitsFullSupportDepthStencil))
{
vkGetPhysicalDeviceFormatProperties(physicalDevice, vkFormat, propertiesOut);
}
else
{
*propertiesOut = formatProperties;
}
}
} // anonymous namespace
namespace vk namespace vk
{ {
bool HasFullFormatSupport(VkPhysicalDevice physicalDevice, VkFormat vkFormat)
{
VkFormatProperties formatProperties;
GetFormatProperties(physicalDevice, vkFormat, &formatProperties);
constexpr uint32_t kBitsColor =
(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
constexpr uint32_t kBitsDepth = (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
return HasFormatFeatureBits(kBitsColor, formatProperties) ||
HasFormatFeatureBits(kBitsDepth, formatProperties);
}
Format::Format() Format::Format()
: internalFormat(GL_NONE), : internalFormat(GL_NONE),
...@@ -81,26 +134,10 @@ void FormatTable::initialize(VkPhysicalDevice physicalDevice, ...@@ -81,26 +134,10 @@ void FormatTable::initialize(VkPhysicalDevice physicalDevice,
// Try filling out the info from our hard coded format data, if we can't find the // Try filling out the info from our hard coded format data, if we can't find the
// information we need, we'll make the call to Vulkan. // information we need, we'll make the call to Vulkan.
const VkFormatProperties &formatProperties = GetMandatoryFormatSupport(vkFormat); VkFormatProperties formatProperties;
GetFormatProperties(physicalDevice, vkFormat, &formatProperties);
gl::TextureCaps textureCaps; gl::TextureCaps textureCaps;
FillTextureFormatCaps(formatProperties, &textureCaps);
// Once we filled what we could with the mandatory texture caps, we verify if
// all the bits we need to satify all our checks are present, and if so we can
// skip the device call.
if (!IsMaskFlagSet(formatProperties.optimalTilingFeatures,
kNecessaryBitsFullSupportColor) &&
!IsMaskFlagSet(formatProperties.optimalTilingFeatures,
kNecessaryBitsFullSupportDepthStencil))
{
VkFormatProperties queriedFormatProperties;
vkGetPhysicalDeviceFormatProperties(physicalDevice, vkFormat, &queriedFormatProperties);
FillTextureFormatCaps(queriedFormatProperties, &textureCaps);
}
else
{
FillTextureFormatCaps(formatProperties, &textureCaps);
}
outTextureCapsMap->set(formatID, textureCaps); outTextureCapsMap->set(formatID, textureCaps);
// TODO(lucferron): Optimize this by including compressed bool in the FormatID // TODO(lucferron): Optimize this by including compressed bool in the FormatID
......
...@@ -76,6 +76,8 @@ VkFormat GetNativeVertexFormat(gl::VertexFormatType vertexFormat); ...@@ -76,6 +76,8 @@ VkFormat GetNativeVertexFormat(gl::VertexFormatType vertexFormat);
// initialized to 0. // initialized to 0.
const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat); const VkFormatProperties &GetMandatoryFormatSupport(VkFormat vkFormat);
bool HasFullFormatSupport(VkPhysicalDevice physicalDevice, VkFormat vkFormat);
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
......
...@@ -133,6 +133,10 @@ TEST_P(ClearTest, RGBA8Framebuffer) ...@@ -133,6 +133,10 @@ TEST_P(ClearTest, RGBA8Framebuffer)
TEST_P(ClearTest, ClearIssue) TEST_P(ClearTest, ClearIssue)
{ {
// Skip this test because of an issue on older Windows AMD Vulkan drivers.
// TODO(jmadill): Re-enable this once Chromium bots are upgraded. http://crbug.com/821522
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAMD() && IsWindows());
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
...@@ -166,7 +170,7 @@ TEST_P(ClearTest, ClearIssue) ...@@ -166,7 +170,7 @@ TEST_P(ClearTest, ClearIssue)
setupDefaultProgram(); setupDefaultProgram();
drawQuad(mProgram, "position", 0.5f); drawQuad(mProgram, "position", 0.5f);
EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
} }
// Requires ES3 // Requires ES3
...@@ -458,7 +462,6 @@ TEST_P(ScissoredClearTest, BasicScissoredColorClear) ...@@ -458,7 +462,6 @@ TEST_P(ScissoredClearTest, BasicScissoredColorClear)
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
// Vulkan support disabled because of incomplete implementation. // Vulkan support disabled because of incomplete implementation.
// TODO(jmadill): Fix depth/stencil support on Vulkan. http://anglebug.com/2357
ANGLE_INSTANTIATE_TEST(ClearTest, ANGLE_INSTANTIATE_TEST(ClearTest,
ES2_D3D9(), ES2_D3D9(),
ES2_D3D11(), ES2_D3D11(),
...@@ -466,8 +469,8 @@ ANGLE_INSTANTIATE_TEST(ClearTest, ...@@ -466,8 +469,8 @@ ANGLE_INSTANTIATE_TEST(ClearTest,
ES2_OPENGL(), ES2_OPENGL(),
ES3_OPENGL(), ES3_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES()/*, ES3_OPENGLES(),
ES2_VULKAN()*/); ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(ClearTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(ClearTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(ScissoredClearTest, ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN()); ANGLE_INSTANTIATE_TEST(ScissoredClearTest, ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment