Commit b766e5e7 by Alexis Hetu Committed by Alexis Hétu

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/+/40348Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 11cb891a
...@@ -1175,12 +1175,13 @@ void Renderer::removeQuery(vk::Query *query) ...@@ -1175,12 +1175,13 @@ void Renderer::removeQuery(vk::Query *query)
occlusionQuery = nullptr; occlusionQuery = nullptr;
} }
// TODO(b/137740918): Optimize instancing to use a single draw call.
void Renderer::advanceInstanceAttributes(Stream *inputs) void Renderer::advanceInstanceAttributes(Stream *inputs)
{ {
for(uint32_t i = 0; i < vk::MAX_VERTEX_INPUT_BINDINGS; i++) for(uint32_t i = 0; i < vk::MAX_VERTEX_INPUT_BINDINGS; i++)
{ {
auto &attrib = inputs[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 // Under the casts: attrib.buffer += attrib.instanceStride
attrib.buffer = (void const *)((uintptr_t)attrib.buffer + attrib.instanceStride); attrib.buffer = (void const *)((uintptr_t)attrib.buffer + attrib.instanceStride);
......
...@@ -15,36 +15,17 @@ ...@@ -15,36 +15,17 @@
#ifndef sw_Stream_hpp #ifndef sw_Stream_hpp
#define sw_Stream_hpp #define sw_Stream_hpp
#include "System/Types.hpp" #include <Vulkan/VulkanPlatform.h>
namespace sw { 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 struct Stream
{ {
const void *buffer = nullptr; const void *buffer = nullptr;
unsigned int robustnessSize = 0; unsigned int robustnessSize = 0;
unsigned int vertexStride = 0; unsigned int vertexStride = 0;
unsigned int instanceStride = 0; unsigned int instanceStride = 0;
StreamType type = STREAMTYPE_FLOAT; VkFormat format = VK_FORMAT_UNDEFINED;
unsigned char count = 0;
bool normalized = false;
unsigned int offset = 0; unsigned int offset = 0;
unsigned int binding = 0; unsigned int binding = 0;
}; };
......
...@@ -44,32 +44,6 @@ uint32_t VertexProcessor::States::computeHash() ...@@ -44,32 +44,6 @@ uint32_t VertexProcessor::States::computeHash()
return hash; 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 bool VertexProcessor::State::operator==(const State &state) const
{ {
if(hash != state.hash) if(hash != state.hash)
...@@ -109,9 +83,7 @@ const VertexProcessor::State VertexProcessor::update(const sw::Context *context) ...@@ -109,9 +83,7 @@ const VertexProcessor::State VertexProcessor::update(const sw::Context *context)
for(int i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++) for(int i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++)
{ {
state.input[i].type = context->input[i].type; state.input[i].format = context->input[i].format;
state.input[i].count = context->input[i].count;
state.input[i].normalized = context->input[i].normalized;
// TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines // TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines
// how to handle the attribute. // how to handle the attribute.
state.input[i].attribType = context->vertexShader->inputs[i * 4].Type; state.input[i].attribType = context->vertexShader->inputs[i * 4].Type;
......
...@@ -68,14 +68,10 @@ public: ...@@ -68,14 +68,10 @@ public:
{ {
operator bool() const // Returns true if stream contains data operator bool() const // Returns true if stream contains data
{ {
return count != 0; return format != VK_FORMAT_UNDEFINED;
} }
unsigned int bytesPerAttrib() const; VkFormat format; // TODO(b/148016460): Could be restricted to VK_FORMAT_END_RANGE
StreamType type : BITS(STREAMTYPE_LAST);
unsigned int count : 3;
bool normalized : 1;
unsigned int attribType : BITS(SpirvShader::ATTRIBTYPE_LAST); unsigned int attribType : BITS(SpirvShader::ATTRIBTYPE_LAST);
}; };
......
...@@ -177,11 +177,13 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -177,11 +177,13 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
Pointer<Byte> source2 = buffer + offsets.z; Pointer<Byte> source2 = buffer + offsets.z;
Pointer<Byte> source3 = buffer + offsets.w; Pointer<Byte> source3 = buffer + offsets.w;
vk::Format format(stream.format);
UInt4 zero(0); UInt4 zero(0);
if(robustBufferAccess) if(robustBufferAccess)
{ {
// TODO(b/141124876): Optimize for wide-vector gather operations. // 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); Pointer<Byte> zeroSource = As<Pointer<Byte>>(&zero);
source0 = IfThenElse(limits.x <= robustnessSize, source0, zeroSource); source0 = IfThenElse(limits.x <= robustnessSize, source0, zeroSource);
source1 = IfThenElse(limits.y <= robustnessSize, source1, zeroSource); source1 = IfThenElse(limits.y <= robustnessSize, source1, zeroSource);
...@@ -189,19 +191,25 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -189,19 +191,25 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
source3 = IfThenElse(limits.w <= robustnessSize, source3, zeroSource); 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 // Null stream, all default components
} }
else else
{ {
if(stream.count == 1) if(componentCount == 1)
{ {
v.x.x = *Pointer<Float>(source0); v.x.x = *Pointer<Float>(source0);
v.x.y = *Pointer<Float>(source1); v.x.y = *Pointer<Float>(source1);
...@@ -215,22 +223,22 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -215,22 +223,22 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = *Pointer<Float4>(source2); v.z = *Pointer<Float4>(source2);
v.w = *Pointer<Float4>(source3); 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) switch(stream.attribType)
{ {
case SpirvShader::ATTRIBTYPE_INT: case SpirvShader::ATTRIBTYPE_INT:
if(stream.count >= 1) v.x = As<Float4>(Int4(v.x)); if(componentCount >= 1) v.x = As<Float4>(Int4(v.x));
if(stream.count >= 2) v.x = As<Float4>(Int4(v.y)); if(componentCount >= 2) v.x = As<Float4>(Int4(v.y));
if(stream.count >= 3) v.x = As<Float4>(Int4(v.z)); if(componentCount >= 3) v.x = As<Float4>(Int4(v.z));
if(stream.count >= 4) v.x = As<Float4>(Int4(v.w)); if(componentCount >= 4) v.x = As<Float4>(Int4(v.w));
break; break;
case SpirvShader::ATTRIBTYPE_UINT: case SpirvShader::ATTRIBTYPE_UINT:
if(stream.count >= 1) v.x = As<Float4>(UInt4(v.x)); if(componentCount >= 1) v.x = As<Float4>(UInt4(v.x));
if(stream.count >= 2) v.x = As<Float4>(UInt4(v.y)); if(componentCount >= 2) v.x = As<Float4>(UInt4(v.y));
if(stream.count >= 3) v.x = As<Float4>(UInt4(v.z)); if(componentCount >= 3) v.x = As<Float4>(UInt4(v.z));
if(stream.count >= 4) v.x = As<Float4>(UInt4(v.w)); if(componentCount >= 4) v.x = As<Float4>(UInt4(v.w));
break; break;
default: default:
break; break;
...@@ -238,7 +246,16 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -238,7 +246,16 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
} }
} }
break; 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 if(isNativeFloatAttrib) // Stream: UByte, Shader attrib: Float
{ {
v.x = Float4(*Pointer<Byte4>(source0)); v.x = Float4(*Pointer<Byte4>(source0));
...@@ -246,14 +263,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -246,14 +263,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = Float4(*Pointer<Byte4>(source2)); v.z = Float4(*Pointer<Byte4>(source2));
v.w = Float4(*Pointer<Byte4>(source3)); 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(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte)); if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte)); if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte)); if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleByte));
} }
} }
else // Stream: UByte, Shader attrib: Int / UInt else // Stream: UByte, Shader attrib: Int / UInt
...@@ -263,10 +280,17 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -263,10 +280,17 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = As<Float4>(Int4(*Pointer<Byte4>(source2))); v.z = As<Float4>(Int4(*Pointer<Byte4>(source2)));
v.w = As<Float4>(Int4(*Pointer<Byte4>(source3))); 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; 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 if(isNativeFloatAttrib) // Stream: SByte, Shader attrib: Float
{ {
v.x = Float4(*Pointer<SByte4>(source0)); v.x = Float4(*Pointer<SByte4>(source0));
...@@ -274,14 +298,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -274,14 +298,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = Float4(*Pointer<SByte4>(source2)); v.z = Float4(*Pointer<SByte4>(source2));
v.w = Float4(*Pointer<SByte4>(source3)); 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(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte)); if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte)); if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
if(stream.count >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte)); if(componentCount >= 4) v.w *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleSByte));
} }
} }
else // Stream: SByte, Shader attrib: Int / UInt else // Stream: SByte, Shader attrib: Int / UInt
...@@ -291,25 +315,15 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -291,25 +315,15 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = As<Float4>(Int4(*Pointer<SByte4>(source2))); v.z = As<Float4>(Int4(*Pointer<SByte4>(source2)));
v.w = As<Float4>(Int4(*Pointer<SByte4>(source3))); 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; 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 if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{ {
v.x = Float4(*Pointer<Short4>(source0)); v.x = Float4(*Pointer<Short4>(source0));
...@@ -317,14 +331,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -317,14 +331,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = Float4(*Pointer<Short4>(source2)); v.z = Float4(*Pointer<Short4>(source2));
v.w = Float4(*Pointer<Short4>(source3)); 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(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort)); if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort)); if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleShort));
if(stream.count >= 4) v.w *= *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 else // Stream: Short, Shader attrib: Int/UInt, no type conversion
...@@ -334,10 +348,15 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -334,10 +348,15 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = As<Float4>(Int4(*Pointer<Short4>(source2))); v.z = As<Float4>(Int4(*Pointer<Short4>(source2)));
v.w = As<Float4>(Int4(*Pointer<Short4>(source3))); 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; 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 if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{ {
v.x = Float4(*Pointer<UShort4>(source0)); v.x = Float4(*Pointer<UShort4>(source0));
...@@ -345,14 +364,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -345,14 +364,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = Float4(*Pointer<UShort4>(source2)); v.z = Float4(*Pointer<UShort4>(source2));
v.w = Float4(*Pointer<UShort4>(source3)); 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(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort)); if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort)); if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUShort));
if(stream.count >= 4) v.w *= *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 else // Stream: UShort, Shader attrib: Int/UInt, no type conversion
...@@ -362,10 +381,13 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -362,10 +381,13 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = As<Float4>(Int4(*Pointer<UShort4>(source2))); v.z = As<Float4>(Int4(*Pointer<UShort4>(source2)));
v.w = As<Float4>(Int4(*Pointer<UShort4>(source3))); 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; 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 if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{ {
v.x = Float4(*Pointer<Int4>(source0)); v.x = Float4(*Pointer<Int4>(source0));
...@@ -373,14 +395,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -373,14 +395,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = Float4(*Pointer<Int4>(source2)); v.z = Float4(*Pointer<Int4>(source2));
v.w = Float4(*Pointer<Int4>(source3)); 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(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt)); if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt)); if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleInt));
if(stream.count >= 4) v.w *= *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 else // Stream: Int, Shader attrib: Int/UInt, no type conversion
...@@ -390,10 +412,13 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -390,10 +412,13 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = *Pointer<Float4>(source2); v.z = *Pointer<Float4>(source2);
v.w = *Pointer<Float4>(source3); 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; 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 if(isNativeFloatAttrib) // Stream: UInt, Shader attrib: Float
{ {
v.x = Float4(*Pointer<UInt4>(source0)); v.x = Float4(*Pointer<UInt4>(source0));
...@@ -401,14 +426,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -401,14 +426,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = Float4(*Pointer<UInt4>(source2)); v.z = Float4(*Pointer<UInt4>(source2));
v.w = Float4(*Pointer<UInt4>(source3)); 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(componentCount >= 1) v.x *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
if(stream.count >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt)); if(componentCount >= 2) v.y *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
if(stream.count >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt)); if(componentCount >= 3) v.z *= *Pointer<Float4>(constants + OFFSET(Constants, unscaleUInt));
if(stream.count >= 4) v.w *= *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 else // Stream: UInt, Shader attrib: Int/UInt, no type conversion
...@@ -418,12 +443,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -418,12 +443,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z = *Pointer<Float4>(source2); v.z = *Pointer<Float4>(source2);
v.w = *Pointer<Float4>(source3); 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; 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 x0 = *Pointer<UShort>(source0 + 0);
UShort x1 = *Pointer<UShort>(source1 + 0); UShort x1 = *Pointer<UShort>(source1 + 0);
...@@ -436,7 +463,7 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -436,7 +463,7 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.x.w = *Pointer<Float>(constants + OFFSET(Constants, half2float) + Int(x3) * 4); 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 y0 = *Pointer<UShort>(source0 + 2);
UShort y1 = *Pointer<UShort>(source1 + 2); UShort y1 = *Pointer<UShort>(source1 + 2);
...@@ -449,7 +476,7 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -449,7 +476,7 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.y.w = *Pointer<Float>(constants + OFFSET(Constants, half2float) + Int(y3) * 4); 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 z0 = *Pointer<UShort>(source0 + 4);
UShort z1 = *Pointer<UShort>(source1 + 4); UShort z1 = *Pointer<UShort>(source1 + 4);
...@@ -462,7 +489,7 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -462,7 +489,7 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.z.w = *Pointer<Float>(constants + OFFSET(Constants, half2float) + Int(z3) * 4); 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 w0 = *Pointer<UShort>(source0 + 6);
UShort w1 = *Pointer<UShort>(source1 + 6); UShort w1 = *Pointer<UShort>(source1 + 6);
...@@ -476,20 +503,25 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -476,20 +503,25 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
} }
} }
break; 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; Int4 src;
src = Insert(src, *Pointer<Int>(source0), 0); src = Insert(src, *Pointer<Int>(source0), 0);
src = Insert(src, *Pointer<Int>(source1), 1); src = Insert(src, *Pointer<Int>(source1), 1);
src = Insert(src, *Pointer<Int>(source2), 2); src = Insert(src, *Pointer<Int>(source2), 2);
src = Insert(src, *Pointer<Int>(source3), 3); src = Insert(src, *Pointer<Int>(source3), 3);
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
v.x = Float4((src << 22) >> 22); v.x = Float4((src << 22) >> 22);
v.y = Float4((src << 12) >> 22); v.y = Float4((src << 12) >> 22);
v.z = Float4((src << 02) >> 22); v.z = Float4((src << 02) >> 22);
v.w = Float4(src >> 30); v.w = Float4(src >> 30);
if(stream.normalized) if(normalized)
{ {
v.x = Max(v.x * Float4(1.0f / 0x1FF), Float4(-1.0f)); 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.y = Max(v.y * Float4(1.0f / 0x1FF), Float4(-1.0f));
...@@ -497,8 +529,20 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -497,8 +529,20 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.w = Max(v.w, 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; 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; Int4 src;
src = Insert(src, *Pointer<Int>(source0), 0); src = Insert(src, *Pointer<Int>(source0), 0);
...@@ -506,12 +550,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -506,12 +550,14 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
src = Insert(src, *Pointer<Int>(source2), 2); src = Insert(src, *Pointer<Int>(source2), 2);
src = Insert(src, *Pointer<Int>(source3), 3); src = Insert(src, *Pointer<Int>(source3), 3);
if(isNativeFloatAttrib) // Stream: Int, Shader attrib: Float
{
v.x = Float4(src & Int4(0x3FF)); v.x = Float4(src & Int4(0x3FF));
v.y = Float4((src >> 10) & Int4(0x3FF)); v.y = Float4((src >> 10) & Int4(0x3FF));
v.z = Float4((src >> 20) & Int4(0x3FF)); v.z = Float4((src >> 20) & Int4(0x3FF));
v.w = Float4((src >> 30) & Int4(0x3)); v.w = Float4((src >> 30) & Int4(0x3));
if(stream.normalized) if(normalized)
{ {
v.x *= Float4(1.0f / 0x3FF); v.x *= Float4(1.0f / 0x3FF);
v.y *= Float4(1.0f / 0x3FF); v.y *= Float4(1.0f / 0x3FF);
...@@ -519,15 +565,31 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St ...@@ -519,15 +565,31 @@ Vector4f VertexRoutine::readStream(Pointer<Byte> &buffer, UInt &stride, const St
v.w *= Float4(1.0f / 0x3); 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; break;
default: default:
UNSUPPORTED("stream.type %d", int(stream.type)); UNSUPPORTED("stream.format %d", int(stream.format));
}
if(bgra)
{
// Swap red and blue
Float4 t = v.x;
v.x = v.z;
v.z = t;
} }
if(stream.count < 1) v.x = Float4(0.0f); if(componentCount < 1) v.x = Float4(0.0f);
if(stream.count < 2) v.y = Float4(0.0f); if(componentCount < 2) v.y = Float4(0.0f);
if(stream.count < 3) v.z = Float4(0.0f); if(componentCount < 3) v.z = Float4(0.0f);
if(stream.count < 4) v.w = isNativeFloatAttrib ? As<Float4>(Float4(1.0f)) : As<Float4>(Int4(1)); if(componentCount < 4) v.w = isNativeFloatAttrib ? As<Float4>(Float4(1.0f)) : As<Float4>(Int4(1));
return v; return v;
} }
......
...@@ -1811,7 +1811,7 @@ void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context &context, int f ...@@ -1811,7 +1811,7 @@ void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context &context, int f
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++) for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
{ {
auto &attrib = context.input[i]; auto &attrib = context.input[i];
if(attrib.count) if(attrib.format != VK_FORMAT_UNDEFINED)
{ {
const auto &vertexInput = vertexInputBindings[attrib.binding]; const auto &vertexInput = vertexInputBindings[attrib.binding];
VkDeviceSize offset = attrib.offset + vertexInput.offset + VkDeviceSize offset = attrib.offset + vertexInput.offset +
......
...@@ -689,7 +689,14 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor ...@@ -689,7 +689,14 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor
case VK_FORMAT_A8B8G8R8_SNORM_PACK32: case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32: case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_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_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_UNORM:
case VK_FORMAT_R16_SNORM: case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_UINT: case VK_FORMAT_R16_UINT:
......
...@@ -31,132 +31,6 @@ ...@@ -31,132 +31,6 @@
namespace { 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. // preprocessSpirv applies and freezes specializations into constants, and inlines all functions.
std::vector<uint32_t> preprocessSpirv( std::vector<uint32_t> preprocessSpirv(
std::vector<uint32_t> const &code, std::vector<uint32_t> const &code,
...@@ -333,9 +207,7 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateIn ...@@ -333,9 +207,7 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateIn
{ {
auto const &desc = vertexInputState->pVertexAttributeDescriptions[i]; auto const &desc = vertexInputState->pVertexAttributeDescriptions[i];
sw::Stream &input = context.input[desc.location]; sw::Stream &input = context.input[desc.location];
input.count = getNumberOfChannels(desc.format); input.format = desc.format;
input.type = getStreamType(desc.format);
input.normalized = !vk::Format(desc.format).isUnnormalizedInteger();
input.offset = desc.offset; input.offset = desc.offset;
input.binding = desc.binding; input.binding = desc.binding;
input.vertexStride = vertexStrides[desc.binding]; input.vertexStride = vertexStrides[desc.binding];
......
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