blob: 99c9de7a39b3a637912ca346c8c19af119cde290 [file] [log] [blame]
/*
* Copyright (c) 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cinttypes>
#include <cstdint>
#include <memory>
#include <variant>
#include <wtf/HashMap.h>
#include <wtf/OptionSet.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace WGSL {
//
// Step 1
//
enum class CompilationMessageType : uint8_t {
Error,
Warning,
Info
};
struct CompilationMessage {
String message;
uint64_t lineNumber;
uint64_t linePosition;
uint64_t offset;
uint64_t length;
};
class AST;
struct SuccessfulCheck {
~SuccessfulCheck();
Vector<CompilationMessage> warnings;
std::unique_ptr<AST> ast;
};
struct FailedCheck {
Vector<CompilationMessage> errors;
Vector<CompilationMessage> warnings;
};
struct SourceMap {
// I don't know what goes in here.
// https://sourcemaps.info/spec.html
};
std::variant<SuccessfulCheck, FailedCheck> staticCheck(const String& wgsl, const std::optional<SourceMap>&);
//
// Step 2
//
enum class BufferBindingType : uint8_t {
Uniform,
Storage,
ReadOnlyStorage
};
struct BufferBindingLayout {
BufferBindingType type;
bool hasDynamicOffset;
uint64_t minBindingSize;
};
enum class SamplerBindingType : uint8_t {
Filtering,
NonFiltering,
Comparison
};
struct SamplerBindingLayout {
SamplerBindingType type;
};
enum class TextureSampleType : uint8_t {
Float,
UnfilterableFloat,
Depth,
SignedInt,
UnsignedInt
};
enum class TextureViewDimension : uint8_t {
OneDimensional,
TwoDimensional,
TwoDimensionalArray,
Cube,
CubeArray,
ThreeDimensional
};
struct TextureBindingLayout {
TextureSampleType sampleType;
TextureViewDimension viewDimension;
bool multisampled;
};
/* enum class StorageTextureAccess : uint8_t {
writeOnly
}; */
struct StorageTextureBindingLayout {
// StorageTextureAccess access; // There's only one field in this enum
// TextureFormat format; // Not sure this is necessary
TextureViewDimension viewDimension;
};
struct ExternalTextureBindingLayout {
// Sentinel
};
enum class ShaderStage : uint8_t {
Vertex = 0x1,
Fragment = 0x2,
Compute = 0x4
};
struct BindGroupLayoutEntry {
uint32_t binding;
OptionSet<ShaderStage> visibility;
std::variant<BufferBindingLayout, SamplerBindingLayout, TextureBindingLayout, StorageTextureBindingLayout, ExternalTextureBindingLayout> bindingMember;
};
struct BindGroupLayout {
// Metal's [[id(n)]] indices are equal to the index into this vector.
Vector<BindGroupLayoutEntry> entries;
};
struct PipelineLayout {
// Metal's [[buffer(n)]] indices are equal to the index into this vector.
Vector<BindGroupLayout> bindGroupLayouts;
};
namespace Reflection {
struct Vertex {
bool invariantIsPresent;
// Tons of reflection data to appear here in the future.
};
struct Fragment {
// Tons of reflection data to appear here in the future.
};
struct WorkgroupSize {
unsigned width;
unsigned height;
unsigned depth;
};
struct Compute {
WorkgroupSize workgroupSize;
};
enum class SpecializationConstantType : uint8_t {
Boolean,
Float,
Int,
Unsigned
};
struct SpecializationConstant {
String mangledName;
SpecializationConstantType type;
};
struct EntryPointInformation {
String mangledName;
std::optional<PipelineLayout> defaultLayout; // If the input PipelineLayout is nullopt, the compiler computes a layout and returns it. https://gpuweb.github.io/gpuweb/#default-pipeline-layout
HashMap<std::pair<size_t, size_t>, size_t> bufferLengthLocations; // Metal buffer identity -> offset within helper buffer where its size needs to lie
Vector<SpecializationConstant> specializationConstants;
std::variant<Vertex, Fragment, Compute> typedEntryPoint;
};
} // namespace Reflection
struct PrepareResult {
String msl;
HashMap<String, Reflection::EntryPointInformation> entryPoints;
};
// These are not allowed to fail.
// All failures must have already been caught in check().
PrepareResult prepare(const AST&, const HashMap<String, std::optional<PipelineLayout>>&);
PrepareResult prepare(const AST&, const String& entryPointName, const std::optional<PipelineLayout>&);
} // namespace WGSL