Commit ae100795 by Nicolas Capens Committed by Nicolas Capens

Assert attachment format supports blending when blending is enabled

The Vulkan spec states that "blendEnable [...] must be VK_FALSE if the attached image’s format features does not contain VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" Previously we would silently ignore blending of integer formats. It was determined to be undefined behavior in https://gitlab.khronos.org/vulkan/vulkan/issues/2098 Bug: b/155147929 Change-Id: I01500d8c39d7f2c9a484944b4a93c6004e938c05 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/45708 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent 32f4be1d
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "Context.hpp" #include "Context.hpp"
#include "Memset.hpp" #include "Memset.hpp"
#include "RoutineCache.hpp" #include "RoutineCache.hpp"
#include "Vulkan/VkFormat.hpp"
#include <memory> #include <memory>
...@@ -84,7 +85,7 @@ public: ...@@ -84,7 +85,7 @@ public:
BlendState blendState[RENDERTARGETS]; BlendState blendState[RENDERTARGETS];
unsigned int colorWriteMask; unsigned int colorWriteMask;
VkFormat targetFormat[RENDERTARGETS]; vk::Format targetFormat[RENDERTARGETS];
unsigned int multiSampleCount; unsigned int multiSampleCount;
unsigned int multiSampleMask; unsigned int multiSampleMask;
bool enableMultiSampling; bool enableMultiSampling;
......
...@@ -1098,7 +1098,7 @@ void PixelRoutine::readPixel(int index, const Pointer<Byte> &cBuffer, const Int ...@@ -1098,7 +1098,7 @@ void PixelRoutine::readPixel(int index, const Pointer<Byte> &cBuffer, const Int
} }
break; break;
default: default:
UNSUPPORTED("VkFormat %d", state.targetFormat[index]); UNSUPPORTED("VkFormat %d", int(state.targetFormat[index]));
} }
if(isSRGB(index)) if(isSRGB(index))
...@@ -1109,11 +1109,13 @@ void PixelRoutine::readPixel(int index, const Pointer<Byte> &cBuffer, const Int ...@@ -1109,11 +1109,13 @@ void PixelRoutine::readPixel(int index, const Pointer<Byte> &cBuffer, const Int
void PixelRoutine::alphaBlend(int index, const Pointer<Byte> &cBuffer, Vector4s &current, const Int &x) void PixelRoutine::alphaBlend(int index, const Pointer<Byte> &cBuffer, Vector4s &current, const Int &x)
{ {
if(!state.blendState[index].alphaBlendEnable || vk::Format(state.targetFormat[index]).isUnnormalizedInteger()) if(!state.blendState[index].alphaBlendEnable)
{ {
return; return;
} }
ASSERT(state.targetFormat[index].supportsColorAttachmentBlend());
Vector4s pixel; Vector4s pixel;
readPixel(index, cBuffer, x, pixel); readPixel(index, cBuffer, x, pixel);
...@@ -1869,11 +1871,14 @@ void PixelRoutine::blendFactorAlpha(Vector4f &blendFactor, const Vector4f &oC, c ...@@ -1869,11 +1871,14 @@ void PixelRoutine::blendFactorAlpha(Vector4f &blendFactor, const Vector4f &oC, c
void PixelRoutine::alphaBlend(int index, const Pointer<Byte> &cBuffer, Vector4f &oC, const Int &x) void PixelRoutine::alphaBlend(int index, const Pointer<Byte> &cBuffer, Vector4f &oC, const Int &x)
{ {
if(!state.blendState[index].alphaBlendEnable || vk::Format(state.targetFormat[index]).isUnnormalizedInteger()) if(!state.blendState[index].alphaBlendEnable)
{ {
return; return;
} }
vk::Format format = state.targetFormat[index];
ASSERT(format.supportsColorAttachmentBlend());
Pointer<Byte> buffer = cBuffer; Pointer<Byte> buffer = cBuffer;
Int pitchB = *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index])); Int pitchB = *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
...@@ -1888,7 +1893,6 @@ void PixelRoutine::alphaBlend(int index, const Pointer<Byte> &cBuffer, Vector4f ...@@ -1888,7 +1893,6 @@ void PixelRoutine::alphaBlend(int index, const Pointer<Byte> &cBuffer, Vector4f
Short4 c23; Short4 c23;
Float4 one; Float4 one;
vk::Format format(state.targetFormat[index]);
if(format.isFloatFormat()) if(format.isFloatFormat())
{ {
one = Float4(1.0f); one = Float4(1.0f);
......
...@@ -2228,6 +2228,37 @@ sw::float4 Format::getScale() const ...@@ -2228,6 +2228,37 @@ sw::float4 Format::getScale() const
return sw::float4(1.0f, 1.0f, 1.0f, 1.0f); return sw::float4(1.0f, 1.0f, 1.0f, 1.0f);
} }
bool Format::supportsColorAttachmentBlend() const
{
switch(format)
{
// Vulkan 1.1 mandatory
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
// Optional
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
return true;
default:
return false;
}
}
bool Format::has16bitPackedTextureFormat() const bool Format::has16bitPackedTextureFormat() const
{ {
if(bytes() != 2) if(bytes() != 2)
......
...@@ -60,6 +60,8 @@ public: ...@@ -60,6 +60,8 @@ public:
sw::float4 getScale() const; sw::float4 getScale() const;
bool supportsColorAttachmentBlend() const;
// Texture sampling utilities // Texture sampling utilities
bool has16bitPackedTextureFormat() const; bool has16bitPackedTextureFormat() const;
bool has8bitTextureComponents() const; bool has8bitTextureComponents() const;
......
...@@ -685,9 +685,6 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor ...@@ -685,9 +685,6 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor
case VK_FORMAT_R32G32_SFLOAT: case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_SFLOAT: case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32: case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
// [[fallthrough]]
case VK_FORMAT_R8_UINT: case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SINT: case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8G8_UINT: case VK_FORMAT_R8G8_UINT:
...@@ -725,6 +722,12 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor ...@@ -725,6 +722,12 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor
break; break;
} }
if(format.supportsColorAttachmentBlend())
{
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
}
switch(format) switch(format)
{ {
case VK_FORMAT_R8_UNORM: case VK_FORMAT_R8_UNORM:
......
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