summaryrefslogtreecommitdiffstats
path: root/tools/render-test/render.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/render-test/render.h')
-rw-r--r--tools/render-test/render.h267
1 files changed, 241 insertions, 26 deletions
diff --git a/tools/render-test/render.h b/tools/render-test/render.h
index 761f9e759..2800e069b 100644
--- a/tools/render-test/render.h
+++ b/tools/render-test/render.h
@@ -11,10 +11,6 @@
namespace renderer_test {
// Declare opaque type
-class Buffer: public Slang::RefObject
-{
- public:
-};
class InputLayout: public Slang::RefObject
{
public:
@@ -71,19 +67,10 @@ enum class Format
Unknown,
RGB_Float32,
RG_Float32,
-};
+ R_Float32,
-enum class BufferFlavor
-{
- Constant,
- Vertex
-};
-
-struct BufferDesc
-{
- UInt size = 0;
- BufferFlavor flavor = BufferFlavor::Constant;
- void const* initData = nullptr;
+ RGBA_Unorm_UInt8,
+ CountOf,
};
struct InputElementDesc
@@ -106,6 +93,231 @@ enum class PrimitiveTopology
TriangleList,
};
+class Resource: public Slang::RefObject
+{
+ 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
+ };
+ };
+
+ /// Get the type
+ SLANG_FORCE_INLINE Type getType() const { return m_type; }
+ /// True if it's a texture derived type
+ SLANG_FORCE_INLINE bool isTexture() const { return int(m_type) >= int(Type::Texture1D); }
+ /// True if it's a buffer derived type
+ SLANG_FORCE_INLINE bool isBuffer() const { return m_type == Type::Buffer; }
+
+ /// For a usage gives the required binding flags
+ static const BindFlag::Enum s_requiredBinding[int(Usage::CountOf)];
+
+ protected:
+ Resource(Type type):
+ m_type(type)
+ {}
+
+ Type m_type;
+};
+
+class BufferResource: public Resource
+{
+ public:
+ typedef Resource Parent;
+
+ struct Desc
+ {
+ void init(size_t sizeInBytesIn)
+ {
+ bindFlags = 0;
+ cpuAccessFlags = 0;
+ sizeInBytes = sizeInBytesIn;
+ elementSize = 0;
+ }
+ /// Set up default parameters based on usage
+ void setDefaults(Usage initialUsage);
+
+ int bindFlags; ///< Combination of Resource::BindFlag or 0 (and will use initialUsage to set)
+ int cpuAccessFlags; ///< Combination of Resource::AccessFlag
+
+ size_t sizeInBytes; ///< Total size in bytes
+ int elementSize; ///< Get the element stride. If > 0, this is a structured buffer
+ };
+
+ /// Get the buffer description
+ SLANG_FORCE_INLINE const Desc& getDesc() const { return m_desc; }
+
+ /// Ctor
+ BufferResource(const Desc& desc):
+ Parent(Type::Buffer),
+ m_desc(desc)
+ {
+ }
+
+ protected:
+ Desc m_desc;
+};
+
+class TextureResource: public Resource
+{
+ public:
+ typedef Resource Parent;
+
+ 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;
+ /// Given a size, calculates the size at a mip level
+ Size calcMipSize(int mipLevel) const;
+
+ int width; ///< Width in pixels
+ int height; ///< Height in pixels (if 2d or 3d)
+ int depth; ///< Depth (if 3d)
+ };
+
+ struct Desc
+ {
+ /// Initialize with default values
+ void init();
+ /// Initialize different dimensions. For cubemap, use init2D
+ void init1D(Format format, int width, int numMipMaps = 0);
+ void init2D(Format format, int width, int height, int numMipMaps = 0);
+ void init3D(Format format, int width, int height, int depth, int numMipMaps = 0);
+
+ /// Given the type, calculates the number of mip maps. 0 on error
+ int calcNumMipLevels(Type type) const;
+ /// Calculate the total number of sub resources. 0 on error.
+ int calcNumSubResources(Type type) const;
+
+ /// 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(Type type) const;
+
+ ///
+ void fixSize(Type type);
+
+ /// Set up default parameters based on type and usage
+ void setDefaults(Type type, Usage initialUsage);
+
+ int bindFlags; ///< Combination of Resource::BindFlag or 0 (and will use initialUsage to set)
+ int cpuAccessFlags; ///< Combination of Resource::AccessFlag
+
+ Size size;
+
+ int arraySize; ///< Array size
+
+ int numMipLevels; ///< Number of mip levels - if 0 will generate all mip levels
+ Format format; ///< The resources format
+ SampleDesc sampleDesc; ///< How the resource is sampled
+ };
+
+ /// The ordering of the subResources is
+ /// forall (cube faces (6) * arraySize / arraySize)
+ /// 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
+ };
+
+ /// Get the description of the texture
+ SLANG_FORCE_INLINE const Desc& getDesc() const { return m_desc; }
+
+ /// Ctor
+ TextureResource(Type type, const Desc& desc):
+ Parent(type),
+ m_desc(desc)
+ {
+ }
+
+ SLANG_FORCE_INLINE static int calcMipSize(int width, int mipLevel)
+ {
+ width = width >> mipLevel;
+ return width > 0 ? width : 1;
+ }
+
+ protected:
+ Desc m_desc;
+};
+
class Renderer: public Slang::RefObject
{
public:
@@ -116,28 +328,32 @@ public:
virtual void presentFrame() = 0;
+ /// Create a texture resource. initData holds the initialize data to set the contents of the texture when constructed.
+ virtual TextureResource* createTextureResource(Resource::Type type, Resource::Usage initialUsage, const TextureResource::Desc& desc, const TextureResource::Data* initData = nullptr) { return nullptr; }
+ /// Create a buffer resource
+ virtual BufferResource* createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& desc, const void* initData = nullptr) { return nullptr; }
+
virtual SlangResult captureScreenShot(const char* outputPath) = 0;
virtual void serializeOutput(BindingState* state, const char* outputPath) = 0;
- virtual Buffer* createBuffer(const BufferDesc& desc) = 0;
virtual InputLayout* createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) = 0;
virtual BindingState* createBindingState(const ShaderInputLayout& shaderInput) = 0;
virtual ShaderCompiler* getShaderCompiler() = 0;
- virtual void* map(Buffer* buffer, MapFlavor flavor) = 0;
- virtual void unmap(Buffer* buffer) = 0;
+ virtual void* map(BufferResource* buffer, MapFlavor flavor) = 0;
+ virtual void unmap(BufferResource* buffer) = 0;
virtual void setInputLayout(InputLayout* inputLayout) = 0;
virtual void setPrimitiveTopology(PrimitiveTopology topology) = 0;
virtual void setBindingState(BindingState* state) = 0;
- virtual void setVertexBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* strides, const UInt* offsets) = 0;
+ virtual void setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* strides, const UInt* offsets) = 0;
- inline void setVertexBuffer(UInt slot, Buffer* buffer, UInt stride, UInt offset = 0);
+ inline void setVertexBuffer(UInt slot, BufferResource* buffer, UInt stride, UInt offset = 0);
virtual void setShaderProgram(ShaderProgram* program) = 0;
- virtual void setConstantBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* offsets) = 0;
- inline void setConstantBuffer(UInt slot, Buffer* buffer, UInt offset = 0);
+ virtual void setConstantBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets) = 0;
+ inline void setConstantBuffer(UInt slot, BufferResource* buffer, UInt offset = 0);
virtual void draw(UInt vertexCount, UInt startVertex = 0) = 0;
virtual void dispatchCompute(int x, int y, int z) = 0;
@@ -149,14 +365,13 @@ public:
virtual void waitForGpu() = 0;
};
-
// ----------------------------------------------------------------------------------------
-inline void Renderer::setVertexBuffer(UInt slot, Buffer* buffer, UInt stride, UInt offset)
+inline void Renderer::setVertexBuffer(UInt slot, BufferResource* buffer, UInt stride, UInt offset)
{
setVertexBuffers(slot, 1, &buffer, &stride, &offset);
}
// ----------------------------------------------------------------------------------------
-inline void Renderer::setConstantBuffer(UInt slot, Buffer* buffer, UInt offset)
+inline void Renderer::setConstantBuffer(UInt slot, BufferResource* buffer, UInt offset)
{
setConstantBuffers(slot, 1, &buffer, &offset);
}