Replace VertexFormatUtils with a dawn_native table of formats

This replaces multiple switches with a single indexing into a data
table, and also adds information about the VertexFormatBaseType for
later validation.

Bug: dawn:1008
Change-Id: Ic3f564b0dc571cc0008a54785613f962ce223452
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/59030
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2021-07-22 08:57:29 +00:00 committed by Dawn LUCI CQ
parent c607e81de2
commit 1384e8b163
14 changed files with 126 additions and 235 deletions

View File

@ -202,8 +202,6 @@ if (is_win || is_linux || is_chromeos || is_mac || is_fuchsia || is_android) {
"TypeTraits.h",
"TypedInteger.h",
"UnderlyingType.h",
"VertexFormatUtils.cpp",
"VertexFormatUtils.h",
"ityp_array.h",
"ityp_bitset.h",
"ityp_span.h",

View File

@ -54,8 +54,6 @@ target_sources(dawn_common PRIVATE
"TypeTraits.h"
"TypedInteger.h"
"UnderlyingType.h"
"VertexFormatUtils.cpp"
"VertexFormatUtils.h"
"ityp_array.h"
"ityp_bitset.h"
"ityp_span.h"

View File

@ -1,162 +0,0 @@
// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VertexFormatUtils.h"
#include "Assert.h"
namespace dawn {
uint32_t VertexFormatNumComponents(wgpu::VertexFormat format) {
switch (format) {
case wgpu::VertexFormat::Uint8x4:
case wgpu::VertexFormat::Sint8x4:
case wgpu::VertexFormat::Unorm8x4:
case wgpu::VertexFormat::Snorm8x4:
case wgpu::VertexFormat::Uint16x4:
case wgpu::VertexFormat::Sint16x4:
case wgpu::VertexFormat::Unorm16x4:
case wgpu::VertexFormat::Snorm16x4:
case wgpu::VertexFormat::Float16x4:
case wgpu::VertexFormat::Float32x4:
case wgpu::VertexFormat::Uint32x4:
case wgpu::VertexFormat::Sint32x4:
return 4;
case wgpu::VertexFormat::Float32x3:
case wgpu::VertexFormat::Uint32x3:
case wgpu::VertexFormat::Sint32x3:
return 3;
case wgpu::VertexFormat::Uint8x2:
case wgpu::VertexFormat::Sint8x2:
case wgpu::VertexFormat::Unorm8x2:
case wgpu::VertexFormat::Snorm8x2:
case wgpu::VertexFormat::Uint16x2:
case wgpu::VertexFormat::Sint16x2:
case wgpu::VertexFormat::Unorm16x2:
case wgpu::VertexFormat::Snorm16x2:
case wgpu::VertexFormat::Float16x2:
case wgpu::VertexFormat::Float32x2:
case wgpu::VertexFormat::Uint32x2:
case wgpu::VertexFormat::Sint32x2:
return 2;
case wgpu::VertexFormat::Float32:
case wgpu::VertexFormat::Uint32:
case wgpu::VertexFormat::Sint32:
return 1;
case wgpu::VertexFormat::Undefined:
break;
}
UNREACHABLE();
}
size_t VertexFormatComponentSize(wgpu::VertexFormat format) {
switch (format) {
case wgpu::VertexFormat::Uint8x2:
case wgpu::VertexFormat::Uint8x4:
case wgpu::VertexFormat::Sint8x2:
case wgpu::VertexFormat::Sint8x4:
case wgpu::VertexFormat::Unorm8x2:
case wgpu::VertexFormat::Unorm8x4:
case wgpu::VertexFormat::Snorm8x2:
case wgpu::VertexFormat::Snorm8x4:
return sizeof(char);
case wgpu::VertexFormat::Uint16x2:
case wgpu::VertexFormat::Uint16x4:
case wgpu::VertexFormat::Unorm16x2:
case wgpu::VertexFormat::Unorm16x4:
case wgpu::VertexFormat::Sint16x2:
case wgpu::VertexFormat::Sint16x4:
case wgpu::VertexFormat::Snorm16x2:
case wgpu::VertexFormat::Snorm16x4:
case wgpu::VertexFormat::Float16x2:
case wgpu::VertexFormat::Float16x4:
return sizeof(uint16_t);
case wgpu::VertexFormat::Float32:
case wgpu::VertexFormat::Float32x2:
case wgpu::VertexFormat::Float32x3:
case wgpu::VertexFormat::Float32x4:
return sizeof(float);
case wgpu::VertexFormat::Uint32:
case wgpu::VertexFormat::Uint32x2:
case wgpu::VertexFormat::Uint32x3:
case wgpu::VertexFormat::Uint32x4:
case wgpu::VertexFormat::Sint32:
case wgpu::VertexFormat::Sint32x2:
case wgpu::VertexFormat::Sint32x3:
case wgpu::VertexFormat::Sint32x4:
return sizeof(int32_t);
case wgpu::VertexFormat::Undefined:
break;
}
UNREACHABLE();
}
size_t VertexFormatSize(wgpu::VertexFormat format) {
return VertexFormatNumComponents(format) * VertexFormatComponentSize(format);
}
const char* GetWGSLVertexFormatType(wgpu::VertexFormat format) {
switch (format) {
case wgpu::VertexFormat::Float32:
return "f32";
case wgpu::VertexFormat::Unorm8x2:
case wgpu::VertexFormat::Snorm8x2:
case wgpu::VertexFormat::Unorm16x2:
case wgpu::VertexFormat::Snorm16x2:
case wgpu::VertexFormat::Float16x2:
case wgpu::VertexFormat::Float32x2:
return "vec2<f32>";
case wgpu::VertexFormat::Float32x3:
return "vec3<f32>";
case wgpu::VertexFormat::Unorm8x4:
case wgpu::VertexFormat::Snorm8x4:
case wgpu::VertexFormat::Unorm16x4:
case wgpu::VertexFormat::Snorm16x4:
case wgpu::VertexFormat::Float16x4:
case wgpu::VertexFormat::Float32x4:
return "vec4<f32>";
case wgpu::VertexFormat::Uint32:
return "u32";
case wgpu::VertexFormat::Uint8x2:
case wgpu::VertexFormat::Uint16x2:
case wgpu::VertexFormat::Uint32x2:
return "vec2<u32>";
case wgpu::VertexFormat::Uint32x3:
return "vec3<u32>";
case wgpu::VertexFormat::Uint8x4:
case wgpu::VertexFormat::Uint16x4:
case wgpu::VertexFormat::Uint32x4:
return "vec4<u32>";
case wgpu::VertexFormat::Sint32:
return "i32";
case wgpu::VertexFormat::Sint8x2:
case wgpu::VertexFormat::Sint16x2:
case wgpu::VertexFormat::Sint32x2:
return "vec2<i32>";
case wgpu::VertexFormat::Sint32x3:
return "vec3<i32>";
case wgpu::VertexFormat::Sint8x4:
case wgpu::VertexFormat::Sint16x4:
case wgpu::VertexFormat::Sint32x4:
return "vec4<i32>";
case wgpu::VertexFormat::Undefined:
break;
}
UNREACHABLE();
}
} // namespace dawn

View File

@ -1,48 +0,0 @@
// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_VERTEX_FORMAT_UTILS_H_
#define DAWNNATIVE_VERTEX_FORMAT_UTILS_H_
#include <array>
#include <dawn/webgpu_cpp.h>
// TODO(dawn:695): Remove the dawncpp_headers CMake dependency when VertexFormatUtils is deleted,
// assuming no other dependencies have been added in other project files.
namespace dawn {
static constexpr std::array<wgpu::VertexFormat, 30> kAllVertexFormats = {
wgpu::VertexFormat::Uint8x2, wgpu::VertexFormat::Uint8x4, wgpu::VertexFormat::Sint8x2,
wgpu::VertexFormat::Sint8x4, wgpu::VertexFormat::Unorm8x2, wgpu::VertexFormat::Unorm8x4,
wgpu::VertexFormat::Snorm8x2, wgpu::VertexFormat::Snorm8x4, wgpu::VertexFormat::Uint16x2,
wgpu::VertexFormat::Uint16x4, wgpu::VertexFormat::Unorm16x2, wgpu::VertexFormat::Unorm16x4,
wgpu::VertexFormat::Sint16x2, wgpu::VertexFormat::Sint16x4, wgpu::VertexFormat::Snorm16x2,
wgpu::VertexFormat::Snorm16x4, wgpu::VertexFormat::Float16x2, wgpu::VertexFormat::Float16x4,
wgpu::VertexFormat::Float32, wgpu::VertexFormat::Float32x2, wgpu::VertexFormat::Float32x3,
wgpu::VertexFormat::Float32x4, wgpu::VertexFormat::Uint32, wgpu::VertexFormat::Uint32x2,
wgpu::VertexFormat::Uint32x3, wgpu::VertexFormat::Uint32x4, wgpu::VertexFormat::Sint32,
wgpu::VertexFormat::Sint32x2, wgpu::VertexFormat::Sint32x3, wgpu::VertexFormat::Sint32x4,
};
uint32_t VertexFormatNumComponents(wgpu::VertexFormat format);
size_t VertexFormatComponentSize(wgpu::VertexFormat format);
size_t VertexFormatSize(wgpu::VertexFormat format);
const char* GetWGSLVertexFormatType(wgpu::VertexFormat textureFormat);
} // namespace dawn
#endif

View File

@ -300,6 +300,8 @@ source_set("dawn_native_sources") {
"ToBackend.h",
"Toggles.cpp",
"Toggles.h",
"VertexFormat.cpp",
"VertexFormat.h",
"dawn_platform.h",
]

View File

@ -166,6 +166,8 @@ target_sources(dawn_native PRIVATE
"ToBackend.h"
"Toggles.cpp"
"Toggles.h"
"VertexFormat.cpp"
"VertexFormat.h"
"dawn_platform.h"
)
target_link_libraries(dawn_native

View File

@ -15,12 +15,12 @@
#include "dawn_native/RenderPipeline.h"
#include "common/BitSetIterator.h"
#include "common/VertexFormatUtils.h"
#include "dawn_native/ChainUtils_autogen.h"
#include "dawn_native/Commands.h"
#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/ValidationUtils_autogen.h"
#include "dawn_native/VertexFormat.h"
#include <cmath>
@ -33,6 +33,7 @@ namespace dawn_native {
uint64_t vertexBufferStride,
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
DAWN_TRY(ValidateVertexFormat(attribute->format));
const VertexFormatInfo& formatInfo = GetVertexFormatInfo(attribute->format);
if (attribute->shaderLocation >= kMaxVertexAttributes) {
return DAWN_VALIDATION_ERROR("Setting attribute out of bounds");
@ -40,9 +41,8 @@ namespace dawn_native {
// No underflow is possible because the max vertex format size is smaller than
// kMaxVertexBufferArrayStride.
ASSERT(kMaxVertexBufferArrayStride >= dawn::VertexFormatSize(attribute->format));
if (attribute->offset >
kMaxVertexBufferArrayStride - dawn::VertexFormatSize(attribute->format)) {
ASSERT(kMaxVertexBufferArrayStride >= formatInfo.byteSize);
if (attribute->offset > kMaxVertexBufferArrayStride - formatInfo.byteSize) {
return DAWN_VALIDATION_ERROR("Setting attribute offset out of bounds");
}
@ -50,12 +50,11 @@ namespace dawn_native {
// than kMaxVertexBufferArrayStride.
ASSERT(attribute->offset < kMaxVertexBufferArrayStride);
if (vertexBufferStride > 0 &&
attribute->offset + dawn::VertexFormatSize(attribute->format) >
vertexBufferStride) {
attribute->offset + formatInfo.byteSize > vertexBufferStride) {
return DAWN_VALIDATION_ERROR("Setting attribute offset out of bounds");
}
if (attribute->offset % dawn::VertexFormatComponentSize(attribute->format) != 0) {
if (attribute->offset % formatInfo.componentByteSize != 0) {
return DAWN_VALIDATION_ERROR(
"Attribute offset needs to be a multiple of the size format's components");
}

View File

@ -16,7 +16,6 @@
#include "common/Constants.h"
#include "common/HashUtils.h"
#include "common/VertexFormatUtils.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/ChainUtils_autogen.h"
#include "dawn_native/CompilationMessages.h"

View File

@ -0,0 +1,69 @@
// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn_native/VertexFormat.h"
#include "common/Assert.h"
#include <array>
namespace dawn_native {
static constexpr std::array<VertexFormatInfo, 31> sVertexFormatTable = {{
//
{wgpu::VertexFormat::Undefined, 0, 0, 0, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Uint8x2, 2, 2, 1, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Uint8x4, 4, 4, 1, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Sint8x2, 2, 2, 1, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Sint8x4, 4, 4, 1, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Unorm8x2, 2, 2, 1, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Unorm8x4, 4, 4, 1, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Snorm8x2, 2, 2, 1, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Snorm8x4, 4, 4, 1, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Uint16x2, 4, 2, 2, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Uint16x4, 8, 4, 2, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Sint16x2, 4, 2, 2, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Sint16x4, 8, 4, 2, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Unorm16x2, 4, 2, 2, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Unorm16x4, 8, 4, 2, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Snorm16x2, 4, 2, 2, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Snorm16x4, 8, 4, 2, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Float16x2, 4, 2, 2, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Float16x4, 8, 4, 2, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Float32, 4, 1, 4, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Float32x2, 8, 2, 4, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Float32x3, 12, 3, 4, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Float32x4, 16, 4, 4, VertexFormatBaseType::Float},
{wgpu::VertexFormat::Uint32, 4, 1, 4, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Uint32x2, 8, 2, 4, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Uint32x3, 12, 3, 4, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Uint32x4, 16, 4, 4, VertexFormatBaseType::Uint},
{wgpu::VertexFormat::Sint32, 4, 1, 4, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Sint32x2, 8, 2, 4, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Sint32x3, 12, 3, 4, VertexFormatBaseType::Sint},
{wgpu::VertexFormat::Sint32x4, 16, 4, 4, VertexFormatBaseType::Sint},
//
}};
const VertexFormatInfo& GetVertexFormatInfo(wgpu::VertexFormat format) {
ASSERT(format != wgpu::VertexFormat::Undefined);
ASSERT(static_cast<uint32_t>(format) < sVertexFormatTable.size());
ASSERT(sVertexFormatTable[static_cast<uint32_t>(format)].format == format);
return sVertexFormatTable[static_cast<uint32_t>(format)];
}
} // namespace dawn_native

View File

@ -0,0 +1,40 @@
// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_VERTEXFORMAT_H_
#define DAWNNATIVE_VERTEXFORMAT_H_
#include "dawn_native/dawn_platform.h"
namespace dawn_native {
enum class VertexFormatBaseType {
Float,
Uint,
Sint,
};
struct VertexFormatInfo {
wgpu::VertexFormat format;
uint32_t byteSize;
uint32_t componentCount;
uint32_t componentByteSize;
VertexFormatBaseType baseType;
};
const VertexFormatInfo& GetVertexFormatInfo(wgpu::VertexFormat format);
} // namespace dawn_native
#endif // DAWNNATIVE_VERTEXFORMAT_H_

View File

@ -14,7 +14,7 @@
#include "dawn_native/metal/RenderPipelineMTL.h"
#include "common/VertexFormatUtils.h"
#include "dawn_native/VertexFormat.h"
#include "dawn_native/metal/DeviceMTL.h"
#include "dawn_native/metal/PipelineLayoutMTL.h"
#include "dawn_native/metal/ShaderModuleMTL.h"
@ -479,8 +479,8 @@ namespace dawn_native { namespace metal {
continue;
}
maxArrayStride =
std::max(maxArrayStride,
dawn::VertexFormatSize(attrib.format) + size_t(attrib.offset));
std::max(maxArrayStride, GetVertexFormatInfo(attrib.format).byteSize +
size_t(attrib.offset));
}
layoutDesc.stepFunction = MTLVertexStepFunctionConstant;
layoutDesc.stepRate = 0;

View File

@ -14,13 +14,13 @@
#include "dawn_native/opengl/CommandBufferGL.h"
#include "common/VertexFormatUtils.h"
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupTracker.h"
#include "dawn_native/CommandEncoder.h"
#include "dawn_native/Commands.h"
#include "dawn_native/ExternalTexture.h"
#include "dawn_native/RenderBundle.h"
#include "dawn_native/VertexFormat.h"
#include "dawn_native/opengl/BufferGL.h"
#include "dawn_native/opengl/ComputePipelineGL.h"
#include "dawn_native/opengl/DeviceGL.h"
@ -179,7 +179,7 @@ namespace dawn_native { namespace opengl {
uint64_t offset = mVertexBufferOffsets[slot];
const VertexBufferInfo& vertexBuffer = mLastPipeline->GetVertexBuffer(slot);
uint32_t components = dawn::VertexFormatNumComponents(attribute.format);
uint32_t components = GetVertexFormatInfo(attribute.format).componentCount;
GLenum formatType = VertexFormatType(attribute.format);
GLboolean normalized = VertexFormatIsNormalized(attribute.format);

View File

@ -20,7 +20,6 @@
#include "tests/DawnTest.h"
#include "common/Constants.h"
#include "common/VertexFormatUtils.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"

View File

@ -15,8 +15,6 @@
#include "tests/unittests/validation/ValidationTest.h"
#include "common/Constants.h"
#include "common/VertexFormatUtils.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"
@ -111,8 +109,7 @@ namespace {
for (auto attr : buffer.attributes) {
// [[location({shaderLocation})]] var_{id} : {typeString},
inputStringStream << "[[location(" << attr.shaderLocation << ")]] var_"
<< attributeCount << " : "
<< dawn::GetWGSLVertexFormatType(attr.format) << ", ";
<< attributeCount << " : vec4<f32>,";
attributeCount++;
}
}
@ -171,9 +168,7 @@ namespace {
// Create a render pipeline using only one vertex-step-mode Float32x4 buffer
wgpu::RenderPipeline CreateBasicRenderPipeline(uint32_t bufferStride = kFloat32x4Stride) {
DAWN_ASSERT(bufferStride >=
dawn::VertexFormatNumComponents(wgpu::VertexFormat::Float32x4) *
dawn::VertexFormatComponentSize(wgpu::VertexFormat::Float32x4));
DAWN_ASSERT(bufferStride >= kFloat32x4Stride);
std::vector<PipelineVertexBufferDesc> bufferDescList = {
{bufferStride, wgpu::InputStepMode::Vertex, {{0, wgpu::VertexFormat::Float32x4}}},