Implement unorm_rgba8 and unorm_rg8 vertex formats.
Backend support implemented in GL, Metal and D3D12. Support for unorm values in the GL backend requires a utility function to indicate if the format's components are normalized. Note that unorm_r8 is only supported on more recent MacOS SDKs (10.13), so it's omitted for now.
This commit is contained in:
parent
33dfd0a78f
commit
8d742d1375
|
@ -1222,7 +1222,9 @@
|
||||||
{"value": 0, "name": "float r32 g32 b32 a32"},
|
{"value": 0, "name": "float r32 g32 b32 a32"},
|
||||||
{"value": 1, "name": "float r32 g32 b32"},
|
{"value": 1, "name": "float r32 g32 b32"},
|
||||||
{"value": 2, "name": "float r32 g32"},
|
{"value": 2, "name": "float r32 g32"},
|
||||||
{"value": 3, "name": "float r32"}
|
{"value": 3, "name": "float r32"},
|
||||||
|
{"value": 4, "name": "unorm r8 g8 b8 a8"},
|
||||||
|
{"value": 5, "name": "unorm r8 g8"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"void": {
|
"void": {
|
||||||
|
|
|
@ -35,10 +35,12 @@ namespace backend {
|
||||||
uint32_t VertexFormatNumComponents(nxt::VertexFormat format) {
|
uint32_t VertexFormatNumComponents(nxt::VertexFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case nxt::VertexFormat::FloatR32G32B32A32:
|
case nxt::VertexFormat::FloatR32G32B32A32:
|
||||||
|
case nxt::VertexFormat::UnormR8G8B8A8:
|
||||||
return 4;
|
return 4;
|
||||||
case nxt::VertexFormat::FloatR32G32B32:
|
case nxt::VertexFormat::FloatR32G32B32:
|
||||||
return 3;
|
return 3;
|
||||||
case nxt::VertexFormat::FloatR32G32:
|
case nxt::VertexFormat::FloatR32G32:
|
||||||
|
case nxt::VertexFormat::UnormR8G8:
|
||||||
return 2;
|
return 2;
|
||||||
case nxt::VertexFormat::FloatR32:
|
case nxt::VertexFormat::FloatR32:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -47,18 +49,25 @@ namespace backend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t VertexFormatSize(nxt::VertexFormat format) {
|
size_t VertexFormatComponentSize(nxt::VertexFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case nxt::VertexFormat::FloatR32G32B32A32:
|
case nxt::VertexFormat::FloatR32G32B32A32:
|
||||||
case nxt::VertexFormat::FloatR32G32B32:
|
case nxt::VertexFormat::FloatR32G32B32:
|
||||||
case nxt::VertexFormat::FloatR32G32:
|
case nxt::VertexFormat::FloatR32G32:
|
||||||
case nxt::VertexFormat::FloatR32:
|
case nxt::VertexFormat::FloatR32:
|
||||||
return VertexFormatNumComponents(format) * sizeof(float);
|
return sizeof(float);
|
||||||
|
case nxt::VertexFormat::UnormR8G8B8A8:
|
||||||
|
case nxt::VertexFormat::UnormR8G8:
|
||||||
|
return sizeof(uint8_t);
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t VertexFormatSize(nxt::VertexFormat format) {
|
||||||
|
return VertexFormatNumComponents(format) * VertexFormatComponentSize(format);
|
||||||
|
}
|
||||||
|
|
||||||
// InputStateBase
|
// InputStateBase
|
||||||
|
|
||||||
InputStateBase::InputStateBase(InputStateBuilder* builder) {
|
InputStateBase::InputStateBase(InputStateBuilder* builder) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace backend {
|
||||||
|
|
||||||
size_t IndexFormatSize(nxt::IndexFormat format);
|
size_t IndexFormatSize(nxt::IndexFormat format);
|
||||||
uint32_t VertexFormatNumComponents(nxt::VertexFormat format);
|
uint32_t VertexFormatNumComponents(nxt::VertexFormat format);
|
||||||
|
size_t VertexFormatComponentSize(nxt::VertexFormat format);
|
||||||
size_t VertexFormatSize(nxt::VertexFormat format);
|
size_t VertexFormatSize(nxt::VertexFormat format);
|
||||||
|
|
||||||
class InputStateBase : public RefCounted {
|
class InputStateBase : public RefCounted {
|
||||||
|
|
|
@ -28,6 +28,10 @@ namespace backend { namespace d3d12 {
|
||||||
return DXGI_FORMAT_R32G32_FLOAT;
|
return DXGI_FORMAT_R32G32_FLOAT;
|
||||||
case nxt::VertexFormat::FloatR32:
|
case nxt::VertexFormat::FloatR32:
|
||||||
return DXGI_FORMAT_R32_FLOAT;
|
return DXGI_FORMAT_R32_FLOAT;
|
||||||
|
case nxt::VertexFormat::UnormR8G8B8A8:
|
||||||
|
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
case nxt::VertexFormat::UnormR8G8:
|
||||||
|
return DXGI_FORMAT_R8G8_UNORM;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ namespace backend { namespace metal {
|
||||||
return MTLVertexFormatFloat2;
|
return MTLVertexFormatFloat2;
|
||||||
case nxt::VertexFormat::FloatR32:
|
case nxt::VertexFormat::FloatR32:
|
||||||
return MTLVertexFormatFloat;
|
return MTLVertexFormatFloat;
|
||||||
|
case nxt::VertexFormat::UnormR8G8B8A8:
|
||||||
|
return MTLVertexFormatUChar4Normalized;
|
||||||
|
case nxt::VertexFormat::UnormR8G8:
|
||||||
|
return MTLVertexFormatUChar2Normalized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,24 @@ namespace backend { namespace opengl {
|
||||||
case nxt::VertexFormat::FloatR32G32:
|
case nxt::VertexFormat::FloatR32G32:
|
||||||
case nxt::VertexFormat::FloatR32:
|
case nxt::VertexFormat::FloatR32:
|
||||||
return GL_FLOAT;
|
return GL_FLOAT;
|
||||||
|
case nxt::VertexFormat::UnormR8G8B8A8:
|
||||||
|
case nxt::VertexFormat::UnormR8G8:
|
||||||
|
return GL_UNSIGNED_BYTE;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean VertexFormatIsNormalized(nxt::VertexFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case nxt::VertexFormat::FloatR32G32B32A32:
|
||||||
|
case nxt::VertexFormat::FloatR32G32B32:
|
||||||
|
case nxt::VertexFormat::FloatR32G32:
|
||||||
|
case nxt::VertexFormat::FloatR32:
|
||||||
|
return GL_FALSE;
|
||||||
|
case nxt::VertexFormat::UnormR8G8B8A8:
|
||||||
|
case nxt::VertexFormat::UnormR8G8:
|
||||||
|
return GL_TRUE;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -184,9 +202,10 @@ namespace backend { namespace opengl {
|
||||||
auto components = VertexFormatNumComponents(attribute.format);
|
auto components = VertexFormatNumComponents(attribute.format);
|
||||||
auto formatType = VertexFormatType(attribute.format);
|
auto formatType = VertexFormatType(attribute.format);
|
||||||
|
|
||||||
|
GLboolean normalized = VertexFormatIsNormalized(attribute.format);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
location, components, formatType, GL_FALSE, input.stride,
|
location, components, formatType, normalized, input.stride,
|
||||||
reinterpret_cast<void*>(
|
reinterpret_cast<void*>(
|
||||||
static_cast<intptr_t>(offset + attribute.offset)));
|
static_cast<intptr_t>(offset + attribute.offset)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,10 +44,12 @@ class InputStateTest : public NXTTest {
|
||||||
EXPECT_TRUE(component >= 0 && component < 4);
|
EXPECT_TRUE(component >= 0 && component < 4);
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case VertexFormat::FloatR32G32B32A32:
|
case VertexFormat::FloatR32G32B32A32:
|
||||||
|
case VertexFormat::UnormR8G8B8A8:
|
||||||
return component >= 4;
|
return component >= 4;
|
||||||
case VertexFormat::FloatR32G32B32:
|
case VertexFormat::FloatR32G32B32:
|
||||||
return component >= 3;
|
return component >= 3;
|
||||||
case VertexFormat::FloatR32G32:
|
case VertexFormat::FloatR32G32:
|
||||||
|
case VertexFormat::UnormR8G8:
|
||||||
return component >= 2;
|
return component >= 2;
|
||||||
case VertexFormat::FloatR32:
|
case VertexFormat::FloatR32:
|
||||||
return component >= 1;
|
return component >= 1;
|
||||||
|
|
Loading…
Reference in New Issue