SPIR-V: Handle conversion of integer vertex input
This commit is contained in:
parent
1757411aa8
commit
9457c63a64
|
@ -64,10 +64,12 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
float_type_ = b.makeFloatType(32);
|
float_type_ = b.makeFloatType(32);
|
||||||
int_type_ = b.makeIntType(32);
|
int_type_ = b.makeIntType(32);
|
||||||
uint_type_ = b.makeUintType(32);
|
uint_type_ = b.makeUintType(32);
|
||||||
|
vec2_int_type_ = b.makeVectorType(int_type_, 2);
|
||||||
vec2_uint_type_ = b.makeVectorType(uint_type_, 2);
|
vec2_uint_type_ = b.makeVectorType(uint_type_, 2);
|
||||||
vec2_float_type_ = b.makeVectorType(float_type_, 2);
|
vec2_float_type_ = b.makeVectorType(float_type_, 2);
|
||||||
vec3_float_type_ = b.makeVectorType(float_type_, 3);
|
vec3_float_type_ = b.makeVectorType(float_type_, 3);
|
||||||
vec4_float_type_ = b.makeVectorType(float_type_, 4);
|
vec4_float_type_ = b.makeVectorType(float_type_, 4);
|
||||||
|
vec4_int_type_ = b.makeVectorType(int_type_, 4);
|
||||||
vec4_uint_type_ = b.makeVectorType(uint_type_, 4);
|
vec4_uint_type_ = b.makeVectorType(uint_type_, 4);
|
||||||
vec2_bool_type_ = b.makeVectorType(bool_type_, 2);
|
vec2_bool_type_ = b.makeVectorType(bool_type_, 2);
|
||||||
vec3_bool_type_ = b.makeVectorType(bool_type_, 3);
|
vec3_bool_type_ = b.makeVectorType(bool_type_, 3);
|
||||||
|
@ -222,6 +224,7 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
for (const auto& attrib : binding.attributes) {
|
for (const auto& attrib : binding.attributes) {
|
||||||
Id attrib_type = 0;
|
Id attrib_type = 0;
|
||||||
bool is_signed = attrib.fetch_instr.attributes.is_signed;
|
bool is_signed = attrib.fetch_instr.attributes.is_signed;
|
||||||
|
bool is_integer = attrib.fetch_instr.attributes.is_integer;
|
||||||
switch (attrib.fetch_instr.attributes.data_format) {
|
switch (attrib.fetch_instr.attributes.data_format) {
|
||||||
case VertexFormat::k_32:
|
case VertexFormat::k_32:
|
||||||
case VertexFormat::k_32_FLOAT:
|
case VertexFormat::k_32_FLOAT:
|
||||||
|
@ -229,6 +232,10 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16:
|
case VertexFormat::k_16_16:
|
||||||
case VertexFormat::k_32_32:
|
case VertexFormat::k_32_32:
|
||||||
|
if (is_integer) {
|
||||||
|
attrib_type = is_signed ? vec2_int_type_ : vec2_uint_type_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case VertexFormat::k_16_16_FLOAT:
|
case VertexFormat::k_16_16_FLOAT:
|
||||||
case VertexFormat::k_32_32_FLOAT:
|
case VertexFormat::k_32_32_FLOAT:
|
||||||
attrib_type = vec2_float_type_;
|
attrib_type = vec2_float_type_;
|
||||||
|
@ -236,10 +243,16 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
case VertexFormat::k_32_32_32_FLOAT:
|
case VertexFormat::k_32_32_32_FLOAT:
|
||||||
attrib_type = vec3_float_type_;
|
attrib_type = vec3_float_type_;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_8_8_8_8:
|
|
||||||
case VertexFormat::k_2_10_10_10:
|
case VertexFormat::k_2_10_10_10:
|
||||||
|
attrib_type = vec4_float_type_;
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_8_8_8_8:
|
||||||
case VertexFormat::k_16_16_16_16:
|
case VertexFormat::k_16_16_16_16:
|
||||||
case VertexFormat::k_32_32_32_32:
|
case VertexFormat::k_32_32_32_32:
|
||||||
|
if (is_integer) {
|
||||||
|
attrib_type = is_signed ? vec4_int_type_ : vec4_uint_type_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case VertexFormat::k_16_16_16_16_FLOAT:
|
case VertexFormat::k_16_16_16_16_FLOAT:
|
||||||
case VertexFormat::k_32_32_32_32_FLOAT:
|
case VertexFormat::k_32_32_32_32_FLOAT:
|
||||||
attrib_type = vec4_float_type_;
|
attrib_type = vec4_float_type_;
|
||||||
|
@ -970,8 +983,10 @@ spv::Id SpirvShaderTranslator::BitfieldExtract(spv::Id result_type,
|
||||||
spv::Id base_type = b.getTypeId(base);
|
spv::Id base_type = b.getTypeId(base);
|
||||||
|
|
||||||
// <-- 32 - (offset + count) ------ [bits] -?-
|
// <-- 32 - (offset + count) ------ [bits] -?-
|
||||||
|
if (32 - (offset + count) > 0) {
|
||||||
base = b.createBinOp(spv::Op::OpShiftLeftLogical, base_type, base,
|
base = b.createBinOp(spv::Op::OpShiftLeftLogical, base_type, base,
|
||||||
b.makeUintConstant(32 - (offset + count)));
|
b.makeUintConstant(32 - (offset + count)));
|
||||||
|
}
|
||||||
// [bits] -?-?-?---------------------------
|
// [bits] -?-?-?---------------------------
|
||||||
auto op = is_signed ? spv::Op::OpShiftRightArithmetic
|
auto op = is_signed ? spv::Op::OpShiftRightArithmetic
|
||||||
: spv::Op::OpShiftRightLogical;
|
: spv::Op::OpShiftRightLogical;
|
||||||
|
@ -1115,9 +1130,9 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
b.makeUintConstant(11));
|
b.makeUintConstant(11));
|
||||||
*/
|
*/
|
||||||
// Workaround until NVIDIA fixes their compiler :|
|
// Workaround until NVIDIA fixes their compiler :|
|
||||||
components[0] = BitfieldExtract(comp_type, vertex, is_signed, 00, 10);
|
components[0] = BitfieldExtract(comp_type, vertex, is_signed, 00, 11);
|
||||||
components[1] = BitfieldExtract(comp_type, vertex, is_signed, 10, 11);
|
components[1] = BitfieldExtract(comp_type, vertex, is_signed, 11, 11);
|
||||||
components[2] = BitfieldExtract(comp_type, vertex, is_signed, 21, 11);
|
components[2] = BitfieldExtract(comp_type, vertex, is_signed, 22, 10);
|
||||||
|
|
||||||
op = is_signed ? spv::Op::OpConvertSToF : spv::Op::OpConvertUToF;
|
op = is_signed ? spv::Op::OpConvertSToF : spv::Op::OpConvertUToF;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
|
@ -1152,9 +1167,9 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
b.makeUintConstant(10));
|
b.makeUintConstant(10));
|
||||||
*/
|
*/
|
||||||
// Workaround until NVIDIA fixes their compiler :|
|
// Workaround until NVIDIA fixes their compiler :|
|
||||||
components[0] = BitfieldExtract(comp_type, vertex, is_signed, 00, 11);
|
components[0] = BitfieldExtract(comp_type, vertex, is_signed, 00, 10);
|
||||||
components[1] = BitfieldExtract(comp_type, vertex, is_signed, 11, 11);
|
components[1] = BitfieldExtract(comp_type, vertex, is_signed, 10, 11);
|
||||||
components[2] = BitfieldExtract(comp_type, vertex, is_signed, 22, 10);
|
components[2] = BitfieldExtract(comp_type, vertex, is_signed, 21, 11);
|
||||||
|
|
||||||
op = is_signed ? spv::Op::OpConvertSToF : spv::Op::OpConvertUToF;
|
op = is_signed ? spv::Op::OpConvertSToF : spv::Op::OpConvertUToF;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
|
@ -1171,6 +1186,30 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert any integers to floats.
|
||||||
|
auto scalar_type = b.getScalarTypeId(b.getTypeId(vertex));
|
||||||
|
if (scalar_type == int_type_ || scalar_type == uint_type_) {
|
||||||
|
auto op = scalar_type == int_type_ ? spv::Op::OpConvertSToF
|
||||||
|
: spv::Op::OpConvertUToF;
|
||||||
|
spv::Id vtx_type;
|
||||||
|
switch (vertex_components) {
|
||||||
|
case 1:
|
||||||
|
vtx_type = float_type_;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vtx_type = vec2_float_type_;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
vtx_type = vec3_float_type_;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
vtx_type = vec4_float_type_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex = b.createUnaryOp(op, vtx_type, vertex);
|
||||||
|
}
|
||||||
|
|
||||||
vertex = b.createTriOp(spv::Op::OpSelect, b.getTypeId(vertex), cond, vertex,
|
vertex = b.createTriOp(spv::Op::OpSelect, b.getTypeId(vertex), cond, vertex,
|
||||||
alt_vertex);
|
alt_vertex);
|
||||||
StoreToResult(vertex, instr.result);
|
StoreToResult(vertex, instr.result);
|
||||||
|
|
|
@ -126,9 +126,9 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
|
|
||||||
// Types.
|
// Types.
|
||||||
spv::Id float_type_ = 0, bool_type_ = 0, int_type_ = 0, uint_type_ = 0;
|
spv::Id float_type_ = 0, bool_type_ = 0, int_type_ = 0, uint_type_ = 0;
|
||||||
spv::Id vec2_uint_type_ = 0;
|
spv::Id vec2_int_type_ = 0, vec2_uint_type_ = 0;
|
||||||
spv::Id vec2_float_type_ = 0, vec3_float_type_ = 0, vec4_float_type_ = 0;
|
spv::Id vec2_float_type_ = 0, vec3_float_type_ = 0, vec4_float_type_ = 0;
|
||||||
spv::Id vec4_uint_type_ = 0;
|
spv::Id vec4_int_type_ = 0, vec4_uint_type_ = 0;
|
||||||
spv::Id vec2_bool_type_ = 0, vec3_bool_type_ = 0, vec4_bool_type_ = 0;
|
spv::Id vec2_bool_type_ = 0, vec3_bool_type_ = 0, vec4_bool_type_ = 0;
|
||||||
spv::Id image_1d_type_ = 0, image_2d_type_ = 0, image_3d_type_ = 0,
|
spv::Id image_1d_type_ = 0, image_2d_type_ = 0, image_3d_type_ = 0,
|
||||||
image_cube_type_ = 0;
|
image_cube_type_ = 0;
|
||||||
|
|
|
@ -891,8 +891,13 @@ PipelineCache::UpdateStatus PipelineCache::UpdateVertexInputState(
|
||||||
bool is_integer = attrib.fetch_instr.attributes.is_integer;
|
bool is_integer = attrib.fetch_instr.attributes.is_integer;
|
||||||
switch (attrib.fetch_instr.attributes.data_format) {
|
switch (attrib.fetch_instr.attributes.data_format) {
|
||||||
case VertexFormat::k_8_8_8_8:
|
case VertexFormat::k_8_8_8_8:
|
||||||
|
if (is_integer) {
|
||||||
|
vertex_attrib_descr.format =
|
||||||
|
is_signed ? VK_FORMAT_R8G8B8A8_SINT : VK_FORMAT_R8G8B8A8_UINT;
|
||||||
|
} else {
|
||||||
vertex_attrib_descr.format =
|
vertex_attrib_descr.format =
|
||||||
is_signed ? VK_FORMAT_R8G8B8A8_SNORM : VK_FORMAT_R8G8B8A8_UNORM;
|
is_signed ? VK_FORMAT_R8G8B8A8_SNORM : VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_2_10_10_10:
|
case VertexFormat::k_2_10_10_10:
|
||||||
vertex_attrib_descr.format = is_signed
|
vertex_attrib_descr.format = is_signed
|
||||||
|
@ -910,16 +915,28 @@ PipelineCache::UpdateStatus PipelineCache::UpdateVertexInputState(
|
||||||
is_signed ? VK_FORMAT_R32_SINT : VK_FORMAT_R32_UINT;
|
is_signed ? VK_FORMAT_R32_SINT : VK_FORMAT_R32_UINT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16:
|
case VertexFormat::k_16_16:
|
||||||
|
if (is_integer) {
|
||||||
|
vertex_attrib_descr.format =
|
||||||
|
is_signed ? VK_FORMAT_R16G16_SINT : VK_FORMAT_R16G16_UINT;
|
||||||
|
} else {
|
||||||
vertex_attrib_descr.format =
|
vertex_attrib_descr.format =
|
||||||
is_signed ? VK_FORMAT_R16G16_SNORM : VK_FORMAT_R16G16_UNORM;
|
is_signed ? VK_FORMAT_R16G16_SNORM : VK_FORMAT_R16G16_UNORM;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16_FLOAT:
|
case VertexFormat::k_16_16_FLOAT:
|
||||||
// assert_true(is_signed);
|
// assert_true(is_signed);
|
||||||
vertex_attrib_descr.format = VK_FORMAT_R16G16_SFLOAT;
|
vertex_attrib_descr.format = VK_FORMAT_R16G16_SFLOAT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16_16_16:
|
case VertexFormat::k_16_16_16_16:
|
||||||
vertex_attrib_descr.format = is_signed ? VK_FORMAT_R16G16B16A16_SNORM
|
if (is_integer) {
|
||||||
|
vertex_attrib_descr.format = is_signed
|
||||||
|
? VK_FORMAT_R16G16B16A16_SINT
|
||||||
|
: VK_FORMAT_R16G16B16A16_UINT;
|
||||||
|
} else {
|
||||||
|
vertex_attrib_descr.format = is_signed
|
||||||
|
? VK_FORMAT_R16G16B16A16_SNORM
|
||||||
: VK_FORMAT_R16G16B16A16_UNORM;
|
: VK_FORMAT_R16G16B16A16_UNORM;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16_16_16_FLOAT:
|
case VertexFormat::k_16_16_16_16_FLOAT:
|
||||||
// assert_true(is_signed);
|
// assert_true(is_signed);
|
||||||
|
@ -927,19 +944,19 @@ PipelineCache::UpdateStatus PipelineCache::UpdateVertexInputState(
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32:
|
case VertexFormat::k_32:
|
||||||
// FIXME: Is this a NORM format?
|
// FIXME: Is this a NORM format?
|
||||||
assert_always();
|
assert_true(is_integer);
|
||||||
vertex_attrib_descr.format =
|
vertex_attrib_descr.format =
|
||||||
is_signed ? VK_FORMAT_R32_SINT : VK_FORMAT_R32_UINT;
|
is_signed ? VK_FORMAT_R32_SINT : VK_FORMAT_R32_UINT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32:
|
case VertexFormat::k_32_32:
|
||||||
// FIXME: Is this a NORM format?
|
// FIXME: Is this a NORM format?
|
||||||
assert_always();
|
assert_true(is_integer);
|
||||||
vertex_attrib_descr.format =
|
vertex_attrib_descr.format =
|
||||||
is_signed ? VK_FORMAT_R32G32_SINT : VK_FORMAT_R32G32_UINT;
|
is_signed ? VK_FORMAT_R32G32_SINT : VK_FORMAT_R32G32_UINT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32_32_32:
|
case VertexFormat::k_32_32_32_32:
|
||||||
// FIXME: Is this a NORM format?
|
// FIXME: Is this a NORM format?
|
||||||
assert_always();
|
assert_true(is_integer);
|
||||||
vertex_attrib_descr.format =
|
vertex_attrib_descr.format =
|
||||||
is_signed ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32_UINT;
|
is_signed ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32_UINT;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue