Support more 10_10_10_2 formats as vertex attributes
Vertex input buffers only support VK_FORMAT_A2B10G10R10_UNORM_PACK32.
This cl adds all the signed and integer variants of that format.
This cl also removes StreamType and replaces it with VkFormat.
Tests: dEQP-VK.*r10*
Bug: b/142661203
Change-Id: I996705395cbb493c599e1a460a6368a7e00d5a55
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40348
Tested-by: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index d94d0ba..a29e3ea 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -1175,12 +1175,13 @@
occlusionQuery = nullptr;
}
+// TODO(b/137740918): Optimize instancing to use a single draw call.
void Renderer::advanceInstanceAttributes(Stream *inputs)
{
for(uint32_t i = 0; i < vk::MAX_VERTEX_INPUT_BINDINGS; i++)
{
auto &attrib = inputs[i];
- if(attrib.count && attrib.instanceStride && (attrib.instanceStride < attrib.robustnessSize))
+ if((attrib.format != VK_FORMAT_UNDEFINED) && attrib.instanceStride && (attrib.instanceStride < attrib.robustnessSize))
{
// Under the casts: attrib.buffer += attrib.instanceStride
attrib.buffer = (void const *)((uintptr_t)attrib.buffer + attrib.instanceStride);
diff --git a/src/Device/Stream.hpp b/src/Device/Stream.hpp
index 8e2fd98..e180bc0 100644
--- a/src/Device/Stream.hpp
+++ b/src/Device/Stream.hpp
@@ -15,36 +15,17 @@
#ifndef sw_Stream_hpp
#define sw_Stream_hpp
-#include "System/Types.hpp"
+#include <Vulkan/VulkanPlatform.h>
namespace sw {
-enum StreamType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
-{
- STREAMTYPE_COLOR, // 4 normalized unsigned bytes, ZYXW order
- STREAMTYPE_FLOAT, // Normalization ignored
- STREAMTYPE_BYTE,
- STREAMTYPE_SBYTE,
- STREAMTYPE_SHORT,
- STREAMTYPE_USHORT,
- STREAMTYPE_INT,
- STREAMTYPE_UINT,
- STREAMTYPE_HALF, // Normalization ignored
- STREAMTYPE_2_10_10_10_INT,
- STREAMTYPE_2_10_10_10_UINT,
-
- STREAMTYPE_LAST = STREAMTYPE_2_10_10_10_UINT
-};
-
struct Stream
{
const void *buffer = nullptr;
unsigned int robustnessSize = 0;
unsigned int vertexStride = 0;
unsigned int instanceStride = 0;
- StreamType type = STREAMTYPE_FLOAT;
- unsigned char count = 0;
- bool normalized = false;
+ VkFormat format = VK_FORMAT_UNDEFINED;
unsigned int offset = 0;
unsigned int binding = 0;
};
diff --git a/src/Device/VertexProcessor.cpp b/src/Device/VertexProcessor.cpp
index 3f72121..88359a2 100644
--- a/src/Device/VertexProcessor.cpp
+++ b/src/Device/VertexProcessor.cpp
@@ -44,32 +44,6 @@
return hash;
}
-unsigned int VertexProcessor::States::Input::bytesPerAttrib() const
-{
- switch(type)
- {
- case STREAMTYPE_FLOAT:
- case STREAMTYPE_INT:
- case STREAMTYPE_UINT:
- return count * sizeof(uint32_t);
- case STREAMTYPE_HALF:
- case STREAMTYPE_SHORT:
- case STREAMTYPE_USHORT:
- return count * sizeof(uint16_t);
- case STREAMTYPE_BYTE:
- case STREAMTYPE_SBYTE:
- return count * sizeof(uint8_t);
- case STREAMTYPE_COLOR:
- case STREAMTYPE_2_10_10_10_INT:
- case STREAMTYPE_2_10_10_10_UINT:
- return sizeof(int);
- default:
- UNSUPPORTED("stream.type %d", int(type));
- }
-
- return 0;
-}
-
bool VertexProcessor::State::operator==(const State &state) const
{
if(hash != state.hash)
@@ -109,9 +83,7 @@
for(int i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++)
{
- state.input[i].type = context->input[i].type;
- state.input[i].count = context->input[i].count;
- state.input[i].normalized = context->input[i].normalized;
+ state.input[i].format = context->input[i].format;
// TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines
// how to handle the attribute.
state.input[i].attribType = context->vertexShader->inputs[i * 4].Type;
diff --git a/src/Device/VertexProcessor.hpp b/src/Device/VertexProcessor.hpp
index 77117d9..1c5b28c 100644
--- a/src/Device/VertexProcessor.hpp
+++ b/src/Device/VertexProcessor.hpp
@@ -68,14 +68,10 @@
{
operator bool() const // Returns true if stream contains data
{
- return count != 0;
+ return format != VK_FORMAT_UNDEFINED;
}
- unsigned int bytesPerAttrib() const;
-
- StreamType type : BITS(STREAMTYPE_LAST);
- unsigned int count : 3;
- bool normalized : 1;
+ VkFormat format; // TODO(b/148016460): Could be restricted to VK_FORMAT_END_RANGE
unsigned int attribType : BITS(SpirvShader::ATTRIBTYPE_LAST);
};
diff --git a/src/Pipeline/VertexRoutine.cpp b/src/Pipeline/VertexRoutine.cpp
index 517ac70..99cdbe3 100644
--- a/src/Pipeline/VertexRoutine.cpp
+++ b/src/Pipeline/VertexRoutine.cpp
@@ -177,11 +177,13 @@
Pointer<Byte> source2 = buffer + offsets.z;
Pointer<Byte> source3 = buffer + offsets.w;
+ vk::Format format(stream.format);
+
UInt4 zero(0);
if(robustBufferAccess)
{
// TODO(b/141124876): Optimize for wide-vector gather operations.
- UInt4 limits = offsets + UInt4(stream.bytesPerAttrib());
+ UInt4 limits = offsets + UInt4(format.bytes());
Pointer<Byte> zeroSource = As<Pointer<Byte>>(&zero);
source0 = IfThenElse(limits.x <= robustnessSize, source0, zeroSource);
source1 = IfThenElse(limits.y <= robustnessSize, source1, zeroSource);
@@ -189,19 +191,25 @@
source3 = IfThenElse(limits.w <= robustnessSize, source3, zeroSource);
}
- bool isNativeFloatAttrib = (stream.attribType == SpirvShader::ATTRIBTYPE_FLOAT) || stream.normalized;
+ int componentCount = format.componentCount();
+ bool normalized = !format.isUnnormalizedInteger();
+ bool isNativeFloatAttrib = (stream.attribType == SpirvShader::ATTRIBTYPE_FLOAT) || normalized;
+ bool bgra = false;
- switch(stream.type)
+ switch(stream.format)
{
- case STREAMTYPE_FLOAT:
+ case VK_FORMAT_R32_SFLOAT:
+ case VK_FORMAT_R32G32_SFLOAT:
+ case VK_FORMAT_R32G32B32_SFLOAT:
+ case VK_FORMAT_R32G32B32A32_SFLOAT:
{
- if(stream.count == 0)
+ if(componentCount == 0)
{
// Null stream, all default components
}
else
{
- if(stream.count == 1)
+ if(componentCount == 1)
{
v.x.x = *Pointer<Float>(source0);
v.x.y = *Pointer<Float>(source1);
@@ -215,22 +223,22 @@
v.z = *Pointer<Float4>(source2);
v.w = *Pointer<Float4>(source3);
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
switch(stream.attribType)
{
case SpirvShader::ATTRIBTYPE_INT:
- if(stream.count >= 1) v.x = As<Float4>(Int4(v.x));
- if(stream.count >= 2) v.x = As<Float4>(Int4(v.y));
- if(stream.count >= 3) v.x = As<Float4>(Int4(v.z));
- if(stream.count >= 4) v.x = As<Float4>(Int4(v.w));
+ if(componentCount >= 1) v.x = As<Float4>(Int4(v.x));
+ if(componentCount >= 2) v.x = As<Float4>(Int4(v.y));
+ if(componentCount >= 3) v.x = As<Float4>(Int4(v.z));
+ if(componentCount >= 4) v.x = As<Float4>(Int4(v.w));
break;
case SpirvShader::ATTRIBTYPE_UINT:
- if(stream.count >= 1) v.x = As<Float4>(UInt4(v.x));
- if(stream.count >= 2) v.x = As<Float4>(UInt4(v.y));
- if(stream.count >= 3) v.x = As<Float4>(UInt4(v.z));
- if(stream.count >= 4) v.x = As<Float4>(UInt4(v.w));
+ if(componentCount >= 1) v.x = As<Float4>(UInt4(v.x));
+ if(componentCount >= 2) v.x = As<Float4>(UInt4(v.y));
+ if(componentCount >= 3) v.x = As<Float4>(UInt4(v.z));
+ if(componentCount >= 4) v.x = As<Float4>(UInt4(v.w));
break;
default:
break;
@@ -238,7 +246,16 @@
}
}
break;
- case STREAMTYPE_BYTE:
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ bgra = true;
+ case VK_FORMAT_R8_UNORM:
+ case VK_FORMAT_R8G8_UNORM:
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ case VK_FORMAT_R8_UINT:
+ case VK_FORMAT_R8G8_UINT:
+ case VK_FORMAT_R8G8B8A8_UINT:
+ case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
+ case VK_FORMAT_A8B8G8R8_UINT_PACK32:
if(isNativeFloatAttrib) // Stream: UByte, Shader attrib: Float
{
v.x = Float4(*Pointer<Byte4>(source0));
@@ -246,14 +263,14 @@
v.z = Float4(*Pointer<Byte4>(source2));
v.w = Float4(*Pointer<Byte4>(source3));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
- if(stream.normalized)
+ if(normalized)
{
- if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
- if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
- if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
- if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
+ if(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
+ if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
+ if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
+ if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
}
}
else // Stream: UByte, Shader attrib: Int / UInt
@@ -263,10 +280,17 @@
v.z = As<Float4>(Int4(*Pointer<Byte4>(source2)));
v.w = As<Float4>(Int4(*Pointer<Byte4>(source3)));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
break;
- case STREAMTYPE_SBYTE:
+ case VK_FORMAT_R8_SNORM:
+ case VK_FORMAT_R8_SINT:
+ case VK_FORMAT_R8G8_SNORM:
+ case VK_FORMAT_R8G8_SINT:
+ case VK_FORMAT_R8G8B8A8_SNORM:
+ case VK_FORMAT_R8G8B8A8_SINT:
+ case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
+ case VK_FORMAT_A8B8G8R8_SINT_PACK32:
if(isNativeFloatAttrib) // Stream: SByte, Shader attrib: Float
{
v.x = Float4(*Pointer<SByte4>(source0));
@@ -274,14 +298,14 @@
v.z = Float4(*Pointer<SByte4>(source2));
v.w = Float4(*Pointer<SByte4>(source3));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
- if(stream.normalized)
+ if(normalized)
{
- if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
- if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
- if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
- if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
+ if(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
+ if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
+ if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
+ if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
}
}
else // Stream: SByte, Shader attrib: Int / UInt
@@ -291,25 +315,15 @@
v.z = As<Float4>(Int4(*Pointer<SByte4>(source2)));
v.w = As<Float4>(Int4(*Pointer<SByte4>(source3)));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
break;
- case STREAMTYPE_COLOR:
- {
- v.x = Float4(*Pointer<Byte4>(source0)) * *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
- v.y = Float4(*Pointer<Byte4>(source1)) * *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
- v.z = Float4(*Pointer<Byte4>(source2)) * *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
- v.w = Float4(*Pointer<Byte4>(source3)) * *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
-
- transpose4x4(v.x, v.y, v.z, v.w);
-
- // Swap red and blue
- Float4 t = v.x;
- v.x = v.z;
- v.z = t;
- }
- break;
- case STREAMTYPE_SHORT:
+ case VK_FORMAT_R16_SNORM:
+ case VK_FORMAT_R16_SINT:
+ case VK_FORMAT_R16G16_SNORM:
+ case VK_FORMAT_R16G16_SINT:
+ case VK_FORMAT_R16G16B16A16_SNORM:
+ case VK_FORMAT_R16G16B16A16_SINT:
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
v.x = Float4(*Pointer<Short4>(source0));
@@ -317,14 +331,14 @@
v.z = Float4(*Pointer<Short4>(source2));
v.w = Float4(*Pointer<Short4>(source3));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
- if(stream.normalized)
+ if(normalized)
{
- if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
- if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
- if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
- if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
+ if(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
+ if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
+ if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
+ if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
}
}
else // Stream: Short, Shader attrib: Int/UInt, no type conversion
@@ -334,10 +348,15 @@
v.z = As<Float4>(Int4(*Pointer<Short4>(source2)));
v.w = As<Float4>(Int4(*Pointer<Short4>(source3)));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
break;
- case STREAMTYPE_USHORT:
+ case VK_FORMAT_R16_UNORM:
+ case VK_FORMAT_R16_UINT:
+ case VK_FORMAT_R16G16_UNORM:
+ case VK_FORMAT_R16G16_UINT:
+ case VK_FORMAT_R16G16B16A16_UNORM:
+ case VK_FORMAT_R16G16B16A16_UINT:
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
v.x = Float4(*Pointer<UShort4>(source0));
@@ -345,14 +364,14 @@
v.z = Float4(*Pointer<UShort4>(source2));
v.w = Float4(*Pointer<UShort4>(source3));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
- if(stream.normalized)
+ if(normalized)
{
- if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
- if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
- if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
- if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
+ if(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
+ if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
+ if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
+ if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
}
}
else // Stream: UShort, Shader attrib: Int/UInt, no type conversion
@@ -362,10 +381,13 @@
v.z = As<Float4>(Int4(*Pointer<UShort4>(source2)));
v.w = As<Float4>(Int4(*Pointer<UShort4>(source3)));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
break;
- case STREAMTYPE_INT:
+ case VK_FORMAT_R32_SINT:
+ case VK_FORMAT_R32G32_SINT:
+ case VK_FORMAT_R32G32B32_SINT:
+ case VK_FORMAT_R32G32B32A32_SINT:
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
v.x = Float4(*Pointer<Int4>(source0));
@@ -373,14 +395,14 @@
v.z = Float4(*Pointer<Int4>(source2));
v.w = Float4(*Pointer<Int4>(source3));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
- if(stream.normalized)
+ if(normalized)
{
- if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
- if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
- if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
- if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+ if(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+ if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+ if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
+ if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
}
}
else // Stream: Int, Shader attrib: Int/UInt, no type conversion
@@ -390,10 +412,13 @@
v.z = *Pointer<Float4>(source2);
v.w = *Pointer<Float4>(source3);
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
break;
- case STREAMTYPE_UINT:
+ case VK_FORMAT_R32_UINT:
+ case VK_FORMAT_R32G32_UINT:
+ case VK_FORMAT_R32G32B32_UINT:
+ case VK_FORMAT_R32G32B32A32_UINT:
if(isNativeFloatAttrib) // Stream: UInt, Shader attrib: Float
{
v.x = Float4(*Pointer<UInt4>(source0));
@@ -401,14 +426,14 @@
v.z = Float4(*Pointer<UInt4>(source2));
v.w = Float4(*Pointer<UInt4>(source3));
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
- if(stream.normalized)
+ if(normalized)
{
- if(stream.count >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
- if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
- if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
- if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+ if(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+ if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+ if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
+ if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
}
}
else // Stream: UInt, Shader attrib: Int/UInt, no type conversion
@@ -418,12 +443,14 @@
v.z = *Pointer<Float4>(source2);
v.w = *Pointer<Float4>(source3);
- transpose4xN(v.x, v.y, v.z, v.w, stream.count);
+ transpose4xN(v.x, v.y, v.z, v.w, componentCount);
}
break;
- case STREAMTYPE_HALF:
+ case VK_FORMAT_R16_SFLOAT:
+ case VK_FORMAT_R16G16_SFLOAT:
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
{
- if(stream.count >= 1)
+ if(componentCount >= 1)
{
UShort x0 = *Pointer<UShort>(source0 + 0);
UShort x1 = *Pointer<UShort>(source1 + 0);
@@ -436,7 +463,7 @@
v.x.w = *Pointer<Float>(constants + OFFSET(Constants, half2float) + Int(x3) * 4);
}
- if(stream.count >= 2)
+ if(componentCount >= 2)
{
UShort y0 = *Pointer<UShort>(source0 + 2);
UShort y1 = *Pointer<UShort>(source1 + 2);
@@ -449,7 +476,7 @@
v.y.w = *Pointer<Float>(constants + OFFSET(Constants, half2float) + Int(y3) * 4);
}
- if(stream.count >= 3)
+ if(componentCount >= 3)
{
UShort z0 = *Pointer<UShort>(source0 + 4);
UShort z1 = *Pointer<UShort>(source1 + 4);
@@ -462,7 +489,7 @@
v.z.w = *Pointer<Float>(constants + OFFSET(Constants, half2float) + Int(z3) * 4);
}
- if(stream.count >= 4)
+ if(componentCount >= 4)
{
UShort w0 = *Pointer<UShort>(source0 + 6);
UShort w1 = *Pointer<UShort>(source1 + 6);
@@ -476,29 +503,46 @@
}
}
break;
- case STREAMTYPE_2_10_10_10_INT:
+ case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
+ case VK_FORMAT_A2R10G10B10_SINT_PACK32:
+ bgra = true;
+ case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
+ case VK_FORMAT_A2B10G10R10_SINT_PACK32:
{
Int4 src;
src = Insert(src, *Pointer<Int>(source0), 0);
src = Insert(src, *Pointer<Int>(source1), 1);
src = Insert(src, *Pointer<Int>(source2), 2);
src = Insert(src, *Pointer<Int>(source3), 3);
-
- v.x = Float4((src << 22) >> 22);
- v.y = Float4((src << 12) >> 22);
- v.z = Float4((src << 02) >> 22);
- v.w = Float4(src >> 30);
-
- if(stream.normalized)
+ if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
- v.x = Max(v.x * Float4(1.0f / 0x1FF), Float4(-1.0f));
- v.y = Max(v.y * Float4(1.0f / 0x1FF), Float4(-1.0f));
- v.z = Max(v.z * Float4(1.0f / 0x1FF), Float4(-1.0f));
- v.w = Max(v.w, Float4(-1.0f));
+ v.x = Float4((src << 22) >> 22);
+ v.y = Float4((src << 12) >> 22);
+ v.z = Float4((src << 02) >> 22);
+ v.w = Float4(src >> 30);
+
+ if(normalized)
+ {
+ v.x = Max(v.x * Float4(1.0f / 0x1FF), Float4(-1.0f));
+ v.y = Max(v.y * Float4(1.0f / 0x1FF), Float4(-1.0f));
+ v.z = Max(v.z * Float4(1.0f / 0x1FF), Float4(-1.0f));
+ v.w = Max(v.w, Float4(-1.0f));
+ }
+ }
+ else // Stream: UInt, Shader attrib: Int/UInt, no type conversion
+ {
+ v.x = As<Float4>((src << 22) >> 22);
+ v.y = As<Float4>((src << 12) >> 22);
+ v.z = As<Float4>((src << 02) >> 22);
+ v.w = As<Float4>(src >> 30);
}
}
break;
- case STREAMTYPE_2_10_10_10_UINT:
+ case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+ case VK_FORMAT_A2R10G10B10_UINT_PACK32:
+ bgra = true;
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+ case VK_FORMAT_A2B10G10R10_UINT_PACK32:
{
Int4 src;
src = Insert(src, *Pointer<Int>(source0), 0);
@@ -506,28 +550,46 @@
src = Insert(src, *Pointer<Int>(source2), 2);
src = Insert(src, *Pointer<Int>(source3), 3);
- v.x = Float4(src & Int4(0x3FF));
- v.y = Float4((src >> 10) & Int4(0x3FF));
- v.z = Float4((src >> 20) & Int4(0x3FF));
- v.w = Float4((src >> 30) & Int4(0x3));
-
- if(stream.normalized)
+ if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
- v.x *= Float4(1.0f / 0x3FF);
- v.y *= Float4(1.0f / 0x3FF);
- v.z *= Float4(1.0f / 0x3FF);
- v.w *= Float4(1.0f / 0x3);
+ v.x = Float4(src & Int4(0x3FF));
+ v.y = Float4((src >> 10) & Int4(0x3FF));
+ v.z = Float4((src >> 20) & Int4(0x3FF));
+ v.w = Float4((src >> 30) & Int4(0x3));
+
+ if(normalized)
+ {
+ v.x *= Float4(1.0f / 0x3FF);
+ v.y *= Float4(1.0f / 0x3FF);
+ v.z *= Float4(1.0f / 0x3FF);
+ v.w *= Float4(1.0f / 0x3);
+ }
+ }
+ else // Stream: UInt, Shader attrib: Int/UInt, no type conversion
+ {
+ v.x = As<Float4>(src & Int4(0x3FF));
+ v.y = As<Float4>((src >> 10) & Int4(0x3FF));
+ v.z = As<Float4>((src >> 20) & Int4(0x3FF));
+ v.w = As<Float4>((src >> 30) & Int4(0x3));
}
}
break;
default:
- UNSUPPORTED("stream.type %d", int(stream.type));
+ UNSUPPORTED("stream.format %d", int(stream.format));
}
- if(stream.count < 1) v.x = Float4(0.0f);
- if(stream.count < 2) v.y = Float4(0.0f);
- if(stream.count < 3) v.z = Float4(0.0f);
- if(stream.count < 4) v.w = isNativeFloatAttrib ? As<Float4>(Float4(1.0f)) : As<Float4>(Int4(1));
+ if(bgra)
+ {
+ // Swap red and blue
+ Float4 t = v.x;
+ v.x = v.z;
+ v.z = t;
+ }
+
+ if(componentCount < 1) v.x = Float4(0.0f);
+ if(componentCount < 2) v.y = Float4(0.0f);
+ if(componentCount < 3) v.z = Float4(0.0f);
+ if(componentCount < 4) v.w = isNativeFloatAttrib ? As<Float4>(Float4(1.0f)) : As<Float4>(Int4(1));
return v;
}
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index e4b02c8..9f38549 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -1811,7 +1811,7 @@
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
{
auto &attrib = context.input[i];
- if(attrib.count)
+ if(attrib.format != VK_FORMAT_UNDEFINED)
{
const auto &vertexInput = vertexInputBindings[attrib.binding];
VkDeviceSize offset = attrib.offset + vertexInput.offset +
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 875f0c1..364c26d 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -689,7 +689,14 @@
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
+ case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+ case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
+ case VK_FORMAT_A2R10G10B10_UINT_PACK32:
+ case VK_FORMAT_A2R10G10B10_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+ case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
+ case VK_FORMAT_A2B10G10R10_UINT_PACK32:
+ case VK_FORMAT_A2B10G10R10_SINT_PACK32:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_UINT:
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 6134ae4..a009c5e 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -31,132 +31,6 @@
namespace {
-sw::StreamType getStreamType(VkFormat format)
-{
- switch(format)
- {
- case VK_FORMAT_R8_UNORM:
- case VK_FORMAT_R8G8_UNORM:
- case VK_FORMAT_R8G8B8A8_UNORM:
- case VK_FORMAT_R8_UINT:
- case VK_FORMAT_R8G8_UINT:
- case VK_FORMAT_R8G8B8A8_UINT:
- case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
- case VK_FORMAT_A8B8G8R8_UINT_PACK32:
- return sw::STREAMTYPE_BYTE;
- case VK_FORMAT_B8G8R8A8_UNORM:
- return sw::STREAMTYPE_COLOR;
- case VK_FORMAT_R8_SNORM:
- case VK_FORMAT_R8_SINT:
- case VK_FORMAT_R8G8_SNORM:
- case VK_FORMAT_R8G8_SINT:
- case VK_FORMAT_R8G8B8A8_SNORM:
- case VK_FORMAT_R8G8B8A8_SINT:
- case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
- case VK_FORMAT_A8B8G8R8_SINT_PACK32:
- return sw::STREAMTYPE_SBYTE;
- case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
- return sw::STREAMTYPE_2_10_10_10_UINT;
- case VK_FORMAT_R16_UNORM:
- case VK_FORMAT_R16_UINT:
- case VK_FORMAT_R16G16_UNORM:
- case VK_FORMAT_R16G16_UINT:
- case VK_FORMAT_R16G16B16A16_UNORM:
- case VK_FORMAT_R16G16B16A16_UINT:
- return sw::STREAMTYPE_USHORT;
- case VK_FORMAT_R16_SNORM:
- case VK_FORMAT_R16_SINT:
- case VK_FORMAT_R16G16_SNORM:
- case VK_FORMAT_R16G16_SINT:
- case VK_FORMAT_R16G16B16A16_SNORM:
- case VK_FORMAT_R16G16B16A16_SINT:
- return sw::STREAMTYPE_SHORT;
- case VK_FORMAT_R16_SFLOAT:
- case VK_FORMAT_R16G16_SFLOAT:
- case VK_FORMAT_R16G16B16A16_SFLOAT:
- return sw::STREAMTYPE_HALF;
- case VK_FORMAT_R32_UINT:
- case VK_FORMAT_R32G32_UINT:
- case VK_FORMAT_R32G32B32_UINT:
- case VK_FORMAT_R32G32B32A32_UINT:
- return sw::STREAMTYPE_UINT;
- case VK_FORMAT_R32_SINT:
- case VK_FORMAT_R32G32_SINT:
- case VK_FORMAT_R32G32B32_SINT:
- case VK_FORMAT_R32G32B32A32_SINT:
- return sw::STREAMTYPE_INT;
- case VK_FORMAT_R32_SFLOAT:
- case VK_FORMAT_R32G32_SFLOAT:
- case VK_FORMAT_R32G32B32_SFLOAT:
- case VK_FORMAT_R32G32B32A32_SFLOAT:
- return sw::STREAMTYPE_FLOAT;
- default:
- UNIMPLEMENTED("format");
- }
-
- return sw::STREAMTYPE_BYTE;
-}
-
-unsigned char getNumberOfChannels(VkFormat format)
-{
- switch(format)
- {
- case VK_FORMAT_R8_UNORM:
- case VK_FORMAT_R8_SNORM:
- case VK_FORMAT_R8_UINT:
- case VK_FORMAT_R8_SINT:
- case VK_FORMAT_R16_UNORM:
- case VK_FORMAT_R16_SNORM:
- case VK_FORMAT_R16_UINT:
- case VK_FORMAT_R16_SINT:
- case VK_FORMAT_R16_SFLOAT:
- case VK_FORMAT_R32_UINT:
- case VK_FORMAT_R32_SINT:
- case VK_FORMAT_R32_SFLOAT:
- return 1;
- case VK_FORMAT_R8G8_UNORM:
- case VK_FORMAT_R8G8_SNORM:
- case VK_FORMAT_R8G8_UINT:
- case VK_FORMAT_R8G8_SINT:
- case VK_FORMAT_R16G16_UNORM:
- case VK_FORMAT_R16G16_SNORM:
- case VK_FORMAT_R16G16_UINT:
- case VK_FORMAT_R16G16_SINT:
- case VK_FORMAT_R16G16_SFLOAT:
- case VK_FORMAT_R32G32_UINT:
- case VK_FORMAT_R32G32_SINT:
- case VK_FORMAT_R32G32_SFLOAT:
- return 2;
- case VK_FORMAT_R32G32B32_UINT:
- case VK_FORMAT_R32G32B32_SINT:
- case VK_FORMAT_R32G32B32_SFLOAT:
- return 3;
- case VK_FORMAT_R8G8B8A8_UNORM:
- case VK_FORMAT_R8G8B8A8_SNORM:
- case VK_FORMAT_R8G8B8A8_UINT:
- case VK_FORMAT_R8G8B8A8_SINT:
- case VK_FORMAT_B8G8R8A8_UNORM:
- case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
- case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
- case VK_FORMAT_A8B8G8R8_UINT_PACK32:
- case VK_FORMAT_A8B8G8R8_SINT_PACK32:
- case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
- case VK_FORMAT_R16G16B16A16_UNORM:
- case VK_FORMAT_R16G16B16A16_SNORM:
- case VK_FORMAT_R16G16B16A16_UINT:
- case VK_FORMAT_R16G16B16A16_SINT:
- case VK_FORMAT_R16G16B16A16_SFLOAT:
- case VK_FORMAT_R32G32B32A32_UINT:
- case VK_FORMAT_R32G32B32A32_SINT:
- case VK_FORMAT_R32G32B32A32_SFLOAT:
- return 4;
- default:
- UNIMPLEMENTED("format");
- }
-
- return 0;
-}
-
// preprocessSpirv applies and freezes specializations into constants, and inlines all functions.
std::vector<uint32_t> preprocessSpirv(
std::vector<uint32_t> const &code,
@@ -333,9 +207,7 @@
{
auto const &desc = vertexInputState->pVertexAttributeDescriptions[i];
sw::Stream &input = context.input[desc.location];
- input.count = getNumberOfChannels(desc.format);
- input.type = getStreamType(desc.format);
- input.normalized = !vk::Format(desc.format).isUnnormalizedInteger();
+ input.format = desc.format;
input.offset = desc.offset;
input.binding = desc.binding;
input.vertexStride = vertexStrides[desc.binding];