From 5f7dc28a6d139487bab4ce61a60f12b3c53b6265 Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 19 Feb 2021 10:11:01 -0800 Subject: Make gfx library visible to external user. (#1719) * Make gfx library visible to external user. * Fixup --- .github/workflows/release-linux.yml | 4 +- .github/workflows/release-windows.yml | 3 + build/visual-studio/gfx/gfx.vcxproj | 2 +- build/visual-studio/gfx/gfx.vcxproj.filters | 6 +- examples/gpu-printing/main.cpp | 2 +- examples/hello-world/main.cpp | 2 +- examples/heterogeneous-hello-world/main.cpp | 2 +- examples/model-viewer/main.cpp | 2 +- examples/shader-object/main.cpp | 2 +- examples/shader-toy/main.cpp | 2 +- premake5.lua | 2 + slang-gfx.h | 1378 +++++++++++++++++++++++++++ tools/gfx-util/shader-cursor.h | 2 +- tools/gfx/cuda/render-cuda.cpp | 2 +- tools/gfx/d3d/d3d-util.h | 2 +- tools/gfx/render.h | 1378 --------------------------- tools/gfx/renderer-shared.h | 2 +- tools/gfx/slang-context.h | 2 +- tools/gfx/vulkan/vk-swap-chain.h | 2 +- tools/gfx/vulkan/vk-util.h | 2 +- tools/graphics-app-framework/gui.h | 2 +- tools/graphics-app-framework/model.h | 2 +- tools/render-test/options.h | 2 +- tools/render-test/render-test-main.cpp | 2 +- tools/render-test/shader-input-layout.cpp | 2 +- tools/render-test/shader-input-layout.h | 2 +- tools/render-test/shader-renderer-util.h | 2 +- tools/render-test/slang-support.h | 2 +- tools/render-test/surface.h | 2 +- 29 files changed, 1411 insertions(+), 1406 deletions(-) create mode 100644 slang-gfx.h delete mode 100644 tools/gfx/render.h diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index d07100721..ec9dd54b1 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -34,9 +34,9 @@ jobs: export SLANG_BINARY_ARCHIVE=slang-${SLANG_TAG}-${SLANG_OS_NAME}-${SLANG_ARCH_NAME}.zip export SLANG_BINARY_ARCHIVE_TAR=slang-${SLANG_TAG}-${SLANG_OS_NAME}-${SLANG_ARCH_NAME}.tar.gz echo "creating zip" - zip -r ${SLANG_BINARY_ARCHIVE} bin/*/*/slangc bin/*/*/libslang.so bin/*/*/libslang-glslang.so docs/*.md README.md LICENSE slang.h slang-com-helper.h slang-com-ptr.h slang-tag-version.h prelude/*.h + zip -r ${SLANG_BINARY_ARCHIVE} bin/*/*/slangc bin/*/*/libslang.so bin/*/*/libslang-glslang.so bin/*/*/libgfx.so docs/*.md README.md LICENSE slang.h slang-com-helper.h slang-com-ptr.h slang-tag-version.h slang-gfx.h prelude/*.h echo "creating tar" - tar -czf ${SLANG_BINARY_ARCHIVE_TAR} bin/*/*/slangc bin/*/*/libslang.so bin/*/*/libslang-glslang.so docs/*.md README.md LICENSE slang.h slang-com-helper.h slang-com-ptr.h slang-tag-version.h prelude/*.h + tar -czf ${SLANG_BINARY_ARCHIVE_TAR} bin/*/*/slangc bin/*/*/libslang.so bin/*/*/libslang-glslang.so bin/*/*/libgfx.so docs/*.md README.md LICENSE slang.h slang-com-helper.h slang-com-ptr.h slang-tag-version.h slang-gfx.h prelude/*.h echo "::set-output name=SLANG_BINARY_ARCHIVE::${SLANG_BINARY_ARCHIVE}" echo "::set-output name=SLANG_BINARY_ARCHIVE_TAR::${SLANG_BINARY_ARCHIVE_TAR}" - name: UploadBinary diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index ac0d90ee6..9d8ee94ca 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -50,10 +50,12 @@ jobs: 7z a "$binArchive" slang-com-helper.h 7z a "$binArchive" slang-com-ptr.h 7z a "$binArchive" slang-tag-version.h + 7z a "$srcArchive" slang-gfx.h 7z a "$binArchive" prelude\*.h 7z a "$binArchive" bin\*\*\slang.dll 7z a "$binArchive" bin\*\*\slang.lib 7z a "$binArchive" bin\*\*\slang-glslang.dll + 7z a "$binArchive" bin\*\*\gfx.dll 7z a "$binArchive" bin\*\*\slangc.exe 7z a "$binArchive" docs\*.md @@ -64,6 +66,7 @@ jobs: 7z a "$srcArchive" slang-com-helper.h 7z a "$srcArchive" slang-com-ptr.h 7z a "$srcArchive" slang-tag-version.h + 7z a "$srcArchive" slang-gfx.h 7z a "$srcArchive" prelude\*.h 7z a "$srcArchive" source\*\*.h 7z a "$srcArchive" source\*\*.cpp diff --git a/build/visual-studio/gfx/gfx.vcxproj b/build/visual-studio/gfx/gfx.vcxproj index 09555f45c..91c6a9441 100644 --- a/build/visual-studio/gfx/gfx.vcxproj +++ b/build/visual-studio/gfx/gfx.vcxproj @@ -179,6 +179,7 @@ + @@ -191,7 +192,6 @@ - diff --git a/build/visual-studio/gfx/gfx.vcxproj.filters b/build/visual-studio/gfx/gfx.vcxproj.filters index d034fc847..cf800961a 100644 --- a/build/visual-studio/gfx/gfx.vcxproj.filters +++ b/build/visual-studio/gfx/gfx.vcxproj.filters @@ -9,6 +9,9 @@ + + Header Files + Header Files @@ -45,9 +48,6 @@ Header Files - - Header Files - Header Files diff --git a/examples/gpu-printing/main.cpp b/examples/gpu-printing/main.cpp index 8dc0b0f3d..63b1939a6 100644 --- a/examples/gpu-printing/main.cpp +++ b/examples/gpu-printing/main.cpp @@ -5,7 +5,7 @@ #include using Slang::ComPtr; -#include "gfx/render.h" +#include "slang-gfx.h" #include "tools/graphics-app-framework/window.h" #include "source/core/slang-basic.h" using namespace gfx; diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp index 91c9c0627..49fe2ec67 100644 --- a/examples/hello-world/main.cpp +++ b/examples/hello-world/main.cpp @@ -32,7 +32,7 @@ // with Slang may depend on an application/engine making certain // design choices in their abstraction layer. // -#include "gfx/render.h" +#include "slang-gfx.h" #include "gfx-util/shader-cursor.h" #include "tools/graphics-app-framework/window.h" #include "slang-com-ptr.h" diff --git a/examples/heterogeneous-hello-world/main.cpp b/examples/heterogeneous-hello-world/main.cpp index 163b17deb..ff44ecc45 100644 --- a/examples/heterogeneous-hello-world/main.cpp +++ b/examples/heterogeneous-hello-world/main.cpp @@ -33,7 +33,7 @@ // design choices in their abstraction layer. // #include "slang-com-ptr.h" -#include "gfx/render.h" +#include "slang-gfx.h" #include "tools/graphics-app-framework/window.h" #include "../../prelude/slang-cpp-types.h" #include "source/core/slang-basic.h" diff --git a/examples/model-viewer/main.cpp b/examples/model-viewer/main.cpp index f830d4044..f18a2cc58 100644 --- a/examples/model-viewer/main.cpp +++ b/examples/model-viewer/main.cpp @@ -17,7 +17,7 @@ // layer, just to keep the examples short and to the point. // #include "graphics-app-framework/model.h" -#include "gfx/render.h" +#include "slang-gfx.h" #include "graphics-app-framework/vector-math.h" #include "graphics-app-framework/window.h" #include "graphics-app-framework/gui.h" diff --git a/examples/shader-object/main.cpp b/examples/shader-object/main.cpp index 88ae24393..b61cf30e4 100644 --- a/examples/shader-object/main.cpp +++ b/examples/shader-object/main.cpp @@ -12,7 +12,7 @@ #include using Slang::ComPtr; -#include "gfx/render.h" +#include "slang-gfx.h" #include "gfx-util/shader-cursor.h" #include "source/core/slang-basic.h" diff --git a/examples/shader-toy/main.cpp b/examples/shader-toy/main.cpp index 2bbc59113..89aa74ccb 100644 --- a/examples/shader-toy/main.cpp +++ b/examples/shader-toy/main.cpp @@ -19,7 +19,7 @@ using Slang::ComPtr; // this layer is *not* required or assumed when using the Slang language, // compiler, and API. // -#include "gfx/render.h" +#include "slang-gfx.h" #include "tools/graphics-app-framework/window.h" #include "source/core/slang-basic.h" diff --git a/premake5.lua b/premake5.lua index e3ae76fc2..b9176a7e1 100644 --- a/premake5.lua +++ b/premake5.lua @@ -750,6 +750,8 @@ tool "gfx" includedirs { ".", "external", "source" } + files {"slang-gfx.h"} + -- Will compile across targets addSourceDir "tools/gfx/nvapi" diff --git a/slang-gfx.h b/slang-gfx.h new file mode 100644 index 000000000..7b77650e8 --- /dev/null +++ b/slang-gfx.h @@ -0,0 +1,1378 @@ +// render.h +#pragma once + +#include +#include + +#include "slang.h" +#include "slang-com-ptr.h" +#include "slang-com-helper.h" + + +#if defined(SLANG_GFX_DYNAMIC) +# if defined(_MSC_VER) +# ifdef SLANG_GFX_DYNAMIC_EXPORT +# define SLANG_GFX_API SLANG_DLL_EXPORT +# else +# define SLANG_GFX_API __declspec(dllimport) +# endif +# else +// TODO: need to consider compiler capabilities +//# ifdef SLANG_DYNAMIC_EXPORT +# define SLANG_GFX_API SLANG_DLL_EXPORT +//# endif +# endif +#endif + +#ifndef SLANG_GFX_API +# define SLANG_GFX_API +#endif + +namespace gfx { + +using Slang::ComPtr; + +typedef SlangResult Result; + +// Had to move here, because Options needs types defined here +typedef SlangInt Int; +typedef SlangUInt UInt; + +// Declare opaque type +class IInputLayout: public ISlangUnknown +{ +}; +#define SLANG_UUID_IInputLayout \ + { \ + 0x45223711, 0xa84b, 0x455c, { 0xbe, 0xfa, 0x49, 0x37, 0x42, 0x1e, 0x8e, 0x2e } \ + } + +enum class PipelineType +{ + Unknown, + Graphics, + Compute, + RayTracing, + CountOf, +}; + +enum class StageType +{ + Unknown, + Vertex, + Hull, + Domain, + Geometry, + Fragment, + Compute, + RayGeneration, + Intersection, + AnyHit, + ClosestHit, + Miss, + Callable, + Amplification, + Mesh, + CountOf, +}; + +enum class RendererType +{ + Unknown, + DirectX11, + DirectX12, + OpenGl, + Vulkan, + CPU, + CUDA, + CountOf, +}; + +enum class ProjectionStyle +{ + Unknown, + OpenGl, + DirectX, + Vulkan, + CountOf, +}; + +/// The style of the binding +enum class BindingStyle +{ + Unknown, + DirectX, + OpenGl, + Vulkan, + CPU, + CUDA, + CountOf, +}; + +class IShaderProgram: public ISlangUnknown +{ +public: + + struct KernelDesc + { + StageType stage; + void const* codeBegin; + void const* codeEnd; + char const* entryPointName; + + UInt getCodeSize() const { return (char const*)codeEnd - (char const*)codeBegin; } + }; + + struct Desc + { + PipelineType pipelineType; + + KernelDesc const* kernels; + Int kernelCount; + + /// Use instead of `kernels`/`kernelCount` if loading a Slang program. + slang::IComponentType* slangProgram; + + /// Find and return the kernel for `stage`, if present. + KernelDesc const* findKernel(StageType stage) const + { + for(Int ii = 0; ii < kernelCount; ++ii) + if(kernels[ii].stage == stage) + return &kernels[ii]; + return nullptr; + } + }; +}; +#define SLANG_UUID_IShaderProgram \ + { \ + 0x9d32d0ad, 0x915c, 0x4ffd, { 0x91, 0xe2, 0x50, 0x85, 0x54, 0xa0, 0x4a, 0x76 } \ + } + +/// Different formats of things like pixels or elements of vertices +/// NOTE! Any change to this type (adding, removing, changing order) - must also be reflected in changes to RendererUtil +enum class Format +{ + Unknown, + + RGBA_Float32, + RGB_Float32, + RG_Float32, + R_Float32, + + RGBA_Unorm_UInt8, + + R_UInt16, + R_UInt32, + + D_Float32, + D_Unorm24_S8, + + CountOf, +}; + +struct InputElementDesc +{ + char const* semanticName; + UInt semanticIndex; + Format format; + UInt offset; +}; + +enum class MapFlavor +{ + Unknown, ///< Unknown mapping type + HostRead, + HostWrite, + WriteDiscard, +}; + +enum class PrimitiveTopology +{ + TriangleList, +}; + +class IResource: public ISlangUnknown +{ +public: + /// The type of resource. + /// NOTE! The order needs to be such that all texture types are at or after Texture1D (otherwise isTexture won't work correctly) + enum class Type + { + Unknown, ///< Unknown + Buffer, ///< A buffer (like a constant/index/vertex buffer) + Texture1D, ///< A 1d texture + Texture2D, ///< A 2d texture + Texture3D, ///< A 3d texture + TextureCube, ///< A cubemap consists of 6 Texture2D like faces + CountOf, + }; + + /// Describes how a resource is to be used + enum class Usage + { + Unknown = -1, + VertexBuffer = 0, + IndexBuffer, + ConstantBuffer, + StreamOutput, + RenderTarget, + DepthRead, + DepthWrite, + UnorderedAccess, + PixelShaderResource, + NonPixelShaderResource, + GenericRead, + CountOf, + }; + + /// Binding flags describe all of the ways a resource can be bound - and therefore used + struct BindFlag + { + enum Enum + { + VertexBuffer = 0x001, + IndexBuffer = 0x002, + ConstantBuffer = 0x004, + StreamOutput = 0x008, + RenderTarget = 0x010, + DepthStencil = 0x020, + UnorderedAccess = 0x040, + PixelShaderResource = 0x080, + NonPixelShaderResource = 0x100, + }; + }; + + /// Combinations describe how a resource can be accessed (typically by the host/cpu) + struct AccessFlag + { + enum Enum + { + Read = 0x1, + Write = 0x2 + }; + }; + + /// Base class for Descs + struct DescBase + { + bool canBind(BindFlag::Enum bindFlag) const { return (bindFlags & bindFlag) != 0; } + bool hasCpuAccessFlag(AccessFlag::Enum accessFlag) { return (cpuAccessFlags & accessFlag) != 0; } + + Type type = Type::Unknown; + + int bindFlags = 0; ///< Combination of Resource::BindFlag or 0 (and will use initialUsage to set) + int cpuAccessFlags = 0; ///< Combination of Resource::AccessFlag + }; + + inline static BindFlag::Enum getDefaultBindFlagsFromUsage(IResource::Usage usage) + { + switch (usage) + { + case Usage::VertexBuffer: + return BindFlag::VertexBuffer; + case Usage::IndexBuffer: + return BindFlag::IndexBuffer; + case Usage::ConstantBuffer: + return BindFlag::ConstantBuffer; + case Usage::StreamOutput: + return BindFlag::StreamOutput; + case Usage::RenderTarget: + return BindFlag::RenderTarget; + case Usage::DepthRead: + case Usage::DepthWrite: + return BindFlag::DepthStencil; + case Usage::UnorderedAccess: + return BindFlag::Enum(BindFlag::UnorderedAccess | BindFlag::PixelShaderResource | + BindFlag::NonPixelShaderResource); + case Usage::PixelShaderResource: + return BindFlag::PixelShaderResource; + case Usage::NonPixelShaderResource: + return BindFlag::NonPixelShaderResource; + case Usage::GenericRead: + return BindFlag::Enum( + BindFlag::PixelShaderResource | + BindFlag::NonPixelShaderResource); + default: + return BindFlag::Enum(-1); + } + } + + virtual SLANG_NO_THROW Type SLANG_MCALL getType() = 0; +}; +#define SLANG_UUID_IResource \ + { \ + 0xa0e39f34, 0x8398, 0x4522, { 0x95, 0xc2, 0xeb, 0xc0, 0xf9, 0x84, 0xef, 0x3f } \ + } + +class IBufferResource: public IResource +{ +public: + struct Desc: public DescBase + { + void init(size_t sizeInBytesIn) + { + sizeInBytes = sizeInBytesIn; + elementSize = 0; + format = Format::Unknown; + } + void setDefaults(Usage initialUsage) + { + if (bindFlags == 0) + { + bindFlags = getDefaultBindFlagsFromUsage(initialUsage); + } + } + size_t sizeInBytes; ///< Total size in bytes + int elementSize; ///< Get the element stride. If > 0, this is a structured buffer + Format format; + }; + virtual SLANG_NO_THROW Desc* SLANG_MCALL getDesc() = 0; +}; +#define SLANG_UUID_IBufferResource \ + { \ + 0x1b274efe, 0x5e37, 0x492b, { 0x82, 0x6e, 0x7e, 0xe7, 0xe8, 0xf5, 0xa4, 0x9b } \ + } + +template T _slang_gfx_max(T v0, T v1) { return v0 > v1 ? v0 : v1; } + +static inline unsigned int _slang_gfx_ones32(unsigned int x) +{ + /* 32-bit recursive reduction using SWAR... + but first step is mapping 2-bit values + into sum of 2 1-bit values in sneaky way + */ + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return (x & 0x0000003f); +} + +static inline unsigned int _slang_gfx_log2Floor(unsigned int x) +{ + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return (_slang_gfx_ones32(x >> 1)); +} + +class ITextureResource: public IResource +{ +public: + struct SampleDesc + { + void init() + { + numSamples = 1; + quality = 0; + } + int numSamples; ///< Number of samples per pixel + int quality; ///< The quality measure for the samples + }; + + struct Size + { + void init() + { + width = height = depth = 1; + } + void init(int widthIn, int heightIn = 1, int depthIn = 1) + { + width = widthIn; + height = heightIn; + depth = depthIn; + } + /// Given the type works out the maximum dimension size + int calcMaxDimension(Type type) const + { + switch (type) + { + case IResource::Type::Texture1D: + return this->width; + case IResource::Type::Texture3D: + return _slang_gfx_max(_slang_gfx_max(this->width, this->height), this->depth); + case IResource::Type::TextureCube: // fallthru + case IResource::Type::Texture2D: + { + return _slang_gfx_max(this->width, this->height); + } + default: + return 0; + } + } + + SLANG_FORCE_INLINE static int calcMipSize(int width, int mipLevel) + { + width = width >> mipLevel; + return width > 0 ? width : 1; + } + /// Given a size, calculates the size at a mip level + Size calcMipSize(int mipLevel) const + { + Size size; + size.width = calcMipSize(this->width, mipLevel); + size.height = calcMipSize(this->height, mipLevel); + size.depth = calcMipSize(this->depth, mipLevel); + return size; + } + + int width; ///< Width in pixels + int height; ///< Height in pixels (if 2d or 3d) + int depth; ///< Depth (if 3d) + }; + + struct Desc: public DescBase + { + /// Initialize with default values + void init(Type typeIn) + { + this->type = typeIn; + this->size.init(); + + this->format = Format::Unknown; + this->arraySize = 0; + this->numMipLevels = 0; + this->sampleDesc.init(); + + this->bindFlags = 0; + this->cpuAccessFlags = 0; + } + /// Initialize different dimensions. For cubemap, use init2D + void init1D(Format formatIn, int widthIn, int numMipMapsIn = 0) + { + this->type = Type::Texture1D; + this->size.init(widthIn); + + this->format = formatIn; + this->arraySize = 0; + this->numMipLevels = numMipMapsIn; + this->sampleDesc.init(); + + this->bindFlags = 0; + this->cpuAccessFlags = 0; + } + + void init2D(Type typeIn, Format formatIn, int widthIn, int heightIn, int numMipMapsIn = 0) + { + assert(typeIn == Type::Texture2D || typeIn == Type::TextureCube); + + this->type = typeIn; + this->size.init(widthIn, heightIn); + + this->format = formatIn; + this->arraySize = 0; + this->numMipLevels = numMipMapsIn; + this->sampleDesc.init(); + + this->bindFlags = 0; + this->cpuAccessFlags = 0; + } + + void init3D(Format formatIn, int widthIn, int heightIn, int depthIn, int numMipMapsIn = 0) + { + this->type = Type::Texture3D; + this->size.init(widthIn, heightIn, depthIn); + + this->format = formatIn; + this->arraySize = 0; + this->numMipLevels = numMipMapsIn; + this->sampleDesc.init(); + + this->bindFlags = 0; + this->cpuAccessFlags = 0; + } + + /// Given the type, calculates the number of mip maps. 0 on error + int calcNumMipLevels() const + { + const int maxDimensionSize = this->size.calcMaxDimension(type); + return (maxDimensionSize > 0) ? (_slang_gfx_log2Floor(maxDimensionSize) + 1) : 0; + } + /// Calculate the total number of sub resources. 0 on error. + int calcNumSubResources() const + { + const int numMipMaps = + (this->numMipLevels > 0) ? this->numMipLevels : calcNumMipLevels(); + const int arrSize = (this->arraySize > 0) ? this->arraySize : 1; + + switch (type) + { + case IResource::Type::Texture1D: + case IResource::Type::Texture2D: + { + return numMipMaps * arrSize; + } + case IResource::Type::Texture3D: + { + // can't have arrays of 3d textures + assert(this->arraySize <= 1); + return numMipMaps * this->size.depth; + } + case IResource::Type::TextureCube: + { + // There are 6 faces to a cubemap + return numMipMaps * arrSize * 6; + } + default: + return 0; + } + } + + /// Calculate the effective array size - in essence the amount if mip map sets needed. + /// In practice takes into account if the arraySize is 0 (it's not an array, but it will still have at least one mip set) + /// and if the type is a cubemap (multiplies the amount of mip sets by 6) + int calcEffectiveArraySize() const + { + const int arrSize = (this->arraySize > 0) ? this->arraySize : 1; + + switch (type) + { + case IResource::Type::Texture1D: // fallthru + case IResource::Type::Texture2D: + { + return arrSize; + } + case IResource::Type::TextureCube: + return arrSize * 6; + case IResource::Type::Texture3D: + return 1; + default: + return 0; + } + } + + /// Use type to fix the size values (and array size). + /// For example a 1d texture, should have height and depth set to 1. + void fixSize() + { + switch (type) + { + case IResource::Type::Texture1D: + { + this->size.height = 1; + this->size.depth = 1; + break; + } + case IResource::Type::TextureCube: + case IResource::Type::Texture2D: + { + this->size.depth = 1; + break; + } + case IResource::Type::Texture3D: + { + // Can't have an array + this->arraySize = 0; + break; + } + default: + break; + } + } + + /// Set up default parameters based on type and usage + void setDefaults(Usage initialUsage) + { + fixSize(); + if (this->bindFlags == 0) + { + this->bindFlags = getDefaultBindFlagsFromUsage(initialUsage); + } + if (this->numMipLevels <= 0) + { + this->numMipLevels = calcNumMipLevels(); + } + } + + Size size; + + int arraySize; ///< Array size + + int numMipLevels; ///< Number of mip levels - if 0 will create all mip levels + Format format; ///< The resources format + SampleDesc sampleDesc; ///< How the resource is sampled + }; + + /// The ordering of the subResources is + /// forall (effectiveArraySize) + /// forall (mip levels) + /// forall (depth levels) + struct Data + { + ptrdiff_t* mipRowStrides; ///< The row stride for a mip map + int numMips; ///< The number of mip maps + const void*const* subResources; ///< Pointers to each full mip subResource + int numSubResources; ///< The total amount of subResources. Typically = numMips * depth * arraySize + }; + + virtual SLANG_NO_THROW Desc* SLANG_MCALL getDesc() = 0; +}; +#define SLANG_UUID_ITextureResource \ + { \ + 0xcf88a31c, 0x6187, 0x46c5, { 0xa4, 0xb7, 0xeb, 0x58, 0xc7, 0x33, 0x40, 0x17 } \ + } + +// Needed for building on cygwin with gcc +#undef Always +#undef None + +enum class ComparisonFunc : uint8_t +{ + Never = 0, + Less = 0x01, + Equal = 0x02, + LessEqual = 0x03, + Greater = 0x04, + NotEqual = 0x05, + GreaterEqual = 0x06, + Always = 0x07, +}; + +enum class TextureFilteringMode +{ + Point, + Linear, +}; + +enum class TextureAddressingMode +{ + Wrap, + ClampToEdge, + ClampToBorder, + MirrorRepeat, + MirrorOnce, +}; + +enum class TextureReductionOp +{ + Average, + Comparison, + Minimum, + Maximum, +}; + +class ISamplerState : public ISlangUnknown +{ +public: + struct Desc + { + TextureFilteringMode minFilter = TextureFilteringMode::Linear; + TextureFilteringMode magFilter = TextureFilteringMode::Linear; + TextureFilteringMode mipFilter = TextureFilteringMode::Linear; + TextureReductionOp reductionOp = TextureReductionOp::Average; + TextureAddressingMode addressU = TextureAddressingMode::Wrap; + TextureAddressingMode addressV = TextureAddressingMode::Wrap; + TextureAddressingMode addressW = TextureAddressingMode::Wrap; + float mipLODBias = 0.0f; + uint32_t maxAnisotropy = 1; + ComparisonFunc comparisonFunc = ComparisonFunc::Never; + float borderColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + float minLOD = -FLT_MAX; + float maxLOD = FLT_MAX; + }; +}; +#define SLANG_UUID_ISamplerState \ + { \ + 0x8b8055df, 0x9377, 0x401d, { 0x91, 0xff, 0x3f, 0xa3, 0xbf, 0x66, 0x64, 0xf4 } \ + } + + +enum class DescriptorSlotType +{ + Unknown, + + Sampler, + CombinedImageSampler, + SampledImage, + StorageImage, + UniformTexelBuffer, + StorageTexelBuffer, + UniformBuffer, + ReadOnlyStorageBuffer, + StorageBuffer, + DynamicUniformBuffer, + DynamicStorageBuffer, + InputAttachment, + RootConstant, + InlineUniformBlock, + RayTracingAccelerationStructure, +}; + +class IDescriptorSetLayout : public ISlangUnknown +{ +public: + struct SlotRangeDesc + { + DescriptorSlotType type = DescriptorSlotType::Unknown; + UInt count = 1; + + /// The underlying API-specific binding/register to use for this slot range. + /// + /// A value of `-1` indicates that the implementation should + /// automatically compute the binding/register to use + /// based on the preceeding slot range(s). + /// + /// Some implementations do not have a concept of bindings/regsiters + /// for slot ranges, and will ignore this field. + /// + Int binding = -1; + + SlotRangeDesc() + {} + + SlotRangeDesc( + DescriptorSlotType type, + UInt count = 1) + : type(type) + , count(count) + {} + }; + + struct Desc + { + UInt slotRangeCount = 0; + SlotRangeDesc const* slotRanges = nullptr; + }; +}; +#define SLANG_UUID_IDescriptorSetLayout \ + { \ + 0x9fe39a2f, 0xdf8b, 0x4690, { 0x90, 0x6a, 0x10, 0x1e, 0xed, 0xf9, 0xbe, 0xc0 } \ + } + + +class IPipelineLayout : public ISlangUnknown +{ +public: + struct DescriptorSetDesc + { + IDescriptorSetLayout* layout = nullptr; + + /// The underlying API-specific space/set number to use for this set. + /// + /// A value of `-1` indicates that the implementation should + /// automatically compute the space/set to use basd on + /// the preceeding set(s) + /// + /// Some implementations do not have a concept of space/set numbers + /// for descriptor sets, and will ignore this field. + /// + Int space = -1; + + DescriptorSetDesc() + {} + + DescriptorSetDesc( + IDescriptorSetLayout* layout) + : layout(layout) + {} + }; + + struct Desc + { + UInt renderTargetCount = 0; + UInt descriptorSetCount = 0; + DescriptorSetDesc const* descriptorSets = nullptr; + }; +}; +#define SLANG_UUID_IPipelineLayout \ + { \ + 0x9d644a9a, 0x3e6f, 0x4350, { 0xa3, 0x5a, 0xe8, 0xe3, 0xbc, 0xef, 0xb9, 0xcf } \ + } + +class IResourceView : public ISlangUnknown +{ +public: + enum class Type + { + Unknown, + + RenderTarget, + DepthStencil, + ShaderResource, + UnorderedAccess, + }; + + struct Desc + { + Type type; + Format format; + }; +}; +#define SLANG_UUID_IResourceView \ + { \ + 0x7b6c4926, 0x884, 0x408c, { 0xad, 0x8a, 0x50, 0x3a, 0x8e, 0x23, 0x98, 0xa4 } \ + } + + +class IDescriptorSet : public ISlangUnknown +{ +public: + virtual SLANG_NO_THROW void SLANG_MCALL setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL + setResource(UInt range, UInt index, IResourceView* view) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL + setSampler(UInt range, UInt index, ISamplerState* sampler) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL setCombinedTextureSampler( + UInt range, + UInt index, + IResourceView* textureView, + ISamplerState* sampler) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL + setRootConstants( + UInt range, + UInt offset, + UInt size, + void const* data) = 0; +}; +#define SLANG_UUID_IDescriptorSet \ + { \ + 0x29a881ea, 0xd7, 0x41d4, { 0xa3, 0x2d, 0x6c, 0x78, 0x4b, 0x79, 0xda, 0x2e } \ + } + + +struct ShaderOffset +{ + SlangInt uniformOffset = 0; + SlangInt bindingRangeIndex = 0; + SlangInt bindingArrayIndex = 0; +}; + +class IShaderObject : public ISlangUnknown +{ +public: + SLANG_NO_THROW ComPtr SLANG_MCALL getObject(ShaderOffset const& offset) + { + ComPtr object = nullptr; + SLANG_RETURN_NULL_ON_FAIL(getObject(offset, object.writeRef())); + return object; + } + + virtual SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL getElementTypeLayout() = 0; + virtual SLANG_NO_THROW UInt SLANG_MCALL getEntryPointCount() = 0; + + ComPtr getEntryPoint(UInt index) + { + ComPtr entryPoint = nullptr; + SLANG_RETURN_NULL_ON_FAIL(getEntryPoint(index, entryPoint.writeRef())); + return entryPoint; + } + virtual SLANG_NO_THROW Result SLANG_MCALL + getEntryPoint(UInt index, IShaderObject** entryPoint) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL + setData(ShaderOffset const& offset, void const* data, size_t size) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL + getObject(ShaderOffset const& offset, IShaderObject** object) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL + setObject(ShaderOffset const& offset, IShaderObject* object) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL + setResource(ShaderOffset const& offset, IResourceView* resourceView) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL + setSampler(ShaderOffset const& offset, ISamplerState* sampler) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler( + ShaderOffset const& offset, IResourceView* textureView, ISamplerState* sampler) = 0; +}; +#define SLANG_UUID_IShaderObject \ + { \ + 0xc1fa997e, 0x5ca2, 0x45ae, { 0x9b, 0xcb, 0xc4, 0x35, 0x9e, 0x85, 0x5, 0x85 } \ + } + + +enum class StencilOp : uint8_t +{ + Keep, + Zero, + Replace, + IncrementSaturate, + DecrementSaturate, + Invert, + IncrementWrap, + DecrementWrap, +}; + +enum class FillMode : uint8_t +{ + Solid, + Wireframe, +}; + +enum class CullMode : uint8_t +{ + None, + Front, + Back, +}; + +enum class FrontFaceMode : uint8_t +{ + CounterClockwise, + Clockwise, +}; + +struct DepthStencilOpDesc +{ + StencilOp stencilFailOp = StencilOp::Keep; + StencilOp stencilDepthFailOp = StencilOp::Keep; + StencilOp stencilPassOp = StencilOp::Keep; + ComparisonFunc stencilFunc = ComparisonFunc::Always; +}; + +struct DepthStencilDesc +{ + bool depthTestEnable = true; + bool depthWriteEnable = true; + ComparisonFunc depthFunc = ComparisonFunc::Less; + + bool stencilEnable = false; + uint32_t stencilReadMask = 0xFFFFFFFF; + uint32_t stencilWriteMask = 0xFFFFFFFF; + DepthStencilOpDesc frontFace; + DepthStencilOpDesc backFace; + + uint32_t stencilRef = 0; +}; + +struct RasterizerDesc +{ + FillMode fillMode = FillMode::Solid; + CullMode cullMode = CullMode::Back; + FrontFaceMode frontFace = FrontFaceMode::CounterClockwise; + int32_t depthBias = 0; + float depthBiasClamp = 0.0f; + float slopeScaledDepthBias = 0.0f; + bool depthClipEnable = true; + bool scissorEnable = false; + bool multisampleEnable = false; + bool antialiasedLineEnable = false; +}; + +enum class LogicOp +{ + NoOp, +}; + +enum class BlendOp +{ + Add, + Subtract, + ReverseSubtract, + Min, + Max, +}; + +enum class BlendFactor +{ + Zero, + One, + SrcColor, + InvSrcColor, + SrcAlpha, + InvSrcAlpha, + DestAlpha, + InvDestAlpha, + DestColor, + InvDestColor, + SrcAlphaSaturate, + BlendColor, + InvBlendColor, + SecondarySrcColor, + InvSecondarySrcColor, + SecondarySrcAlpha, + InvSecondarySrcAlpha, +}; + +namespace RenderTargetWriteMask +{ + typedef uint8_t Type; + enum + { + EnableNone = 0, + EnableRed = 0x01, + EnableGreen = 0x02, + EnableBlue = 0x04, + EnableAlpha = 0x08, + EnableAll = 0x0F, + }; +}; +typedef RenderTargetWriteMask::Type RenderTargetWriteMaskT; + +struct AspectBlendDesc +{ + BlendFactor srcFactor = BlendFactor::One; + BlendFactor dstFactor = BlendFactor::Zero; + BlendOp op = BlendOp::Add; +}; + +struct TargetBlendDesc +{ + AspectBlendDesc color; + AspectBlendDesc alpha; + + LogicOp logicOp = LogicOp::NoOp; + RenderTargetWriteMaskT writeMask = RenderTargetWriteMask::EnableAll; +}; + +struct BlendDesc +{ + TargetBlendDesc const* targets = nullptr; + UInt targetCount = 0; + + bool alphaToCoverateEnable = false; +}; + +struct GraphicsPipelineStateDesc +{ + IShaderProgram* program; + + // If `pipelineLayout` is null, then layout information will be extracted + // from `program`, which must have been created with Slang reflection info. + IPipelineLayout* pipelineLayout = nullptr; + + IInputLayout* inputLayout; + UInt renderTargetCount = 0; // Only used if `pipelineLayout` is non-null + DepthStencilDesc depthStencil; + RasterizerDesc rasterizer; + BlendDesc blend; +}; + +struct ComputePipelineStateDesc +{ + IShaderProgram* program; + + // If `pipelineLayout` is null, then layout information will be extracted + // from `program`, which must have been created with Slang reflection info. + IPipelineLayout* pipelineLayout = nullptr; +}; + +class IPipelineState : public ISlangUnknown +{ +}; +#define SLANG_UUID_IPipelineState \ + { \ + 0xca7e57d, 0x8a90, 0x44f3, { 0xbd, 0xb1, 0xfe, 0x9b, 0x35, 0x3f, 0x5a, 0x72 } \ + } + + +struct ScissorRect +{ + Int minX; + Int minY; + Int maxX; + Int maxY; +}; + +struct Viewport +{ + float originX = 0.0f; + float originY = 0.0f; + float extentX = 0.0f; + float extentY = 0.0f; + float minZ = 0.0f; + float maxZ = 1.0f; +}; + +class IRenderer: public ISlangUnknown +{ +public: + struct SlangDesc + { + slang::IGlobalSession* slangGlobalSession = nullptr; // (optional) A slang global session object. If null will create automatically. + + SlangMatrixLayoutMode defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_ROW_MAJOR; + + char const* const* searchPaths = nullptr; + SlangInt searchPathCount = 0; + + slang::PreprocessorMacroDesc const* preprocessorMacros = nullptr; + SlangInt preprocessorMacroCount = 0; + + const char* targetProfile = nullptr; // (optional) Target shader profile. If null this will be set to platform dependent default. + SlangFloatingPointMode floatingPointMode = SLANG_FLOATING_POINT_MODE_DEFAULT; + SlangOptimizationLevel optimizationLevel = SLANG_OPTIMIZATION_LEVEL_DEFAULT; + }; + + struct Desc + { + RendererType rendererType; // The underlying API/Platform of the renderer. + int width = 0; // Width in pixels + int height = 0; // height in pixels + const char* adapter = nullptr; // Name to identify the adapter to use + int requiredFeatureCount = 0; // Number of required features. + const char** requiredFeatures = nullptr; // Array of required feature names, whose size is `requiredFeatureCount`. + int nvapiExtnSlot = -1; // The slot (typically UAV) used to identify NVAPI intrinsics. If >=0 NVAPI is required. + ISlangFileSystem* shaderCacheFileSystem = nullptr; // The file system for loading cached shader kernels. + SlangDesc slang = {}; // Configurations for Slang. + }; + + virtual SLANG_NO_THROW bool SLANG_MCALL hasFeature(const char* feature) = 0; + + /// Returns a list of features supported by the renderer. + virtual SLANG_NO_THROW Result SLANG_MCALL getFeatures(const char** outFeatures, UInt bufferSize, UInt* outFeatureCount) = 0; + + virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) = 0; + + inline ComPtr getSlangSession() + { + ComPtr result; + getSlangSession(result.writeRef()); + return result; + } + + virtual SLANG_NO_THROW void SLANG_MCALL setClearColor(const float color[4]) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL clearFrame() = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL presentFrame() = 0; + + virtual SLANG_NO_THROW ITextureResource::Desc SLANG_MCALL getSwapChainTextureDesc() = 0; + + /// Create a texture resource. initData holds the initialize data to set the contents of the texture when constructed. + virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( + IResource::Usage initialUsage, + const ITextureResource::Desc& desc, + const ITextureResource::Data* initData, + ITextureResource** outResource) = 0; + + /// Create a texture resource. initData holds the initialize data to set the contents of the texture when constructed. + inline SLANG_NO_THROW ComPtr createTextureResource( + IResource::Usage initialUsage, + const ITextureResource::Desc& desc, + const ITextureResource::Data* initData = nullptr) + { + ComPtr resource; + SLANG_RETURN_NULL_ON_FAIL(createTextureResource(initialUsage, desc, initData, resource.writeRef())); + return resource; + } + + /// Create a buffer resource + virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( + IResource::Usage initialUsage, + const IBufferResource::Desc& desc, + const void* initData, + IBufferResource** outResource) = 0; + + inline SLANG_NO_THROW ComPtr createBufferResource( + IResource::Usage initialUsage, + const IBufferResource::Desc& desc, + const void* initData = nullptr) + { + ComPtr resource; + SLANG_RETURN_NULL_ON_FAIL(createBufferResource(initialUsage, desc, initData, resource.writeRef())); + return resource; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL + createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) = 0; + + inline ComPtr createSamplerState(ISamplerState::Desc const& desc) + { + ComPtr sampler; + SLANG_RETURN_NULL_ON_FAIL(createSamplerState(desc, sampler.writeRef())); + return sampler; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createTextureView( + ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) = 0; + + inline ComPtr createTextureView(ITextureResource* texture, IResourceView::Desc const& desc) + { + ComPtr view; + SLANG_RETURN_NULL_ON_FAIL(createTextureView(texture, desc, view.writeRef())); + return view; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createBufferView( + IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) = 0; + + inline ComPtr createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc) + { + ComPtr view; + SLANG_RETURN_NULL_ON_FAIL(createBufferView(buffer, desc, view.writeRef())); + return view; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout( + const InputElementDesc* inputElements, UInt inputElementCount, IInputLayout** outLayout) = 0; + + inline ComPtr createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) + { + ComPtr layout; + SLANG_RETURN_NULL_ON_FAIL(createInputLayout(inputElements, inputElementCount, layout.writeRef())); + return layout; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createDescriptorSetLayout( + const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) = 0; + + inline ComPtr createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc) + { + ComPtr layout; + SLANG_RETURN_NULL_ON_FAIL(createDescriptorSetLayout(desc, layout.writeRef())); + return layout; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(slang::TypeReflection* type, IShaderObject** outObject) = 0; + + inline ComPtr createShaderObject(slang::TypeReflection* type) + { + ComPtr object; + SLANG_RETURN_NULL_ON_FAIL(createShaderObject(type, object.writeRef())); + return object; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObject(IShaderProgram* program, IShaderObject** outObject) = 0; + + inline ComPtr createRootShaderObject(IShaderProgram* program) + { + ComPtr object; + SLANG_RETURN_NULL_ON_FAIL(createRootShaderObject(program, object.writeRef())); + return object; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL bindRootShaderObject(PipelineType pipelineType, IShaderObject* object) = 0; + + virtual SLANG_NO_THROW Result SLANG_MCALL createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) = 0; + + inline ComPtr createPipelineLayout(const IPipelineLayout::Desc& desc) + { + ComPtr layout; + SLANG_RETURN_NULL_ON_FAIL(createPipelineLayout(desc, layout.writeRef())); + return layout; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createDescriptorSet(IDescriptorSetLayout* layout, IDescriptorSet** outDescriptorSet) = 0; + + inline ComPtr createDescriptorSet(IDescriptorSetLayout* layout) + { + ComPtr descriptorSet; + SLANG_RETURN_NULL_ON_FAIL(createDescriptorSet(layout, descriptorSet.writeRef())); + return descriptorSet; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) = 0; + + inline ComPtr createProgram(const IShaderProgram::Desc& desc) + { + ComPtr program; + SLANG_RETURN_NULL_ON_FAIL(createProgram(desc, program.writeRef())); + return program; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createGraphicsPipelineState( + const GraphicsPipelineStateDesc& desc, + IPipelineState** outState) = 0; + + inline ComPtr createGraphicsPipelineState( + const GraphicsPipelineStateDesc& desc) + { + ComPtr state; + SLANG_RETURN_NULL_ON_FAIL(createGraphicsPipelineState(desc, state.writeRef())); + return state; + } + + virtual SLANG_NO_THROW Result SLANG_MCALL createComputePipelineState( + const ComputePipelineStateDesc& desc, + IPipelineState** outState) = 0; + + inline ComPtr createComputePipelineState( + const ComputePipelineStateDesc& desc) + { + ComPtr state; + SLANG_RETURN_NULL_ON_FAIL(createComputePipelineState(desc, state.writeRef())); + return state; + } + + /// Captures the back buffer and stores the result in surfaceOut. If the surface contains data - it will either be overwritten (if same size and format), or freed and a re-allocated. + virtual SLANG_NO_THROW SlangResult SLANG_MCALL captureScreenSurface(void* buffer, size_t *inOutBufferSize, size_t* outRowPitch, size_t* outPixelSize) = 0; + + virtual SLANG_NO_THROW void* SLANG_MCALL map(IBufferResource* buffer, MapFlavor flavor) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL unmap(IBufferResource* buffer) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL setPrimitiveTopology(PrimitiveTopology topology) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL setDescriptorSet( + PipelineType pipelineType, + IPipelineLayout* layout, + UInt index, + IDescriptorSet* descriptorSet) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL setVertexBuffers( + UInt startSlot, + UInt slotCount, + IBufferResource* const* buffers, + const UInt* strides, + const UInt* offsets) = 0; + inline void setVertexBuffer(UInt slot, IBufferResource* buffer, UInt stride, UInt offset = 0); + + virtual SLANG_NO_THROW void SLANG_MCALL + setIndexBuffer(IBufferResource* buffer, Format indexFormat, UInt offset = 0) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL setDepthStencilTarget(IResourceView* depthStencilView) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL setViewports(UInt count, Viewport const* viewports) = 0; + inline void setViewport(Viewport const& viewport) + { + setViewports(1, &viewport); + } + + virtual SLANG_NO_THROW void SLANG_MCALL setScissorRects(UInt count, ScissorRect const* rects) = 0; + inline void setScissorRect(ScissorRect const& rect) + { + setScissorRects(1, &rect); + } + + virtual SLANG_NO_THROW void SLANG_MCALL setPipelineState(IPipelineState* state) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL draw(UInt vertexCount, UInt startVertex = 0) = 0; + virtual SLANG_NO_THROW void SLANG_MCALL drawIndexed(UInt indexCount, UInt startIndex = 0, UInt baseVertex = 0) = 0; + + virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) = 0; + + /// Commit any buffered state changes or draw calls. + /// presentFrame will commitAll implicitly before doing a present + virtual SLANG_NO_THROW void SLANG_MCALL submitGpuWork() = 0; + /// Blocks until Gpu work is complete + virtual SLANG_NO_THROW void SLANG_MCALL waitForGpu() = 0; + + /// Get the type of this renderer + virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const = 0; +}; + +#define SLANG_UUID_IRenderer \ + { \ + 0x715bdf26, 0x5135, 0x11eb, { 0xAE, 0x93, 0x02, 0x42, 0xAC, 0x13, 0x00, 0x02 } \ + } + +// ---------------------------------------------------------------------------------------- +inline void IRenderer::setVertexBuffer(UInt slot, IBufferResource* buffer, UInt stride, UInt offset) +{ + setVertexBuffers(slot, 1, &buffer, &stride, &offset); +} + +// Global public functions + +extern "C" +{ + /// Gets the size in bytes of a Format type. Returns 0 if a size is not defined/invalid + SLANG_GFX_API size_t SLANG_MCALL gfxGetFormatSize(Format format); + + /// Gets the binding style from the type + SLANG_GFX_API BindingStyle SLANG_MCALL gfxGetBindingStyle(RendererType type); + + /// Given a renderer type, gets a projection style + SLANG_GFX_API ProjectionStyle SLANG_MCALL gfxGetProjectionStyle(RendererType type); + + /// Given the projection style returns an 'identity' matrix, which ensures x,y mapping to pixels + /// is the same on all targets + SLANG_GFX_API void SLANG_MCALL + gfxGetIdentityProjection(ProjectionStyle style, float projMatrix[16]); + + /// Get the name of the renderer + SLANG_GFX_API const char* SLANG_MCALL gfxGetRendererName(RendererType type); + + /// Given a type returns a function that can construct it, or nullptr if there isn't one + SLANG_GFX_API SlangResult SLANG_MCALL gfxCreateRenderer(const IRenderer::Desc* desc, void* windowHandle, IRenderer** outRenderer); +} + +}// renderer_test diff --git a/tools/gfx-util/shader-cursor.h b/tools/gfx-util/shader-cursor.h index 04dddc3aa..24008cf24 100644 --- a/tools/gfx-util/shader-cursor.h +++ b/tools/gfx-util/shader-cursor.h @@ -1,6 +1,6 @@ #pragma once -#include "tools/gfx/render.h" +#include "slang-gfx.h" namespace gfx { diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index a64c354b5..4673cda6e 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -1358,7 +1358,7 @@ private: return SLANG_OK; } - virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject( + virtual Result createShaderObject( ShaderObjectLayoutBase* layout, IShaderObject** outObject) override { diff --git a/tools/gfx/d3d/d3d-util.h b/tools/gfx/d3d/d3d-util.h index 69d42418e..63a897206 100644 --- a/tools/gfx/d3d/d3d-util.h +++ b/tools/gfx/d3d/d3d-util.h @@ -10,7 +10,7 @@ #include "../flag-combiner.h" -#include "../render.h" +#include "slang-gfx.h" #include #include diff --git a/tools/gfx/render.h b/tools/gfx/render.h deleted file mode 100644 index 7b77650e8..000000000 --- a/tools/gfx/render.h +++ /dev/null @@ -1,1378 +0,0 @@ -// render.h -#pragma once - -#include -#include - -#include "slang.h" -#include "slang-com-ptr.h" -#include "slang-com-helper.h" - - -#if defined(SLANG_GFX_DYNAMIC) -# if defined(_MSC_VER) -# ifdef SLANG_GFX_DYNAMIC_EXPORT -# define SLANG_GFX_API SLANG_DLL_EXPORT -# else -# define SLANG_GFX_API __declspec(dllimport) -# endif -# else -// TODO: need to consider compiler capabilities -//# ifdef SLANG_DYNAMIC_EXPORT -# define SLANG_GFX_API SLANG_DLL_EXPORT -//# endif -# endif -#endif - -#ifndef SLANG_GFX_API -# define SLANG_GFX_API -#endif - -namespace gfx { - -using Slang::ComPtr; - -typedef SlangResult Result; - -// Had to move here, because Options needs types defined here -typedef SlangInt Int; -typedef SlangUInt UInt; - -// Declare opaque type -class IInputLayout: public ISlangUnknown -{ -}; -#define SLANG_UUID_IInputLayout \ - { \ - 0x45223711, 0xa84b, 0x455c, { 0xbe, 0xfa, 0x49, 0x37, 0x42, 0x1e, 0x8e, 0x2e } \ - } - -enum class PipelineType -{ - Unknown, - Graphics, - Compute, - RayTracing, - CountOf, -}; - -enum class StageType -{ - Unknown, - Vertex, - Hull, - Domain, - Geometry, - Fragment, - Compute, - RayGeneration, - Intersection, - AnyHit, - ClosestHit, - Miss, - Callable, - Amplification, - Mesh, - CountOf, -}; - -enum class RendererType -{ - Unknown, - DirectX11, - DirectX12, - OpenGl, - Vulkan, - CPU, - CUDA, - CountOf, -}; - -enum class ProjectionStyle -{ - Unknown, - OpenGl, - DirectX, - Vulkan, - CountOf, -}; - -/// The style of the binding -enum class BindingStyle -{ - Unknown, - DirectX, - OpenGl, - Vulkan, - CPU, - CUDA, - CountOf, -}; - -class IShaderProgram: public ISlangUnknown -{ -public: - - struct KernelDesc - { - StageType stage; - void const* codeBegin; - void const* codeEnd; - char const* entryPointName; - - UInt getCodeSize() const { return (char const*)codeEnd - (char const*)codeBegin; } - }; - - struct Desc - { - PipelineType pipelineType; - - KernelDesc const* kernels; - Int kernelCount; - - /// Use instead of `kernels`/`kernelCount` if loading a Slang program. - slang::IComponentType* slangProgram; - - /// Find and return the kernel for `stage`, if present. - KernelDesc const* findKernel(StageType stage) const - { - for(Int ii = 0; ii < kernelCount; ++ii) - if(kernels[ii].stage == stage) - return &kernels[ii]; - return nullptr; - } - }; -}; -#define SLANG_UUID_IShaderProgram \ - { \ - 0x9d32d0ad, 0x915c, 0x4ffd, { 0x91, 0xe2, 0x50, 0x85, 0x54, 0xa0, 0x4a, 0x76 } \ - } - -/// Different formats of things like pixels or elements of vertices -/// NOTE! Any change to this type (adding, removing, changing order) - must also be reflected in changes to RendererUtil -enum class Format -{ - Unknown, - - RGBA_Float32, - RGB_Float32, - RG_Float32, - R_Float32, - - RGBA_Unorm_UInt8, - - R_UInt16, - R_UInt32, - - D_Float32, - D_Unorm24_S8, - - CountOf, -}; - -struct InputElementDesc -{ - char const* semanticName; - UInt semanticIndex; - Format format; - UInt offset; -}; - -enum class MapFlavor -{ - Unknown, ///< Unknown mapping type - HostRead, - HostWrite, - WriteDiscard, -}; - -enum class PrimitiveTopology -{ - TriangleList, -}; - -class IResource: public ISlangUnknown -{ -public: - /// The type of resource. - /// NOTE! The order needs to be such that all texture types are at or after Texture1D (otherwise isTexture won't work correctly) - enum class Type - { - Unknown, ///< Unknown - Buffer, ///< A buffer (like a constant/index/vertex buffer) - Texture1D, ///< A 1d texture - Texture2D, ///< A 2d texture - Texture3D, ///< A 3d texture - TextureCube, ///< A cubemap consists of 6 Texture2D like faces - CountOf, - }; - - /// Describes how a resource is to be used - enum class Usage - { - Unknown = -1, - VertexBuffer = 0, - IndexBuffer, - ConstantBuffer, - StreamOutput, - RenderTarget, - DepthRead, - DepthWrite, - UnorderedAccess, - PixelShaderResource, - NonPixelShaderResource, - GenericRead, - CountOf, - }; - - /// Binding flags describe all of the ways a resource can be bound - and therefore used - struct BindFlag - { - enum Enum - { - VertexBuffer = 0x001, - IndexBuffer = 0x002, - ConstantBuffer = 0x004, - StreamOutput = 0x008, - RenderTarget = 0x010, - DepthStencil = 0x020, - UnorderedAccess = 0x040, - PixelShaderResource = 0x080, - NonPixelShaderResource = 0x100, - }; - }; - - /// Combinations describe how a resource can be accessed (typically by the host/cpu) - struct AccessFlag - { - enum Enum - { - Read = 0x1, - Write = 0x2 - }; - }; - - /// Base class for Descs - struct DescBase - { - bool canBind(BindFlag::Enum bindFlag) const { return (bindFlags & bindFlag) != 0; } - bool hasCpuAccessFlag(AccessFlag::Enum accessFlag) { return (cpuAccessFlags & accessFlag) != 0; } - - Type type = Type::Unknown; - - int bindFlags = 0; ///< Combination of Resource::BindFlag or 0 (and will use initialUsage to set) - int cpuAccessFlags = 0; ///< Combination of Resource::AccessFlag - }; - - inline static BindFlag::Enum getDefaultBindFlagsFromUsage(IResource::Usage usage) - { - switch (usage) - { - case Usage::VertexBuffer: - return BindFlag::VertexBuffer; - case Usage::IndexBuffer: - return BindFlag::IndexBuffer; - case Usage::ConstantBuffer: - return BindFlag::ConstantBuffer; - case Usage::StreamOutput: - return BindFlag::StreamOutput; - case Usage::RenderTarget: - return BindFlag::RenderTarget; - case Usage::DepthRead: - case Usage::DepthWrite: - return BindFlag::DepthStencil; - case Usage::UnorderedAccess: - return BindFlag::Enum(BindFlag::UnorderedAccess | BindFlag::PixelShaderResource | - BindFlag::NonPixelShaderResource); - case Usage::PixelShaderResource: - return BindFlag::PixelShaderResource; - case Usage::NonPixelShaderResource: - return BindFlag::NonPixelShaderResource; - case Usage::GenericRead: - return BindFlag::Enum( - BindFlag::PixelShaderResource | - BindFlag::NonPixelShaderResource); - default: - return BindFlag::Enum(-1); - } - } - - virtual SLANG_NO_THROW Type SLANG_MCALL getType() = 0; -}; -#define SLANG_UUID_IResource \ - { \ - 0xa0e39f34, 0x8398, 0x4522, { 0x95, 0xc2, 0xeb, 0xc0, 0xf9, 0x84, 0xef, 0x3f } \ - } - -class IBufferResource: public IResource -{ -public: - struct Desc: public DescBase - { - void init(size_t sizeInBytesIn) - { - sizeInBytes = sizeInBytesIn; - elementSize = 0; - format = Format::Unknown; - } - void setDefaults(Usage initialUsage) - { - if (bindFlags == 0) - { - bindFlags = getDefaultBindFlagsFromUsage(initialUsage); - } - } - size_t sizeInBytes; ///< Total size in bytes - int elementSize; ///< Get the element stride. If > 0, this is a structured buffer - Format format; - }; - virtual SLANG_NO_THROW Desc* SLANG_MCALL getDesc() = 0; -}; -#define SLANG_UUID_IBufferResource \ - { \ - 0x1b274efe, 0x5e37, 0x492b, { 0x82, 0x6e, 0x7e, 0xe7, 0xe8, 0xf5, 0xa4, 0x9b } \ - } - -template T _slang_gfx_max(T v0, T v1) { return v0 > v1 ? v0 : v1; } - -static inline unsigned int _slang_gfx_ones32(unsigned int x) -{ - /* 32-bit recursive reduction using SWAR... - but first step is mapping 2-bit values - into sum of 2 1-bit values in sneaky way - */ - x -= ((x >> 1) & 0x55555555); - x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); - x = (((x >> 4) + x) & 0x0f0f0f0f); - x += (x >> 8); - x += (x >> 16); - return (x & 0x0000003f); -} - -static inline unsigned int _slang_gfx_log2Floor(unsigned int x) -{ - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - return (_slang_gfx_ones32(x >> 1)); -} - -class ITextureResource: public IResource -{ -public: - struct SampleDesc - { - void init() - { - numSamples = 1; - quality = 0; - } - int numSamples; ///< Number of samples per pixel - int quality; ///< The quality measure for the samples - }; - - struct Size - { - void init() - { - width = height = depth = 1; - } - void init(int widthIn, int heightIn = 1, int depthIn = 1) - { - width = widthIn; - height = heightIn; - depth = depthIn; - } - /// Given the type works out the maximum dimension size - int calcMaxDimension(Type type) const - { - switch (type) - { - case IResource::Type::Texture1D: - return this->width; - case IResource::Type::Texture3D: - return _slang_gfx_max(_slang_gfx_max(this->width, this->height), this->depth); - case IResource::Type::TextureCube: // fallthru - case IResource::Type::Texture2D: - { - return _slang_gfx_max(this->width, this->height); - } - default: - return 0; - } - } - - SLANG_FORCE_INLINE static int calcMipSize(int width, int mipLevel) - { - width = width >> mipLevel; - return width > 0 ? width : 1; - } - /// Given a size, calculates the size at a mip level - Size calcMipSize(int mipLevel) const - { - Size size; - size.width = calcMipSize(this->width, mipLevel); - size.height = calcMipSize(this->height, mipLevel); - size.depth = calcMipSize(this->depth, mipLevel); - return size; - } - - int width; ///< Width in pixels - int height; ///< Height in pixels (if 2d or 3d) - int depth; ///< Depth (if 3d) - }; - - struct Desc: public DescBase - { - /// Initialize with default values - void init(Type typeIn) - { - this->type = typeIn; - this->size.init(); - - this->format = Format::Unknown; - this->arraySize = 0; - this->numMipLevels = 0; - this->sampleDesc.init(); - - this->bindFlags = 0; - this->cpuAccessFlags = 0; - } - /// Initialize different dimensions. For cubemap, use init2D - void init1D(Format formatIn, int widthIn, int numMipMapsIn = 0) - { - this->type = Type::Texture1D; - this->size.init(widthIn); - - this->format = formatIn; - this->arraySize = 0; - this->numMipLevels = numMipMapsIn; - this->sampleDesc.init(); - - this->bindFlags = 0; - this->cpuAccessFlags = 0; - } - - void init2D(Type typeIn, Format formatIn, int widthIn, int heightIn, int numMipMapsIn = 0) - { - assert(typeIn == Type::Texture2D || typeIn == Type::TextureCube); - - this->type = typeIn; - this->size.init(widthIn, heightIn); - - this->format = formatIn; - this->arraySize = 0; - this->numMipLevels = numMipMapsIn; - this->sampleDesc.init(); - - this->bindFlags = 0; - this->cpuAccessFlags = 0; - } - - void init3D(Format formatIn, int widthIn, int heightIn, int depthIn, int numMipMapsIn = 0) - { - this->type = Type::Texture3D; - this->size.init(widthIn, heightIn, depthIn); - - this->format = formatIn; - this->arraySize = 0; - this->numMipLevels = numMipMapsIn; - this->sampleDesc.init(); - - this->bindFlags = 0; - this->cpuAccessFlags = 0; - } - - /// Given the type, calculates the number of mip maps. 0 on error - int calcNumMipLevels() const - { - const int maxDimensionSize = this->size.calcMaxDimension(type); - return (maxDimensionSize > 0) ? (_slang_gfx_log2Floor(maxDimensionSize) + 1) : 0; - } - /// Calculate the total number of sub resources. 0 on error. - int calcNumSubResources() const - { - const int numMipMaps = - (this->numMipLevels > 0) ? this->numMipLevels : calcNumMipLevels(); - const int arrSize = (this->arraySize > 0) ? this->arraySize : 1; - - switch (type) - { - case IResource::Type::Texture1D: - case IResource::Type::Texture2D: - { - return numMipMaps * arrSize; - } - case IResource::Type::Texture3D: - { - // can't have arrays of 3d textures - assert(this->arraySize <= 1); - return numMipMaps * this->size.depth; - } - case IResource::Type::TextureCube: - { - // There are 6 faces to a cubemap - return numMipMaps * arrSize * 6; - } - default: - return 0; - } - } - - /// Calculate the effective array size - in essence the amount if mip map sets needed. - /// In practice takes into account if the arraySize is 0 (it's not an array, but it will still have at least one mip set) - /// and if the type is a cubemap (multiplies the amount of mip sets by 6) - int calcEffectiveArraySize() const - { - const int arrSize = (this->arraySize > 0) ? this->arraySize : 1; - - switch (type) - { - case IResource::Type::Texture1D: // fallthru - case IResource::Type::Texture2D: - { - return arrSize; - } - case IResource::Type::TextureCube: - return arrSize * 6; - case IResource::Type::Texture3D: - return 1; - default: - return 0; - } - } - - /// Use type to fix the size values (and array size). - /// For example a 1d texture, should have height and depth set to 1. - void fixSize() - { - switch (type) - { - case IResource::Type::Texture1D: - { - this->size.height = 1; - this->size.depth = 1; - break; - } - case IResource::Type::TextureCube: - case IResource::Type::Texture2D: - { - this->size.depth = 1; - break; - } - case IResource::Type::Texture3D: - { - // Can't have an array - this->arraySize = 0; - break; - } - default: - break; - } - } - - /// Set up default parameters based on type and usage - void setDefaults(Usage initialUsage) - { - fixSize(); - if (this->bindFlags == 0) - { - this->bindFlags = getDefaultBindFlagsFromUsage(initialUsage); - } - if (this->numMipLevels <= 0) - { - this->numMipLevels = calcNumMipLevels(); - } - } - - Size size; - - int arraySize; ///< Array size - - int numMipLevels; ///< Number of mip levels - if 0 will create all mip levels - Format format; ///< The resources format - SampleDesc sampleDesc; ///< How the resource is sampled - }; - - /// The ordering of the subResources is - /// forall (effectiveArraySize) - /// forall (mip levels) - /// forall (depth levels) - struct Data - { - ptrdiff_t* mipRowStrides; ///< The row stride for a mip map - int numMips; ///< The number of mip maps - const void*const* subResources; ///< Pointers to each full mip subResource - int numSubResources; ///< The total amount of subResources. Typically = numMips * depth * arraySize - }; - - virtual SLANG_NO_THROW Desc* SLANG_MCALL getDesc() = 0; -}; -#define SLANG_UUID_ITextureResource \ - { \ - 0xcf88a31c, 0x6187, 0x46c5, { 0xa4, 0xb7, 0xeb, 0x58, 0xc7, 0x33, 0x40, 0x17 } \ - } - -// Needed for building on cygwin with gcc -#undef Always -#undef None - -enum class ComparisonFunc : uint8_t -{ - Never = 0, - Less = 0x01, - Equal = 0x02, - LessEqual = 0x03, - Greater = 0x04, - NotEqual = 0x05, - GreaterEqual = 0x06, - Always = 0x07, -}; - -enum class TextureFilteringMode -{ - Point, - Linear, -}; - -enum class TextureAddressingMode -{ - Wrap, - ClampToEdge, - ClampToBorder, - MirrorRepeat, - MirrorOnce, -}; - -enum class TextureReductionOp -{ - Average, - Comparison, - Minimum, - Maximum, -}; - -class ISamplerState : public ISlangUnknown -{ -public: - struct Desc - { - TextureFilteringMode minFilter = TextureFilteringMode::Linear; - TextureFilteringMode magFilter = TextureFilteringMode::Linear; - TextureFilteringMode mipFilter = TextureFilteringMode::Linear; - TextureReductionOp reductionOp = TextureReductionOp::Average; - TextureAddressingMode addressU = TextureAddressingMode::Wrap; - TextureAddressingMode addressV = TextureAddressingMode::Wrap; - TextureAddressingMode addressW = TextureAddressingMode::Wrap; - float mipLODBias = 0.0f; - uint32_t maxAnisotropy = 1; - ComparisonFunc comparisonFunc = ComparisonFunc::Never; - float borderColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - float minLOD = -FLT_MAX; - float maxLOD = FLT_MAX; - }; -}; -#define SLANG_UUID_ISamplerState \ - { \ - 0x8b8055df, 0x9377, 0x401d, { 0x91, 0xff, 0x3f, 0xa3, 0xbf, 0x66, 0x64, 0xf4 } \ - } - - -enum class DescriptorSlotType -{ - Unknown, - - Sampler, - CombinedImageSampler, - SampledImage, - StorageImage, - UniformTexelBuffer, - StorageTexelBuffer, - UniformBuffer, - ReadOnlyStorageBuffer, - StorageBuffer, - DynamicUniformBuffer, - DynamicStorageBuffer, - InputAttachment, - RootConstant, - InlineUniformBlock, - RayTracingAccelerationStructure, -}; - -class IDescriptorSetLayout : public ISlangUnknown -{ -public: - struct SlotRangeDesc - { - DescriptorSlotType type = DescriptorSlotType::Unknown; - UInt count = 1; - - /// The underlying API-specific binding/register to use for this slot range. - /// - /// A value of `-1` indicates that the implementation should - /// automatically compute the binding/register to use - /// based on the preceeding slot range(s). - /// - /// Some implementations do not have a concept of bindings/regsiters - /// for slot ranges, and will ignore this field. - /// - Int binding = -1; - - SlotRangeDesc() - {} - - SlotRangeDesc( - DescriptorSlotType type, - UInt count = 1) - : type(type) - , count(count) - {} - }; - - struct Desc - { - UInt slotRangeCount = 0; - SlotRangeDesc const* slotRanges = nullptr; - }; -}; -#define SLANG_UUID_IDescriptorSetLayout \ - { \ - 0x9fe39a2f, 0xdf8b, 0x4690, { 0x90, 0x6a, 0x10, 0x1e, 0xed, 0xf9, 0xbe, 0xc0 } \ - } - - -class IPipelineLayout : public ISlangUnknown -{ -public: - struct DescriptorSetDesc - { - IDescriptorSetLayout* layout = nullptr; - - /// The underlying API-specific space/set number to use for this set. - /// - /// A value of `-1` indicates that the implementation should - /// automatically compute the space/set to use basd on - /// the preceeding set(s) - /// - /// Some implementations do not have a concept of space/set numbers - /// for descriptor sets, and will ignore this field. - /// - Int space = -1; - - DescriptorSetDesc() - {} - - DescriptorSetDesc( - IDescriptorSetLayout* layout) - : layout(layout) - {} - }; - - struct Desc - { - UInt renderTargetCount = 0; - UInt descriptorSetCount = 0; - DescriptorSetDesc const* descriptorSets = nullptr; - }; -}; -#define SLANG_UUID_IPipelineLayout \ - { \ - 0x9d644a9a, 0x3e6f, 0x4350, { 0xa3, 0x5a, 0xe8, 0xe3, 0xbc, 0xef, 0xb9, 0xcf } \ - } - -class IResourceView : public ISlangUnknown -{ -public: - enum class Type - { - Unknown, - - RenderTarget, - DepthStencil, - ShaderResource, - UnorderedAccess, - }; - - struct Desc - { - Type type; - Format format; - }; -}; -#define SLANG_UUID_IResourceView \ - { \ - 0x7b6c4926, 0x884, 0x408c, { 0xad, 0x8a, 0x50, 0x3a, 0x8e, 0x23, 0x98, 0xa4 } \ - } - - -class IDescriptorSet : public ISlangUnknown -{ -public: - virtual SLANG_NO_THROW void SLANG_MCALL setConstantBuffer(UInt range, UInt index, IBufferResource* buffer) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL - setResource(UInt range, UInt index, IResourceView* view) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL - setSampler(UInt range, UInt index, ISamplerState* sampler) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL setCombinedTextureSampler( - UInt range, - UInt index, - IResourceView* textureView, - ISamplerState* sampler) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL - setRootConstants( - UInt range, - UInt offset, - UInt size, - void const* data) = 0; -}; -#define SLANG_UUID_IDescriptorSet \ - { \ - 0x29a881ea, 0xd7, 0x41d4, { 0xa3, 0x2d, 0x6c, 0x78, 0x4b, 0x79, 0xda, 0x2e } \ - } - - -struct ShaderOffset -{ - SlangInt uniformOffset = 0; - SlangInt bindingRangeIndex = 0; - SlangInt bindingArrayIndex = 0; -}; - -class IShaderObject : public ISlangUnknown -{ -public: - SLANG_NO_THROW ComPtr SLANG_MCALL getObject(ShaderOffset const& offset) - { - ComPtr object = nullptr; - SLANG_RETURN_NULL_ON_FAIL(getObject(offset, object.writeRef())); - return object; - } - - virtual SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL getElementTypeLayout() = 0; - virtual SLANG_NO_THROW UInt SLANG_MCALL getEntryPointCount() = 0; - - ComPtr getEntryPoint(UInt index) - { - ComPtr entryPoint = nullptr; - SLANG_RETURN_NULL_ON_FAIL(getEntryPoint(index, entryPoint.writeRef())); - return entryPoint; - } - virtual SLANG_NO_THROW Result SLANG_MCALL - getEntryPoint(UInt index, IShaderObject** entryPoint) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL - setData(ShaderOffset const& offset, void const* data, size_t size) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL - getObject(ShaderOffset const& offset, IShaderObject** object) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL - setObject(ShaderOffset const& offset, IShaderObject* object) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL - setResource(ShaderOffset const& offset, IResourceView* resourceView) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL - setSampler(ShaderOffset const& offset, ISamplerState* sampler) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler( - ShaderOffset const& offset, IResourceView* textureView, ISamplerState* sampler) = 0; -}; -#define SLANG_UUID_IShaderObject \ - { \ - 0xc1fa997e, 0x5ca2, 0x45ae, { 0x9b, 0xcb, 0xc4, 0x35, 0x9e, 0x85, 0x5, 0x85 } \ - } - - -enum class StencilOp : uint8_t -{ - Keep, - Zero, - Replace, - IncrementSaturate, - DecrementSaturate, - Invert, - IncrementWrap, - DecrementWrap, -}; - -enum class FillMode : uint8_t -{ - Solid, - Wireframe, -}; - -enum class CullMode : uint8_t -{ - None, - Front, - Back, -}; - -enum class FrontFaceMode : uint8_t -{ - CounterClockwise, - Clockwise, -}; - -struct DepthStencilOpDesc -{ - StencilOp stencilFailOp = StencilOp::Keep; - StencilOp stencilDepthFailOp = StencilOp::Keep; - StencilOp stencilPassOp = StencilOp::Keep; - ComparisonFunc stencilFunc = ComparisonFunc::Always; -}; - -struct DepthStencilDesc -{ - bool depthTestEnable = true; - bool depthWriteEnable = true; - ComparisonFunc depthFunc = ComparisonFunc::Less; - - bool stencilEnable = false; - uint32_t stencilReadMask = 0xFFFFFFFF; - uint32_t stencilWriteMask = 0xFFFFFFFF; - DepthStencilOpDesc frontFace; - DepthStencilOpDesc backFace; - - uint32_t stencilRef = 0; -}; - -struct RasterizerDesc -{ - FillMode fillMode = FillMode::Solid; - CullMode cullMode = CullMode::Back; - FrontFaceMode frontFace = FrontFaceMode::CounterClockwise; - int32_t depthBias = 0; - float depthBiasClamp = 0.0f; - float slopeScaledDepthBias = 0.0f; - bool depthClipEnable = true; - bool scissorEnable = false; - bool multisampleEnable = false; - bool antialiasedLineEnable = false; -}; - -enum class LogicOp -{ - NoOp, -}; - -enum class BlendOp -{ - Add, - Subtract, - ReverseSubtract, - Min, - Max, -}; - -enum class BlendFactor -{ - Zero, - One, - SrcColor, - InvSrcColor, - SrcAlpha, - InvSrcAlpha, - DestAlpha, - InvDestAlpha, - DestColor, - InvDestColor, - SrcAlphaSaturate, - BlendColor, - InvBlendColor, - SecondarySrcColor, - InvSecondarySrcColor, - SecondarySrcAlpha, - InvSecondarySrcAlpha, -}; - -namespace RenderTargetWriteMask -{ - typedef uint8_t Type; - enum - { - EnableNone = 0, - EnableRed = 0x01, - EnableGreen = 0x02, - EnableBlue = 0x04, - EnableAlpha = 0x08, - EnableAll = 0x0F, - }; -}; -typedef RenderTargetWriteMask::Type RenderTargetWriteMaskT; - -struct AspectBlendDesc -{ - BlendFactor srcFactor = BlendFactor::One; - BlendFactor dstFactor = BlendFactor::Zero; - BlendOp op = BlendOp::Add; -}; - -struct TargetBlendDesc -{ - AspectBlendDesc color; - AspectBlendDesc alpha; - - LogicOp logicOp = LogicOp::NoOp; - RenderTargetWriteMaskT writeMask = RenderTargetWriteMask::EnableAll; -}; - -struct BlendDesc -{ - TargetBlendDesc const* targets = nullptr; - UInt targetCount = 0; - - bool alphaToCoverateEnable = false; -}; - -struct GraphicsPipelineStateDesc -{ - IShaderProgram* program; - - // If `pipelineLayout` is null, then layout information will be extracted - // from `program`, which must have been created with Slang reflection info. - IPipelineLayout* pipelineLayout = nullptr; - - IInputLayout* inputLayout; - UInt renderTargetCount = 0; // Only used if `pipelineLayout` is non-null - DepthStencilDesc depthStencil; - RasterizerDesc rasterizer; - BlendDesc blend; -}; - -struct ComputePipelineStateDesc -{ - IShaderProgram* program; - - // If `pipelineLayout` is null, then layout information will be extracted - // from `program`, which must have been created with Slang reflection info. - IPipelineLayout* pipelineLayout = nullptr; -}; - -class IPipelineState : public ISlangUnknown -{ -}; -#define SLANG_UUID_IPipelineState \ - { \ - 0xca7e57d, 0x8a90, 0x44f3, { 0xbd, 0xb1, 0xfe, 0x9b, 0x35, 0x3f, 0x5a, 0x72 } \ - } - - -struct ScissorRect -{ - Int minX; - Int minY; - Int maxX; - Int maxY; -}; - -struct Viewport -{ - float originX = 0.0f; - float originY = 0.0f; - float extentX = 0.0f; - float extentY = 0.0f; - float minZ = 0.0f; - float maxZ = 1.0f; -}; - -class IRenderer: public ISlangUnknown -{ -public: - struct SlangDesc - { - slang::IGlobalSession* slangGlobalSession = nullptr; // (optional) A slang global session object. If null will create automatically. - - SlangMatrixLayoutMode defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_ROW_MAJOR; - - char const* const* searchPaths = nullptr; - SlangInt searchPathCount = 0; - - slang::PreprocessorMacroDesc const* preprocessorMacros = nullptr; - SlangInt preprocessorMacroCount = 0; - - const char* targetProfile = nullptr; // (optional) Target shader profile. If null this will be set to platform dependent default. - SlangFloatingPointMode floatingPointMode = SLANG_FLOATING_POINT_MODE_DEFAULT; - SlangOptimizationLevel optimizationLevel = SLANG_OPTIMIZATION_LEVEL_DEFAULT; - }; - - struct Desc - { - RendererType rendererType; // The underlying API/Platform of the renderer. - int width = 0; // Width in pixels - int height = 0; // height in pixels - const char* adapter = nullptr; // Name to identify the adapter to use - int requiredFeatureCount = 0; // Number of required features. - const char** requiredFeatures = nullptr; // Array of required feature names, whose size is `requiredFeatureCount`. - int nvapiExtnSlot = -1; // The slot (typically UAV) used to identify NVAPI intrinsics. If >=0 NVAPI is required. - ISlangFileSystem* shaderCacheFileSystem = nullptr; // The file system for loading cached shader kernels. - SlangDesc slang = {}; // Configurations for Slang. - }; - - virtual SLANG_NO_THROW bool SLANG_MCALL hasFeature(const char* feature) = 0; - - /// Returns a list of features supported by the renderer. - virtual SLANG_NO_THROW Result SLANG_MCALL getFeatures(const char** outFeatures, UInt bufferSize, UInt* outFeatureCount) = 0; - - virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) = 0; - - inline ComPtr getSlangSession() - { - ComPtr result; - getSlangSession(result.writeRef()); - return result; - } - - virtual SLANG_NO_THROW void SLANG_MCALL setClearColor(const float color[4]) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL clearFrame() = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL presentFrame() = 0; - - virtual SLANG_NO_THROW ITextureResource::Desc SLANG_MCALL getSwapChainTextureDesc() = 0; - - /// Create a texture resource. initData holds the initialize data to set the contents of the texture when constructed. - virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource( - IResource::Usage initialUsage, - const ITextureResource::Desc& desc, - const ITextureResource::Data* initData, - ITextureResource** outResource) = 0; - - /// Create a texture resource. initData holds the initialize data to set the contents of the texture when constructed. - inline SLANG_NO_THROW ComPtr createTextureResource( - IResource::Usage initialUsage, - const ITextureResource::Desc& desc, - const ITextureResource::Data* initData = nullptr) - { - ComPtr resource; - SLANG_RETURN_NULL_ON_FAIL(createTextureResource(initialUsage, desc, initData, resource.writeRef())); - return resource; - } - - /// Create a buffer resource - virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource( - IResource::Usage initialUsage, - const IBufferResource::Desc& desc, - const void* initData, - IBufferResource** outResource) = 0; - - inline SLANG_NO_THROW ComPtr createBufferResource( - IResource::Usage initialUsage, - const IBufferResource::Desc& desc, - const void* initData = nullptr) - { - ComPtr resource; - SLANG_RETURN_NULL_ON_FAIL(createBufferResource(initialUsage, desc, initData, resource.writeRef())); - return resource; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL - createSamplerState(ISamplerState::Desc const& desc, ISamplerState** outSampler) = 0; - - inline ComPtr createSamplerState(ISamplerState::Desc const& desc) - { - ComPtr sampler; - SLANG_RETURN_NULL_ON_FAIL(createSamplerState(desc, sampler.writeRef())); - return sampler; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createTextureView( - ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) = 0; - - inline ComPtr createTextureView(ITextureResource* texture, IResourceView::Desc const& desc) - { - ComPtr view; - SLANG_RETURN_NULL_ON_FAIL(createTextureView(texture, desc, view.writeRef())); - return view; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createBufferView( - IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) = 0; - - inline ComPtr createBufferView(IBufferResource* buffer, IResourceView::Desc const& desc) - { - ComPtr view; - SLANG_RETURN_NULL_ON_FAIL(createBufferView(buffer, desc, view.writeRef())); - return view; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout( - const InputElementDesc* inputElements, UInt inputElementCount, IInputLayout** outLayout) = 0; - - inline ComPtr createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) - { - ComPtr layout; - SLANG_RETURN_NULL_ON_FAIL(createInputLayout(inputElements, inputElementCount, layout.writeRef())); - return layout; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createDescriptorSetLayout( - const IDescriptorSetLayout::Desc& desc, IDescriptorSetLayout** outLayout) = 0; - - inline ComPtr createDescriptorSetLayout(const IDescriptorSetLayout::Desc& desc) - { - ComPtr layout; - SLANG_RETURN_NULL_ON_FAIL(createDescriptorSetLayout(desc, layout.writeRef())); - return layout; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(slang::TypeReflection* type, IShaderObject** outObject) = 0; - - inline ComPtr createShaderObject(slang::TypeReflection* type) - { - ComPtr object; - SLANG_RETURN_NULL_ON_FAIL(createShaderObject(type, object.writeRef())); - return object; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObject(IShaderProgram* program, IShaderObject** outObject) = 0; - - inline ComPtr createRootShaderObject(IShaderProgram* program) - { - ComPtr object; - SLANG_RETURN_NULL_ON_FAIL(createRootShaderObject(program, object.writeRef())); - return object; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL bindRootShaderObject(PipelineType pipelineType, IShaderObject* object) = 0; - - virtual SLANG_NO_THROW Result SLANG_MCALL createPipelineLayout(const IPipelineLayout::Desc& desc, IPipelineLayout** outLayout) = 0; - - inline ComPtr createPipelineLayout(const IPipelineLayout::Desc& desc) - { - ComPtr layout; - SLANG_RETURN_NULL_ON_FAIL(createPipelineLayout(desc, layout.writeRef())); - return layout; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createDescriptorSet(IDescriptorSetLayout* layout, IDescriptorSet** outDescriptorSet) = 0; - - inline ComPtr createDescriptorSet(IDescriptorSetLayout* layout) - { - ComPtr descriptorSet; - SLANG_RETURN_NULL_ON_FAIL(createDescriptorSet(layout, descriptorSet.writeRef())); - return descriptorSet; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) = 0; - - inline ComPtr createProgram(const IShaderProgram::Desc& desc) - { - ComPtr program; - SLANG_RETURN_NULL_ON_FAIL(createProgram(desc, program.writeRef())); - return program; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createGraphicsPipelineState( - const GraphicsPipelineStateDesc& desc, - IPipelineState** outState) = 0; - - inline ComPtr createGraphicsPipelineState( - const GraphicsPipelineStateDesc& desc) - { - ComPtr state; - SLANG_RETURN_NULL_ON_FAIL(createGraphicsPipelineState(desc, state.writeRef())); - return state; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL createComputePipelineState( - const ComputePipelineStateDesc& desc, - IPipelineState** outState) = 0; - - inline ComPtr createComputePipelineState( - const ComputePipelineStateDesc& desc) - { - ComPtr state; - SLANG_RETURN_NULL_ON_FAIL(createComputePipelineState(desc, state.writeRef())); - return state; - } - - /// Captures the back buffer and stores the result in surfaceOut. If the surface contains data - it will either be overwritten (if same size and format), or freed and a re-allocated. - virtual SLANG_NO_THROW SlangResult SLANG_MCALL captureScreenSurface(void* buffer, size_t *inOutBufferSize, size_t* outRowPitch, size_t* outPixelSize) = 0; - - virtual SLANG_NO_THROW void* SLANG_MCALL map(IBufferResource* buffer, MapFlavor flavor) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL unmap(IBufferResource* buffer) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL setPrimitiveTopology(PrimitiveTopology topology) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL setDescriptorSet( - PipelineType pipelineType, - IPipelineLayout* layout, - UInt index, - IDescriptorSet* descriptorSet) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL setVertexBuffers( - UInt startSlot, - UInt slotCount, - IBufferResource* const* buffers, - const UInt* strides, - const UInt* offsets) = 0; - inline void setVertexBuffer(UInt slot, IBufferResource* buffer, UInt stride, UInt offset = 0); - - virtual SLANG_NO_THROW void SLANG_MCALL - setIndexBuffer(IBufferResource* buffer, Format indexFormat, UInt offset = 0) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL setDepthStencilTarget(IResourceView* depthStencilView) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL setViewports(UInt count, Viewport const* viewports) = 0; - inline void setViewport(Viewport const& viewport) - { - setViewports(1, &viewport); - } - - virtual SLANG_NO_THROW void SLANG_MCALL setScissorRects(UInt count, ScissorRect const* rects) = 0; - inline void setScissorRect(ScissorRect const& rect) - { - setScissorRects(1, &rect); - } - - virtual SLANG_NO_THROW void SLANG_MCALL setPipelineState(IPipelineState* state) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL draw(UInt vertexCount, UInt startVertex = 0) = 0; - virtual SLANG_NO_THROW void SLANG_MCALL drawIndexed(UInt indexCount, UInt startIndex = 0, UInt baseVertex = 0) = 0; - - virtual SLANG_NO_THROW void SLANG_MCALL dispatchCompute(int x, int y, int z) = 0; - - /// Commit any buffered state changes or draw calls. - /// presentFrame will commitAll implicitly before doing a present - virtual SLANG_NO_THROW void SLANG_MCALL submitGpuWork() = 0; - /// Blocks until Gpu work is complete - virtual SLANG_NO_THROW void SLANG_MCALL waitForGpu() = 0; - - /// Get the type of this renderer - virtual SLANG_NO_THROW RendererType SLANG_MCALL getRendererType() const = 0; -}; - -#define SLANG_UUID_IRenderer \ - { \ - 0x715bdf26, 0x5135, 0x11eb, { 0xAE, 0x93, 0x02, 0x42, 0xAC, 0x13, 0x00, 0x02 } \ - } - -// ---------------------------------------------------------------------------------------- -inline void IRenderer::setVertexBuffer(UInt slot, IBufferResource* buffer, UInt stride, UInt offset) -{ - setVertexBuffers(slot, 1, &buffer, &stride, &offset); -} - -// Global public functions - -extern "C" -{ - /// Gets the size in bytes of a Format type. Returns 0 if a size is not defined/invalid - SLANG_GFX_API size_t SLANG_MCALL gfxGetFormatSize(Format format); - - /// Gets the binding style from the type - SLANG_GFX_API BindingStyle SLANG_MCALL gfxGetBindingStyle(RendererType type); - - /// Given a renderer type, gets a projection style - SLANG_GFX_API ProjectionStyle SLANG_MCALL gfxGetProjectionStyle(RendererType type); - - /// Given the projection style returns an 'identity' matrix, which ensures x,y mapping to pixels - /// is the same on all targets - SLANG_GFX_API void SLANG_MCALL - gfxGetIdentityProjection(ProjectionStyle style, float projMatrix[16]); - - /// Get the name of the renderer - SLANG_GFX_API const char* SLANG_MCALL gfxGetRendererName(RendererType type); - - /// Given a type returns a function that can construct it, or nullptr if there isn't one - SLANG_GFX_API SlangResult SLANG_MCALL gfxCreateRenderer(const IRenderer::Desc* desc, void* windowHandle, IRenderer** outRenderer); -} - -}// renderer_test diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index 7b7a6d757..c9f2b3340 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -1,6 +1,6 @@ #pragma once -#include "tools/gfx/render.h" +#include "slang-gfx.h" #include "slang-context.h" #include "core/slang-basic.h" diff --git a/tools/gfx/slang-context.h b/tools/gfx/slang-context.h index e6168deed..909bcaa1c 100644 --- a/tools/gfx/slang-context.h +++ b/tools/gfx/slang-context.h @@ -1,6 +1,6 @@ #pragma once -#include "tools/gfx/render.h" +#include "slang-gfx.h" namespace gfx { diff --git a/tools/gfx/vulkan/vk-swap-chain.h b/tools/gfx/vulkan/vk-swap-chain.h index 893910ea6..e5162d63b 100644 --- a/tools/gfx/vulkan/vk-swap-chain.h +++ b/tools/gfx/vulkan/vk-swap-chain.h @@ -4,7 +4,7 @@ #include "vk-api.h" #include "vk-device-queue.h" -#include "../render.h" +#include "slang-gfx.h" #include "core/slang-list.h" diff --git a/tools/gfx/vulkan/vk-util.h b/tools/gfx/vulkan/vk-util.h index c8194789d..723c3fde5 100644 --- a/tools/gfx/vulkan/vk-util.h +++ b/tools/gfx/vulkan/vk-util.h @@ -2,7 +2,7 @@ #pragma once #include "vk-api.h" -#include "../render.h" +#include "slang-gfx.h" // Macros to make testing vulkan return codes simpler diff --git a/tools/graphics-app-framework/gui.h b/tools/graphics-app-framework/gui.h index 4fd1ca150..3ef2b0ba5 100644 --- a/tools/graphics-app-framework/gui.h +++ b/tools/graphics-app-framework/gui.h @@ -1,7 +1,7 @@ // gui.h #pragma once -#include "tools/gfx/render.h" +#include "slang-gfx.h" #include "vector-math.h" #include "window.h" #include "slang-com-ptr.h" diff --git a/tools/graphics-app-framework/model.h b/tools/graphics-app-framework/model.h index 44c8f0aab..412f10a1d 100644 --- a/tools/graphics-app-framework/model.h +++ b/tools/graphics-app-framework/model.h @@ -1,7 +1,7 @@ // model.h #pragma once -#include "tools/gfx/render.h" +#include "slang-gfx.h" #include "vector-math.h" #include "slang-com-ptr.h" #include diff --git a/tools/render-test/options.h b/tools/render-test/options.h index 646cf3a76..9d39e35b3 100644 --- a/tools/render-test/options.h +++ b/tools/render-test/options.h @@ -12,7 +12,7 @@ #include "../../source/core/slang-process-util.h" -#include "render.h" +#include "../../slang-gfx.h" namespace renderer_test { diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 8f62d8a50..7bf7dd369 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -3,7 +3,7 @@ #define _CRT_SECURE_NO_WARNINGS 1 #include "options.h" -#include "render.h" +#include "slang-gfx.h" #include "tools/gfx-util/shader-cursor.h" #include "slang-support.h" #include "surface.h" diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index 5f43b254d..2f7162f35 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -5,7 +5,7 @@ #include "core/slang-token-reader.h" #include "core/slang-type-text-util.h" -#include "render.h" +#include "slang-gfx.h" namespace renderer_test { diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index 51463eca6..2c8dbe821 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -9,7 +9,7 @@ #include "bind-location.h" -#include "render.h" +#include "slang-gfx.h" namespace renderer_test { diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h index 045f501c3..815bf2248 100644 --- a/tools/render-test/shader-renderer-util.h +++ b/tools/render-test/shader-renderer-util.h @@ -1,7 +1,7 @@ // shader-renderer-util.h #pragma once -#include "render.h" +#include "slang-gfx.h" #include "shader-input-layout.h" namespace renderer_test { diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h index c08d18567..6fa850874 100644 --- a/tools/render-test/slang-support.h +++ b/tools/render-test/slang-support.h @@ -1,7 +1,7 @@ // slang-support.h #pragma once -#include "render.h" +#include "slang-gfx.h" #include diff --git a/tools/render-test/surface.h b/tools/render-test/surface.h index 3e0f6f0aa..f6e888745 100644 --- a/tools/render-test/surface.h +++ b/tools/render-test/surface.h @@ -1,7 +1,7 @@ // surface.h #pragma once -#include "render.h" +#include "slang-gfx.h" namespace gfx { -- cgit v1.2.3