diff --git a/ffi/SpirvInterpreter.h b/ffi/SpirvInterpreter.h index 4f40abd..f137d46 100644 --- a/ffi/SpirvInterpreter.h +++ b/ffi/SpirvInterpreter.h @@ -38,112 +38,7 @@ extern "C" #endif #ifndef spirv_H - typedef enum SpvBuiltIn_ SpvBuiltIn; - typedef enum SpvDecoration_ SpvDecoration; -#endif /* spirv_H */ - -typedef int SpvBool; -typedef unsigned char SpvByte; -typedef unsigned long SpvWord; -typedef unsigned long SpvSize; - -typedef enum -{ - SPV_RESULT_SUCCESS = 0, - SPV_RESULT_DIVISION_BY_ZERO = -1, - SPV_RESULT_INVALID_ENTRY_POINT = -2, - SPV_RESULT_INVALID_SPIRV = -3, - SPV_RESULT_INVALID_VALUE_TYPE = -4, - SPV_RESULT_KILLED = -5, - SPV_RESULT_NOT_FOUND = -6, - SPV_RESULT_OUT_OF_MEMORY = -7, - SPV_RESULT_OUT_OF_BOUNDS = -8, - SPV_RESULT_TODO = -9, - SPV_RESULT_UNREACHABLE = -10, - SPV_RESULT_UNSUPPORTED_SPIRV = -11, - SPV_RESULT_UNSUPPORTED_EXTENSION = -12, - SPV_RESULT_UNSUPPORTED_ENDIANNESS = -13, - SPV_RESULT_INVALID_MAGIC = -14, - SPV_RESULT_UNKNOWN = -15, -} SpvResult; - -typedef struct -{ - SpvBool use_simd_vectors_specializations; -} SpvModuleOptions; - -typedef struct -{ - SpvWord id; - SpvSize offset; - SpvSize size; -} SpvRuntimeSpecializationEntry; - -typedef enum -{ - SPV_LOCATION_INPUT = 0, - SPV_LOCATION_OUTPUT = 1, -} SpvLocationType; - -typedef struct -{ - float x; - float y; - float z; - float w; -} SpvVec4f; - -typedef struct -{ - unsigned int x; - unsigned int y; - unsigned int z; - unsigned int w; -} SpvVec4u; - -typedef SpvResult (*SpvReadImageFloat4_PFN)(void* driver_image, int x, int y, int z, SpvVec4f* dst); -typedef SpvResult (*SpvReadImageInt4_PFN)(void* driver_image, int x, int y, int z, SpvVec4u* dst); -typedef SpvResult (*SpvWriteImageFloat4_PFN)(void* driver_image, int x, int y, int z, SpvVec4f src); -typedef SpvResult (*SpvWriteImageInt4_PFN)(void* driver_image, int x, int y, int z, SpvVec4u src); - -typedef struct -{ - SpvReadImageFloat4_PFN SpvReadImageFloat4; - SpvReadImageInt4_PFN SpvReadImageInt4; - SpvWriteImageFloat4_PFN SpvWriteImageFloat4; - SpvWriteImageInt4_PFN SpvWriteImageInt4; -} SpvImageAPI; - -typedef void* SpvModule; -typedef void* SpvRuntime; - -SPV_API SpvResult SpvInitModule(SpvModule* module, const SpvWord* source, SpvSize source_len, SpvModuleOptions options); -SPV_API void SpvDeinitModule(SpvModule module); - -SPV_API SpvResult SpvInitRuntime(SpvRuntime* runtime, SpvModule module, SpvImageAPI image_api); -SPV_API void SpvDeinitRuntime(SpvRuntime runtime); - -SPV_API SpvResult SpvFlushDescriptorSets(SpvRuntime runtime); - -SPV_API SpvResult SpvAddSpecializationInfo(SpvRuntime runtime, SpvRuntimeSpecializationEntry entry, const SpvByte* data, SpvSize data_size); - -SPV_API SpvResult SpvGetResultByName(SpvRuntime runtime, const char* name, SpvWord* result); -SPV_API SpvResult SpvGetResultLocation(SpvRuntime runtime, SpvWord location, SpvLocationType type, SpvWord* result); -SPV_API SpvResult SpvGetEntryPointByName(SpvRuntime runtime, const char* name, SpvWord* result); -SPV_API SpvResult SpvGetResultMemorySize(SpvRuntime runtime, SpvWord result, SpvSize* size); -SPV_API SpvBool SpvHasResultDecoration(SpvRuntime runtime, SpvWord result, SpvDecoration decoration); - -SPV_API SpvResult SpvCallEntryPoint(SpvRuntime runtime, SpvWord entry_point_index); - -SPV_API SpvResult SpvReadOutput(SpvRuntime runtime, SpvByte* output, SpvSize output_size, SpvWord result); -SPV_API SpvResult SpvReadBuiltIn(SpvRuntime runtime, SpvByte* output, SpvSize output_size, SpvBuiltIn builtin); - -SPV_API SpvResult SpvWriteInput(SpvRuntime runtime, const SpvByte* input, SpvSize input_size, SpvWord result); -SPV_API SpvResult SpvWriteBuiltIn(SpvRuntime runtime, const SpvByte* input, SpvSize input_size, SpvBuiltIn builtin); -SPV_API SpvResult SpvWriteDescriptorSet(SpvRuntime runtime, const SpvByte* input, SpvSize input_size, SpvWord set, SpvWord binding, SpvWord descriptor_index); - -#ifndef spirv_H - enum SpvBuiltIn_ + typedef enum SpvBuiltIn_ { SpvBuiltInPosition = 0, SpvBuiltInPointSize = 1, @@ -295,8 +190,8 @@ SPV_API SpvResult SpvWriteDescriptorSet(SpvRuntime runtime, const SpvByte* input SpvBuiltInHitLSSRadiiNV = 5421, SpvBuiltInClusterIDNV = 5436, SpvBuiltInCullMaskKHR = 6021, - SpvBuiltInMax = 0x7fffffff, - }; + SpvBuiltInMax = 0x7fffffff + } SpvBuiltIn; typedef enum SpvDecoration_ { SpvDecorationRelaxedPrecision = 0, @@ -497,10 +392,122 @@ SPV_API SpvResult SpvWriteDescriptorSet(SpvRuntime runtime, const SpvByte* input SpvDecorationConditionalINTEL = 6247, SpvDecorationCacheControlLoadINTEL = 6442, SpvDecorationCacheControlStoreINTEL = 6443, - SpvDecorationMax = 0x7fffffff, + SpvDecorationMax = 0x7fffffff } SpvDecoration; + + typedef enum SpvDim_ { + _1D = 0, + _2D = 1, + _3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + Max = 0x7fffffff + } SpvDim; #endif /* spirv_H */ +typedef int SpvBool; +typedef unsigned char SpvByte; +typedef unsigned long SpvWord; +typedef unsigned long SpvSize; + +typedef enum +{ + SPV_RESULT_SUCCESS = 0, + SPV_RESULT_DIVISION_BY_ZERO = -1, + SPV_RESULT_INVALID_ENTRY_POINT = -2, + SPV_RESULT_INVALID_SPIRV = -3, + SPV_RESULT_INVALID_VALUE_TYPE = -4, + SPV_RESULT_KILLED = -5, + SPV_RESULT_NOT_FOUND = -6, + SPV_RESULT_OUT_OF_MEMORY = -7, + SPV_RESULT_OUT_OF_BOUNDS = -8, + SPV_RESULT_TODO = -9, + SPV_RESULT_UNREACHABLE = -10, + SPV_RESULT_UNSUPPORTED_SPIRV = -11, + SPV_RESULT_UNSUPPORTED_EXTENSION = -12, + SPV_RESULT_UNSUPPORTED_ENDIANNESS = -13, + SPV_RESULT_INVALID_MAGIC = -14, + SPV_RESULT_UNKNOWN = -15 +} SpvResult; + +typedef struct +{ + SpvBool use_simd_vectors_specializations; +} SpvModuleOptions; + +typedef struct +{ + SpvWord id; + SpvSize offset; + SpvSize size; +} SpvRuntimeSpecializationEntry; + +typedef enum +{ + SPV_LOCATION_INPUT = 0, + SPV_LOCATION_OUTPUT = 1 +} SpvLocationType; + +typedef struct +{ + float x; + float y; + float z; + float w; +} SpvVec4f; + +typedef struct +{ + unsigned int x; + unsigned int y; + unsigned int z; + unsigned int w; +} SpvVec4u; + +typedef SpvResult (*SpvReadImageFloat4_PFN)(void* driver_image, SpvDim dim, int x, int y, int z, SpvVec4f* dst); +typedef SpvResult (*SpvReadImageInt4_PFN)(void* driver_image, SpvDim dim, int x, int y, int z, SpvVec4u* dst); +typedef SpvResult (*SpvWriteImageFloat4_PFN)(void* driver_image, SpvDim dim, int x, int y, int z, SpvVec4f src); +typedef SpvResult (*SpvWriteImageInt4_PFN)(void* driver_image, SpvDim dim, int x, int y, int z, SpvVec4u src); + +typedef struct +{ + SpvReadImageFloat4_PFN SpvReadImageFloat4; + SpvReadImageInt4_PFN SpvReadImageInt4; + SpvWriteImageFloat4_PFN SpvWriteImageFloat4; + SpvWriteImageInt4_PFN SpvWriteImageInt4; +} SpvImageAPI; + +typedef void* SpvModule; +typedef void* SpvRuntime; + +SPV_API SpvResult SpvInitModule(SpvModule* module, const SpvWord* source, SpvSize source_len, SpvModuleOptions options); +SPV_API void SpvDeinitModule(SpvModule module); + +SPV_API SpvResult SpvInitRuntime(SpvRuntime* runtime, SpvModule module, SpvImageAPI image_api); +SPV_API void SpvDeinitRuntime(SpvRuntime runtime); + +SPV_API SpvResult SpvFlushDescriptorSets(SpvRuntime runtime); + +SPV_API SpvResult SpvAddSpecializationInfo(SpvRuntime runtime, SpvRuntimeSpecializationEntry entry, const SpvByte* data, SpvSize data_size); + +SPV_API SpvResult SpvGetResultByName(SpvRuntime runtime, const char* name, SpvWord* result); +SPV_API SpvResult SpvGetResultLocation(SpvRuntime runtime, SpvWord location, SpvLocationType type, SpvWord* result); +SPV_API SpvResult SpvGetEntryPointByName(SpvRuntime runtime, const char* name, SpvWord* result); +SPV_API SpvResult SpvGetResultMemorySize(SpvRuntime runtime, SpvWord result, SpvSize* size); +SPV_API SpvBool SpvHasResultDecoration(SpvRuntime runtime, SpvWord result, SpvDecoration decoration); + +SPV_API SpvResult SpvCallEntryPoint(SpvRuntime runtime, SpvWord entry_point_index); + +SPV_API SpvResult SpvReadOutput(SpvRuntime runtime, SpvByte* output, SpvSize output_size, SpvWord result); +SPV_API SpvResult SpvReadBuiltIn(SpvRuntime runtime, SpvByte* output, SpvSize output_size, SpvBuiltIn builtin); + +SPV_API SpvResult SpvWriteInput(SpvRuntime runtime, const SpvByte* input, SpvSize input_size, SpvWord result); +SPV_API SpvResult SpvWriteBuiltIn(SpvRuntime runtime, const SpvByte* input, SpvSize input_size, SpvBuiltIn builtin); +SPV_API SpvResult SpvWriteDescriptorSet(SpvRuntime runtime, const SpvByte* input, SpvSize input_size, SpvWord set, SpvWord binding, SpvWord descriptor_index); + #ifdef __cplusplus } #endif diff --git a/ffi/runtime.zig b/ffi/runtime.zig index d21369d..0c6060c 100644 --- a/ffi/runtime.zig +++ b/ffi/runtime.zig @@ -27,10 +27,10 @@ const Vec4u = extern struct { w: c_uint, }; -const readImageFloat4_PFN = *const fn (driver_image: ?*anyopaque, x: c_int, y: c_int, z: c_int, dst: *Vec4f) callconv(.c) ffi.Result; -const readImageInt4_PFN = *const fn (driver_image: ?*anyopaque, x: c_int, y: c_int, z: c_int, dst: *Vec4u) callconv(.c) ffi.Result; -const writeImageFloat4_PFN = *const fn (driver_image: ?*anyopaque, x: c_int, y: c_int, z: c_int, src: Vec4f) callconv(.c) ffi.Result; -const writeImageInt4_PFN = *const fn (driver_image: ?*anyopaque, x: c_int, y: c_int, z: c_int, src: Vec4u) callconv(.c) ffi.Result; +const readImageFloat4_PFN = *const fn (driver_image: ?*anyopaque, dim: spv.spv.SpvDim, x: c_int, y: c_int, z: c_int, dst: *Vec4f) callconv(.c) ffi.Result; +const readImageInt4_PFN = *const fn (driver_image: ?*anyopaque, dim: spv.spv.SpvDim, x: c_int, y: c_int, z: c_int, dst: *Vec4u) callconv(.c) ffi.Result; +const writeImageFloat4_PFN = *const fn (driver_image: ?*anyopaque, dim: spv.spv.SpvDim, x: c_int, y: c_int, z: c_int, src: Vec4f) callconv(.c) ffi.Result; +const writeImageInt4_PFN = *const fn (driver_image: ?*anyopaque, dim: spv.spv.SpvDim, x: c_int, y: c_int, z: c_int, src: Vec4u) callconv(.c) ffi.Result; const ImageAPI = extern struct { readImageFloat4: readImageFloat4_PFN, @@ -76,18 +76,19 @@ fn fromCResult(res: ffi.Result) spv.Runtime.RuntimeError!void { }; } +/// Hacky wrapper const ImageAPIBridge = struct { - threadlocal var current_image_api: ?*const ImageAPI = null; // Hacky + threadlocal var current_image_api: ?*const ImageAPI = null; fn getImageAPI() spv.Runtime.RuntimeError!*const ImageAPI { return current_image_api orelse spv.Runtime.RuntimeError.Unknown; } - fn readImageFloat4(driver_image: *anyopaque, x: i32, y: i32, z: i32) spv.Runtime.RuntimeError!spv.Runtime.Vec4(f32) { + fn readImageFloat4(driver_image: *anyopaque, dim: spv.spv.SpvDim, x: i32, y: i32, z: i32) spv.Runtime.RuntimeError!spv.Runtime.Vec4(f32) { const image_api = try getImageAPI(); var dst: Vec4f = undefined; - const result = image_api.readImageFloat4(driver_image, @intCast(x), @intCast(y), @intCast(z), &dst); + const result = image_api.readImageFloat4(driver_image, dim, @intCast(x), @intCast(y), @intCast(z), &dst); try fromCResult(result); @@ -99,11 +100,11 @@ const ImageAPIBridge = struct { }; } - fn readImageInt4(driver_image: *anyopaque, x: i32, y: i32, z: i32) spv.Runtime.RuntimeError!spv.Runtime.Vec4(u32) { + fn readImageInt4(driver_image: *anyopaque, dim: spv.spv.SpvDim, x: i32, y: i32, z: i32) spv.Runtime.RuntimeError!spv.Runtime.Vec4(u32) { const image_api = try getImageAPI(); var dst: Vec4u = undefined; - const result = image_api.readImageInt4(driver_image, @intCast(x), @intCast(y), @intCast(z), &dst); + const result = image_api.readImageInt4(driver_image, dim, @intCast(x), @intCast(y), @intCast(z), &dst); try fromCResult(result); @@ -115,18 +116,18 @@ const ImageAPIBridge = struct { }; } - fn writeImageFloat4(driver_image: *anyopaque, x: i32, y: i32, z: i32, pixel: spv.Runtime.Vec4(f32)) spv.Runtime.RuntimeError!void { + fn writeImageFloat4(driver_image: *anyopaque, dim: spv.spv.SpvDim, x: i32, y: i32, z: i32, pixel: spv.Runtime.Vec4(f32)) spv.Runtime.RuntimeError!void { const image_api = try getImageAPI(); - const result = image_api.writeImageFloat4(driver_image, @intCast(x), @intCast(y), @intCast(z), .{ .x = pixel.x, .y = pixel.y, .z = pixel.z, .w = pixel.w }); + const result = image_api.writeImageFloat4(driver_image, dim, @intCast(x), @intCast(y), @intCast(z), .{ .x = pixel.x, .y = pixel.y, .z = pixel.z, .w = pixel.w }); try fromCResult(result); } - fn writeImageInt4(driver_image: *anyopaque, x: i32, y: i32, z: i32, pixel: spv.Runtime.Vec4(u32)) spv.Runtime.RuntimeError!void { + fn writeImageInt4(driver_image: *anyopaque, dim: spv.spv.SpvDim, x: i32, y: i32, z: i32, pixel: spv.Runtime.Vec4(u32)) spv.Runtime.RuntimeError!void { const image_api = try getImageAPI(); - const result = image_api.writeImageInt4(driver_image, @intCast(x), @intCast(y), @intCast(z), .{ .x = pixel.x, .y = pixel.y, .z = pixel.z, .w = pixel.w }); + const result = image_api.writeImageInt4(driver_image, dim, @intCast(x), @intCast(y), @intCast(z), .{ .x = pixel.x, .y = pixel.y, .z = pixel.z, .w = pixel.w }); try fromCResult(result); } diff --git a/src/Runtime.zig b/src/Runtime.zig index 4eeafd0..45babc3 100644 --- a/src/Runtime.zig +++ b/src/Runtime.zig @@ -55,10 +55,10 @@ pub fn Vec4(comptime T: type) type { } pub const ImageAPI = struct { - readImageFloat4: *const fn (driver_image: *anyopaque, x: i32, y: i32, z: i32) RuntimeError!Vec4(f32), - readImageInt4: *const fn (driver_image: *anyopaque, x: i32, y: i32, z: i32) RuntimeError!Vec4(u32), - writeImageFloat4: *const fn (driver_image: *anyopaque, x: i32, y: i32, z: i32, pixel: Vec4(f32)) RuntimeError!void, - writeImageInt4: *const fn (driver_image: *anyopaque, x: i32, y: i32, z: i32, pixel: Vec4(u32)) RuntimeError!void, + readImageFloat4: *const fn (driver_image: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32) RuntimeError!Vec4(f32), + readImageInt4: *const fn (driver_image: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32) RuntimeError!Vec4(u32), + writeImageFloat4: *const fn (driver_image: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32, pixel: Vec4(f32)) RuntimeError!void, + writeImageInt4: *const fn (driver_image: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32, pixel: Vec4(u32)) RuntimeError!void, }; mod: *Module, diff --git a/src/lib.zig b/src/lib.zig index 664d962..5d17774 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -41,6 +41,8 @@ pub const SpvByte = spv.SpvByte; pub const SpvWord = spv.SpvWord; pub const SpvBool = spv.SpvBool; +pub const SpvDim = spv.SpvDim; + pub const Vec4f32 = @Vector(4, f32); pub const Vec3f32 = @Vector(3, f32); pub const Vec2f32 = @Vector(2, f32); diff --git a/src/opcodes.zig b/src/opcodes.zig index a575d5d..1f0161e 100644 --- a/src/opcodes.zig +++ b/src/opcodes.zig @@ -2495,8 +2495,14 @@ fn opImageRead(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void const coordinate = try rt.results[try rt.it.next()].getValue(); const dst = try rt.results[result_id].getValue(); - const driver_image = switch ((try image.getValue()).*) { - .Image => |img| img.driver_image, + const driver_image, const image_type = switch ((try image.getValue()).*) { + .Image => |img| .{ img.driver_image, switch ((try rt.results[img.type_word].getConstVariant()).*) { + .Type => |t| switch (t) { + .Image => |i| i, + else => return RuntimeError.InvalidSpirV, + }, + else => return RuntimeError.InvalidSpirV, + } }, else => return RuntimeError.InvalidSpirV, }; @@ -2586,13 +2592,13 @@ fn opImageRead(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void const z = helpers.readCoordLane(coordinate, 2) catch 0; switch (dst.*) { - .Vector4f32, .Vector3f32, .Vector2f32 => try helpers.writeFloatTexel(dst, try rt.image_api.readImageFloat4(driver_image, x, y, z)), - .Vector4i32, .Vector3i32, .Vector2i32, .Vector4u32, .Vector3u32, .Vector2u32 => try helpers.writeIntTexel(dst, try rt.image_api.readImageInt4(driver_image, x, y, z)), + .Vector4f32, .Vector3f32, .Vector2f32 => try helpers.writeFloatTexel(dst, try rt.image_api.readImageFloat4(driver_image, image_type.dim, x, y, z)), + .Vector4i32, .Vector3i32, .Vector2i32, .Vector4u32, .Vector3u32, .Vector2u32 => try helpers.writeIntTexel(dst, try rt.image_api.readImageInt4(driver_image, image_type.dim, x, y, z)), .Vector => |lanes| { if (lanes.len == 0) return RuntimeError.InvalidSpirV; switch (lanes[0]) { - .Float => try helpers.writeFloatTexel(dst, try rt.image_api.readImageFloat4(driver_image, x, y, z)), - .Int => try helpers.writeIntTexel(dst, try rt.image_api.readImageInt4(driver_image, x, y, z)), + .Float => try helpers.writeFloatTexel(dst, try rt.image_api.readImageFloat4(driver_image, image_type.dim, x, y, z)), + .Int => try helpers.writeIntTexel(dst, try rt.image_api.readImageInt4(driver_image, image_type.dim, x, y, z)), else => return RuntimeError.InvalidValueType, } }, @@ -2605,8 +2611,14 @@ fn opImageWrite(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!voi const coordinate = try rt.results[try rt.it.next()].getValue(); const texel = try rt.results[try rt.it.next()].getValue(); - const driver_image = switch ((try image.getValue()).*) { - .Image => |img| img.driver_image, + const driver_image, const image_type = switch ((try image.getValue()).*) { + .Image => |img| .{ img.driver_image, switch ((try rt.results[img.type_word].getConstVariant()).*) { + .Type => |t| switch (t) { + .Image => |i| i, + else => return RuntimeError.InvalidSpirV, + }, + else => return RuntimeError.InvalidSpirV, + } }, else => return RuntimeError.InvalidSpirV, }; @@ -2741,7 +2753,7 @@ fn opImageWrite(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!voi .Vector4f32, .Vector3f32, .Vector2f32, - => try rt.image_api.writeImageFloat4(driver_image, x, y, z, try helpers.readFloatTexel(texel)), + => try rt.image_api.writeImageFloat4(driver_image, image_type.dim, x, y, z, try helpers.readFloatTexel(texel)), .Int, .Vector4i32, .Vector3i32, @@ -2749,12 +2761,12 @@ fn opImageWrite(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!voi .Vector4u32, .Vector3u32, .Vector2u32, - => try rt.image_api.writeImageInt4(driver_image, x, y, z, try helpers.readIntTexel(texel)), + => try rt.image_api.writeImageInt4(driver_image, image_type.dim, x, y, z, try helpers.readIntTexel(texel)), .Vector => |lanes| { if (lanes.len == 0) return RuntimeError.InvalidSpirV; switch (lanes[0]) { - .Float => try rt.image_api.writeImageFloat4(driver_image, x, y, z, try helpers.readFloatTexel(texel)), - .Int => try rt.image_api.writeImageInt4(driver_image, x, y, z, try helpers.readIntTexel(texel)), + .Float => try rt.image_api.writeImageFloat4(driver_image, image_type.dim, x, y, z, try helpers.readFloatTexel(texel)), + .Int => try rt.image_api.writeImageInt4(driver_image, image_type.dim, x, y, z, try helpers.readIntTexel(texel)), else => return RuntimeError.InvalidValueType, } }, diff --git a/src/spv.zig b/src/spv.zig index 1e0b83e..3c6ff11 100644 --- a/src/spv.zig +++ b/src/spv.zig @@ -263,9 +263,9 @@ pub const SpvStorageClass = enum(u32) { }; pub const SpvDim = enum(u32) { - _1D = 0, - _2D = 1, - _3D = 2, + @"1D" = 0, + @"2D" = 1, + @"3D" = 2, Cube = 3, Rect = 4, Buffer = 5,