Refactor Vertex Shader input vertex layout to use GPUVertexLayout defined on Vertex Buffer rather than Vertex Shader
#3044 #2667
This commit is contained in:
@@ -67,9 +67,15 @@ void DynamicBuffer::Dispose()
|
||||
Data.Resize(0);
|
||||
}
|
||||
|
||||
void DynamicVertexBuffer::SetLayout(GPUVertexLayout* layout)
|
||||
{
|
||||
_layout = layout;
|
||||
SAFE_DELETE_GPU_RESOURCE(_buffer);
|
||||
}
|
||||
|
||||
void DynamicVertexBuffer::InitDesc(GPUBufferDescription& desc, int32 numElements)
|
||||
{
|
||||
desc = GPUBufferDescription::Vertex(_stride, numElements, GPUResourceUsage::Dynamic);
|
||||
desc = GPUBufferDescription::Vertex(_layout, _stride, numElements, GPUResourceUsage::Dynamic);
|
||||
}
|
||||
|
||||
void DynamicIndexBuffer::InitDesc(GPUBufferDescription& desc, int32 numElements)
|
||||
|
||||
@@ -127,6 +127,9 @@ protected:
|
||||
/// </summary>
|
||||
class FLAXENGINE_API DynamicVertexBuffer : public DynamicBuffer
|
||||
{
|
||||
private:
|
||||
GPUVertexLayout* _layout;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Init
|
||||
@@ -134,11 +137,16 @@ public:
|
||||
/// <param name="initialCapacity">Initial capacity of the buffer (in bytes)</param>
|
||||
/// <param name="stride">Stride in bytes</param>
|
||||
/// <param name="name">Buffer name</param>
|
||||
DynamicVertexBuffer(uint32 initialCapacity, uint32 stride, const String& name = String::Empty)
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
DynamicVertexBuffer(uint32 initialCapacity, uint32 stride, const String& name = String::Empty, GPUVertexLayout* layout = nullptr)
|
||||
: DynamicBuffer(initialCapacity, stride, name)
|
||||
, _layout(layout)
|
||||
{
|
||||
}
|
||||
|
||||
// Sets the vertex buffer layout.
|
||||
void SetLayout(GPUVertexLayout* layout);
|
||||
|
||||
protected:
|
||||
// [DynamicBuffer]
|
||||
void InitDesc(GPUBufferDescription& desc, int32 numElements) override;
|
||||
|
||||
@@ -27,6 +27,7 @@ GPUBufferDescription GPUBufferDescription::Buffer(uint32 size, GPUBufferFlags fl
|
||||
desc.Format = format;
|
||||
desc.InitData = initData;
|
||||
desc.Usage = usage;
|
||||
desc.VertexLayout = nullptr;
|
||||
return desc;
|
||||
}
|
||||
|
||||
@@ -48,6 +49,32 @@ GPUBufferDescription GPUBufferDescription::Typed(const void* data, int32 count,
|
||||
return Buffer(count * stride, bufferFlags, viewFormat, data, stride, usage);
|
||||
}
|
||||
|
||||
GPUBufferDescription GPUBufferDescription::Vertex(GPUVertexLayout* layout, uint32 elementStride, uint32 elementsCount, const void* data)
|
||||
{
|
||||
GPUBufferDescription desc;
|
||||
desc.Size = elementsCount * elementStride;
|
||||
desc.Stride = elementStride;
|
||||
desc.Flags = GPUBufferFlags::VertexBuffer;
|
||||
desc.Format = PixelFormat::Unknown;
|
||||
desc.InitData = data;
|
||||
desc.Usage = GPUResourceUsage::Default;
|
||||
desc.VertexLayout = layout;
|
||||
return desc;
|
||||
}
|
||||
|
||||
GPUBufferDescription GPUBufferDescription::Vertex(GPUVertexLayout* layout, uint32 elementStride, uint32 elementsCount, GPUResourceUsage usage)
|
||||
{
|
||||
GPUBufferDescription desc;
|
||||
desc.Size = elementsCount * elementStride;
|
||||
desc.Stride = elementStride;
|
||||
desc.Flags = GPUBufferFlags::VertexBuffer;
|
||||
desc.Format = PixelFormat::Unknown;
|
||||
desc.InitData = nullptr;
|
||||
desc.Usage = GPUResourceUsage::Default;
|
||||
desc.VertexLayout = layout;
|
||||
return desc;
|
||||
}
|
||||
|
||||
void GPUBufferDescription::Clear()
|
||||
{
|
||||
Platform::MemoryClear(this, sizeof(GPUBufferDescription));
|
||||
@@ -78,7 +105,8 @@ bool GPUBufferDescription::Equals(const GPUBufferDescription& other) const
|
||||
&& Flags == other.Flags
|
||||
&& Format == other.Format
|
||||
&& Usage == other.Usage
|
||||
&& InitData == other.InitData;
|
||||
&& InitData == other.InitData
|
||||
&& VertexLayout == other.VertexLayout;
|
||||
}
|
||||
|
||||
String GPUBufferDescription::ToString() const
|
||||
@@ -98,6 +126,7 @@ uint32 GetHash(const GPUBufferDescription& key)
|
||||
hashCode = (hashCode * 397) ^ (uint32)key.Flags;
|
||||
hashCode = (hashCode * 397) ^ (uint32)key.Format;
|
||||
hashCode = (hashCode * 397) ^ (uint32)key.Usage;
|
||||
hashCode = (hashCode * 397) ^ GetHash(key.VertexLayout);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@@ -129,11 +158,16 @@ bool GPUBuffer::Init(const GPUBufferDescription& desc)
|
||||
&& Math::IsInRange<uint32>(desc.Stride, 0, 1024));
|
||||
|
||||
// Validate description
|
||||
#if !BUILD_RELEASE
|
||||
#define GET_NAME() GetName()
|
||||
#else
|
||||
#define GET_NAME() TEXT("")
|
||||
#endif
|
||||
if (EnumHasAnyFlags(desc.Flags, GPUBufferFlags::Structured))
|
||||
{
|
||||
if (desc.Stride <= 0)
|
||||
{
|
||||
LOG(Warning, "Cannot create buffer. Element size cannot be less or equal 0 for structured buffer.");
|
||||
LOG(Warning, "Cannot create buffer '{}'. Element size cannot be less or equal 0 for structured buffer.", GET_NAME());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -141,10 +175,19 @@ bool GPUBuffer::Init(const GPUBufferDescription& desc)
|
||||
{
|
||||
if (desc.Format != PixelFormat::R32_Typeless)
|
||||
{
|
||||
LOG(Warning, "Cannot create buffer. Raw buffers must use format R32_Typeless.");
|
||||
LOG(Warning, "Cannot create buffer '{}'. Raw buffers must use format R32_Typeless.", GET_NAME());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (EnumHasAnyFlags(desc.Flags, GPUBufferFlags::VertexBuffer))
|
||||
{
|
||||
if (desc.VertexLayout == nullptr)
|
||||
{
|
||||
// [Deprecated in v1.10] Change this into an error as VertexLayout becomes a requirement when layout is no longer set in a vertex shader
|
||||
LOG(Warning, "Missing Vertex Layout in buffer '{}'. Vertex Buffers should provide layout information about contained vertex elements.", GET_NAME());
|
||||
}
|
||||
}
|
||||
#undef GET_NAME
|
||||
|
||||
// Release previous data
|
||||
ReleaseGPU();
|
||||
|
||||
@@ -85,6 +85,14 @@ public:
|
||||
return _desc.Flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets vertex elements layout used by vertex buffers only.
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE GPUVertexLayout* GetVertexLayout() const
|
||||
{
|
||||
return _desc.VertexLayout;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if buffer is a staging buffer (supports CPU readback).
|
||||
/// </summary>
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace FlaxEngine
|
||||
desc.Format = format;
|
||||
desc.InitData = initData;
|
||||
desc.Usage = usage;
|
||||
desc.VertexLayout = null;
|
||||
return desc;
|
||||
}
|
||||
|
||||
@@ -70,6 +71,7 @@ namespace FlaxEngine
|
||||
desc.Format = format;
|
||||
desc.InitData = initData;
|
||||
desc.Usage = usage;
|
||||
desc.VertexLayout = null;
|
||||
return desc;
|
||||
}
|
||||
|
||||
@@ -117,11 +119,55 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// </summary>
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
public static GPUBufferDescription Vertex(int elementStride, int elementsCount, IntPtr data)
|
||||
public static GPUBufferDescription Vertex(GPUVertexLayout layout, int elementStride, int elementsCount, IntPtr data)
|
||||
{
|
||||
GPUBufferDescription desc;
|
||||
desc.Size = (uint)(elementsCount * elementStride);
|
||||
desc.Stride = (uint)elementStride;
|
||||
desc.Flags = GPUBufferFlags.VertexBuffer;
|
||||
desc.Format = PixelFormat.Unknown;
|
||||
desc.InitData = data;
|
||||
desc.Usage = GPUResourceUsage.Default;
|
||||
desc.VertexLayout = layout;
|
||||
return desc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// </summary>
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="usage">The usage mode.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
public static GPUBufferDescription Vertex(GPUVertexLayout layout, int elementStride, int elementsCount, GPUResourceUsage usage = GPUResourceUsage.Default)
|
||||
{
|
||||
GPUBufferDescription desc;
|
||||
desc.Size = (uint)(elementsCount * elementStride);
|
||||
desc.Stride = (uint)elementStride;
|
||||
desc.Flags = GPUBufferFlags.VertexBuffer;
|
||||
desc.Format = PixelFormat.Unknown;
|
||||
desc.InitData = new IntPtr();
|
||||
desc.Usage = usage;
|
||||
desc.VertexLayout = layout;
|
||||
return desc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// </summary>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
[Obsolete("Use Vertex with vertex layout parameter instead")]
|
||||
public static GPUBufferDescription Vertex(int elementStride, int elementsCount, IntPtr data, GPUVertexLayout layout = null)
|
||||
{
|
||||
return Buffer(elementsCount * elementStride, GPUBufferFlags.VertexBuffer, PixelFormat.Unknown, data, elementStride, GPUResourceUsage.Default);
|
||||
}
|
||||
@@ -132,18 +178,22 @@ namespace FlaxEngine
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="usage">The usage mode.</param>
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
public static GPUBufferDescription Vertex(int elementStride, int elementsCount, GPUResourceUsage usage = GPUResourceUsage.Default)
|
||||
[Obsolete("Use Vertex with vertex layout parameter instead")]
|
||||
public static GPUBufferDescription Vertex(int elementStride, int elementsCount, GPUResourceUsage usage = GPUResourceUsage.Default, GPUVertexLayout layout = null)
|
||||
{
|
||||
return Buffer(elementsCount * elementStride, GPUBufferFlags.VertexBuffer, PixelFormat.Unknown, new IntPtr(), elementStride, usage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
/// <param name="size">The size (in bytes).</param>
|
||||
/// <param name="usage">The usage mode.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
[Obsolete("Use Vertex with separate vertex stride and count instead")]
|
||||
public static GPUBufferDescription Vertex(int size, GPUResourceUsage usage = GPUResourceUsage.Default)
|
||||
{
|
||||
return Buffer(size, GPUBufferFlags.VertexBuffer, PixelFormat.Unknown, new IntPtr(), 0, usage);
|
||||
@@ -190,7 +240,6 @@ namespace FlaxEngine
|
||||
var bufferFlags = GPUBufferFlags.Structured | GPUBufferFlags.ShaderResource;
|
||||
if (isUnorderedAccess)
|
||||
bufferFlags |= GPUBufferFlags.UnorderedAccess;
|
||||
|
||||
return Buffer(elementCount * elementSize, bufferFlags, PixelFormat.Unknown, new IntPtr(), elementSize);
|
||||
}
|
||||
|
||||
@@ -304,7 +353,8 @@ namespace FlaxEngine
|
||||
Flags == other.Flags &&
|
||||
Format == other.Format &&
|
||||
InitData.Equals(other.InitData) &&
|
||||
Usage == other.Usage;
|
||||
Usage == other.Usage &&
|
||||
VertexLayout == other.VertexLayout;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -324,6 +374,58 @@ namespace FlaxEngine
|
||||
hashCode = (hashCode * 397) ^ (int)Format;
|
||||
hashCode = (hashCode * 397) ^ InitData.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int)Usage;
|
||||
if (VertexLayout != null)
|
||||
hashCode = (hashCode * 397) ^ VertexLayout.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial struct VertexElement : IEquatable<VertexElement>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the vertex element description.
|
||||
/// </summary>
|
||||
/// <param name="type">Element type.</param>
|
||||
/// <param name="slot">Vertex buffer bind slot.</param>
|
||||
/// <param name="offset">Data byte offset.</param>
|
||||
/// <param name="perInstance">True if element data is instanced.</param>
|
||||
/// <param name="format">Data format.</param>
|
||||
public VertexElement(Types type, byte slot, byte offset, bool perInstance, PixelFormat format)
|
||||
{
|
||||
Type = type;
|
||||
Slot = slot;
|
||||
Offset = offset;
|
||||
PerInstance = (byte)(perInstance ? 1 : 0);
|
||||
Format = format;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(VertexElement other)
|
||||
{
|
||||
return Type == other.Type &&
|
||||
Slot == other.Slot &&
|
||||
Offset == other.Offset &&
|
||||
PerInstance == other.PerInstance &&
|
||||
Format == other.Format;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is VertexElement other && Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int)Type;
|
||||
hashCode = (hashCode * 397) ^ Slot;
|
||||
hashCode = (hashCode * 397) ^ Offset;
|
||||
hashCode = (hashCode * 397) ^ PerInstance;
|
||||
hashCode = (hashCode * 397) ^ (int)Format;
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "Enums.h"
|
||||
#include "PixelFormat.h"
|
||||
|
||||
class GPUVertexLayout;
|
||||
|
||||
/// <summary>
|
||||
/// The GPU buffer usage flags.
|
||||
/// </summary>
|
||||
@@ -110,6 +112,11 @@ API_STRUCT() struct FLAXENGINE_API GPUBufferDescription
|
||||
/// </summary>
|
||||
API_FIELD() GPUResourceUsage Usage;
|
||||
|
||||
/// <summary>
|
||||
/// The vertex elements layout used by vertex buffers only.
|
||||
/// </summary>
|
||||
API_FIELD() GPUVertexLayout* VertexLayout;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the number elements in the buffer.
|
||||
@@ -178,34 +185,57 @@ public:
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// </summary>
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
static GPUBufferDescription Vertex(int32 elementStride, int32 elementsCount, const void* data)
|
||||
static GPUBufferDescription Vertex(GPUVertexLayout* layout, uint32 elementStride, uint32 elementsCount, const void* data);
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// </summary>
|
||||
/// <param name="layout">The vertex buffer layout.</param>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="usage">The usage mode.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
static GPUBufferDescription Vertex(GPUVertexLayout* layout, uint32 elementStride, uint32 elementsCount, GPUResourceUsage usage = GPUResourceUsage::Default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
DEPRECATED("Use Vertex with vertex layout parameter instead") static GPUBufferDescription Vertex(int32 elementStride, int32 elementsCount, const void* data)
|
||||
{
|
||||
return Buffer(elementsCount * elementStride, GPUBufferFlags::VertexBuffer, PixelFormat::Unknown, data, elementStride, GPUResourceUsage::Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
/// <param name="elementStride">The element stride.</param>
|
||||
/// <param name="elementsCount">The elements count.</param>
|
||||
/// <param name="usage">The usage mode.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
static GPUBufferDescription Vertex(int32 elementStride, int32 elementsCount, GPUResourceUsage usage = GPUResourceUsage::Default)
|
||||
DEPRECATED("Use Vertex with vertex layout parameter instead") static GPUBufferDescription Vertex(int32 elementStride, int32 elementsCount, GPUResourceUsage usage = GPUResourceUsage::Default)
|
||||
{
|
||||
return Buffer(elementsCount * elementStride, GPUBufferFlags::VertexBuffer, PixelFormat::Unknown, nullptr, elementStride, usage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates vertex buffer description.
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
/// <param name="size">The size (in bytes).</param>
|
||||
/// <param name="usage">The usage mode.</param>
|
||||
/// <returns>The buffer description.</returns>
|
||||
static GPUBufferDescription Vertex(int32 size, GPUResourceUsage usage = GPUResourceUsage::Default)
|
||||
DEPRECATED("Use Vertex with separate vertex stride and count instead") static GPUBufferDescription Vertex(int32 size, GPUResourceUsage usage = GPUResourceUsage::Default)
|
||||
{
|
||||
return Buffer(size, GPUBufferFlags::VertexBuffer, PixelFormat::Unknown, nullptr, 0, usage);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class GPUResource;
|
||||
class GPUResourceView;
|
||||
class GPUTextureView;
|
||||
class GPUBufferView;
|
||||
class GPUVertexLayout;
|
||||
|
||||
// Gets the GPU texture view. Checks if pointer is not null and texture has one or more mip levels loaded.
|
||||
#define GET_TEXTURE_VIEW_SAFE(t) (t && t->ResidentMipLevels() > 0 ? t->View() : nullptr)
|
||||
@@ -404,7 +405,8 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="vertexBuffers">The array of vertex buffers to use.</param>
|
||||
/// <param name="vertexBuffersOffsets">The optional array of byte offsets from the vertex buffers begins. Can be used to offset the vertex data when reusing the same buffer allocation for multiple geometry objects.</param>
|
||||
API_FUNCTION() virtual void BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets = nullptr) = 0;
|
||||
/// <param name="vertexLayout">The optional vertex layout to use when passing data from vertex buffers to the vertex shader. If null, layout will be automatically extracted from vertex buffers combined.</param>
|
||||
API_FUNCTION() virtual void BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets = nullptr, GPUVertexLayout* vertexLayout = nullptr) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Binds the index buffer to the pipeline.
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Scripting/Enums.h"
|
||||
|
||||
#include "Shaders/GPUVertexLayout.h"
|
||||
|
||||
GPUResourcePropertyBase::~GPUResourcePropertyBase()
|
||||
{
|
||||
const auto e = _resource;
|
||||
@@ -386,7 +388,11 @@ bool GPUDevice::LoadContent()
|
||||
};
|
||||
// @formatter:on
|
||||
_res->FullscreenTriangleVB = CreateBuffer(TEXT("QuadVB"));
|
||||
if (_res->FullscreenTriangleVB->Init(GPUBufferDescription::Vertex(sizeof(float) * 4, 3, vb)))
|
||||
auto layout = GPUVertexLayout::Get({
|
||||
{ VertexElement::Types::Position, 0, 0, 0, PixelFormat::R32G32_Float },
|
||||
{ VertexElement::Types::TexCoord, 0, 8, 0, PixelFormat::R32G32_Float },
|
||||
});
|
||||
if (_res->FullscreenTriangleVB->Init(GPUBufferDescription::Vertex(layout, 16, 3, vb)))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MCore.h"
|
||||
@@ -21,6 +22,30 @@
|
||||
#include "Engine/Renderer/GBufferPass.h"
|
||||
#endif
|
||||
|
||||
GPUVertexLayout* VB0ElementType18::GetLayout()
|
||||
{
|
||||
return GPUVertexLayout::Get({
|
||||
{ VertexElement::Types::Position, 0, 0, 0, PixelFormat::R32G32B32_Float },
|
||||
});
|
||||
}
|
||||
|
||||
GPUVertexLayout* VB1ElementType18::GetLayout()
|
||||
{
|
||||
return GPUVertexLayout::Get({
|
||||
{ VertexElement::Types::TexCoord, 1, 0, 0, PixelFormat::R16G16_Float },
|
||||
{ VertexElement::Types::Normal, 1, 0, 0, PixelFormat::R10G10B10A2_UNorm },
|
||||
{ VertexElement::Types::Tangent, 1, 0, 0, PixelFormat::R10G10B10A2_UNorm },
|
||||
{ VertexElement::Types::TexCoord1, 1, 0, 0, PixelFormat::R16G16_Float },
|
||||
});
|
||||
}
|
||||
|
||||
GPUVertexLayout* VB2ElementType18::GetLayout()
|
||||
{
|
||||
return GPUVertexLayout::Get({
|
||||
{ VertexElement::Types::Color, 2, 0, 0, PixelFormat::R8G8B8A8_UNorm },
|
||||
});
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename IndexType>
|
||||
@@ -233,15 +258,15 @@ bool Mesh::Load(uint32 vertices, uint32 triangles, const void* vb0, const void*
|
||||
#define MESH_BUFFER_NAME(postfix) String::Empty
|
||||
#endif
|
||||
vertexBuffer0 = GPUDevice::Instance->CreateBuffer(MESH_BUFFER_NAME(".VB0"));
|
||||
if (vertexBuffer0->Init(GPUBufferDescription::Vertex(sizeof(VB0ElementType), vertices, vb0)))
|
||||
if (vertexBuffer0->Init(GPUBufferDescription::Vertex(VB0ElementType::GetLayout(), sizeof(VB0ElementType), vertices, vb0)))
|
||||
goto ERROR_LOAD_END;
|
||||
vertexBuffer1 = GPUDevice::Instance->CreateBuffer(MESH_BUFFER_NAME(".VB1"));
|
||||
if (vertexBuffer1->Init(GPUBufferDescription::Vertex(sizeof(VB1ElementType), vertices, vb1)))
|
||||
if (vertexBuffer1->Init(GPUBufferDescription::Vertex(VB1ElementType::GetLayout(), sizeof(VB1ElementType), vertices, vb1)))
|
||||
goto ERROR_LOAD_END;
|
||||
if (vb2)
|
||||
{
|
||||
vertexBuffer2 = GPUDevice::Instance->CreateBuffer(MESH_BUFFER_NAME(".VB2"));
|
||||
if (vertexBuffer2->Init(GPUBufferDescription::Vertex(sizeof(VB2ElementType), vertices, vb2)))
|
||||
if (vertexBuffer2->Init(GPUBufferDescription::Vertex(VB2ElementType::GetLayout(), sizeof(VB2ElementType), vertices, vb2)))
|
||||
goto ERROR_LOAD_END;
|
||||
}
|
||||
indexBuffer = GPUDevice::Instance->CreateBuffer(MESH_BUFFER_NAME(".IB"));
|
||||
|
||||
@@ -151,6 +151,7 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Init from model vertices array
|
||||
/// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
/// </summary>
|
||||
/// <param name="vertices">Array of vertices</param>
|
||||
/// <param name="verticesCount">Amount of vertices</param>
|
||||
@@ -158,6 +159,7 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Init from model vertices array
|
||||
/// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
/// </summary>
|
||||
/// <param name="vertices">Array of vertices</param>
|
||||
/// <param name="verticesCount">Amount of vertices</param>
|
||||
@@ -182,6 +184,7 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Init from model vertices array
|
||||
/// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
/// </summary>
|
||||
/// <param name="vb0">Array of data for vertex buffer 0</param>
|
||||
/// <param name="vb1">Array of data for vertex buffer 1</param>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
@@ -18,6 +19,18 @@
|
||||
#include "Engine/Threading/Task.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
|
||||
GPUVertexLayout* VB0SkinnedElementType2::GetLayout()
|
||||
{
|
||||
return GPUVertexLayout::Get({
|
||||
{ VertexElement::Types::Position, 0, 0, 0, PixelFormat::R32G32B32_Float },
|
||||
{ VertexElement::Types::TexCoord, 0, 0, 0, PixelFormat::R16G16_Float },
|
||||
{ VertexElement::Types::Normal, 0, 0, 0, PixelFormat::R10G10B10A2_UNorm },
|
||||
{ VertexElement::Types::Tangent, 0, 0, 0, PixelFormat::R10G10B10A2_UNorm },
|
||||
{ VertexElement::Types::BlendIndices, 0, 0, 0, PixelFormat::R8G8B8A8_UInt },
|
||||
{ VertexElement::Types::BlendWeight, 0, 0, 0, PixelFormat::R16G16B16A16_Float },
|
||||
});
|
||||
}
|
||||
|
||||
void SkeletonData::Swap(SkeletonData& other)
|
||||
{
|
||||
Nodes.Swap(other.Nodes);
|
||||
@@ -120,7 +133,7 @@ bool SkinnedMesh::Load(uint32 vertices, uint32 triangles, const void* vb0, const
|
||||
#else
|
||||
vertexBuffer = GPUDevice::Instance->CreateBuffer(String::Empty);
|
||||
#endif
|
||||
if (vertexBuffer->Init(GPUBufferDescription::Vertex(sizeof(VB0SkinnedElementType), vertices, vb0)))
|
||||
if (vertexBuffer->Init(GPUBufferDescription::Vertex(VB0SkinnedElementType::GetLayout(), sizeof(VB0SkinnedElementType), vertices, vb0)))
|
||||
goto ERROR_LOAD_END;
|
||||
|
||||
// Create index buffer
|
||||
|
||||
@@ -21,6 +21,7 @@ class Model;
|
||||
class SkinnedModel;
|
||||
class MeshDeformation;
|
||||
class GPUContext;
|
||||
class GPUVertexLayout;
|
||||
struct RenderView;
|
||||
|
||||
/// <summary>
|
||||
@@ -69,6 +70,7 @@ enum class MeshBufferType
|
||||
};
|
||||
|
||||
// Vertex structure for all models (versioned)
|
||||
// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
PACK_STRUCT(struct ModelVertex15
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -77,6 +79,7 @@ PACK_STRUCT(struct ModelVertex15
|
||||
Float1010102 Tangent;
|
||||
});
|
||||
|
||||
// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
PACK_STRUCT(struct ModelVertex18
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -86,6 +89,7 @@ PACK_STRUCT(struct ModelVertex18
|
||||
Half2 LightmapUVs;
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
PACK_STRUCT(struct ModelVertex19
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -96,9 +100,10 @@ PACK_STRUCT(struct ModelVertex19
|
||||
Color32 Color;
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
typedef ModelVertex19 ModelVertex;
|
||||
|
||||
//
|
||||
// [Deprecated in v1.10]
|
||||
struct RawModelVertex
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -111,11 +116,12 @@ struct RawModelVertex
|
||||
};
|
||||
|
||||
// For vertex data we use three buffers: one with positions, one with other attributes, and one with colors
|
||||
// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
PACK_STRUCT(struct VB0ElementType15
|
||||
{
|
||||
Float3 Position;
|
||||
});
|
||||
|
||||
// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
PACK_STRUCT(struct VB1ElementType15
|
||||
{
|
||||
Half2 TexCoord;
|
||||
@@ -123,30 +129,42 @@ PACK_STRUCT(struct VB1ElementType15
|
||||
Float1010102 Tangent;
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
PACK_STRUCT(struct VB0ElementType18
|
||||
{
|
||||
Float3 Position;
|
||||
|
||||
static GPUVertexLayout* GetLayout();
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
PACK_STRUCT(struct VB1ElementType18
|
||||
{
|
||||
Half2 TexCoord;
|
||||
Float1010102 Normal;
|
||||
Float1010102 Tangent;
|
||||
Half2 LightmapUVs;
|
||||
|
||||
static GPUVertexLayout* GetLayout();
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
PACK_STRUCT(struct VB2ElementType18
|
||||
{
|
||||
Color32 Color;
|
||||
|
||||
static GPUVertexLayout* GetLayout();
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
typedef VB0ElementType18 VB0ElementType;
|
||||
// [Deprecated in v1.10]
|
||||
typedef VB1ElementType18 VB1ElementType;
|
||||
// [Deprecated in v1.10]
|
||||
typedef VB2ElementType18 VB2ElementType;
|
||||
//
|
||||
|
||||
// Vertex structure for all skinned models (versioned)
|
||||
// [Deprecated in v1.10]
|
||||
PACK_STRUCT(struct SkinnedModelVertex1
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -157,9 +175,10 @@ PACK_STRUCT(struct SkinnedModelVertex1
|
||||
Color32 BlendWeights;
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
typedef SkinnedModelVertex1 SkinnedModelVertex;
|
||||
|
||||
//
|
||||
// [Deprecated in v1.10]
|
||||
struct RawSkinnedModelVertex
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -171,6 +190,7 @@ struct RawSkinnedModelVertex
|
||||
Float4 BlendWeights;
|
||||
};
|
||||
|
||||
// [Deprecated on 28.04.2023, expires on 01.01.2024]
|
||||
PACK_STRUCT(struct VB0SkinnedElementType1
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -181,6 +201,7 @@ PACK_STRUCT(struct VB0SkinnedElementType1
|
||||
Color32 BlendWeights;
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
PACK_STRUCT(struct VB0SkinnedElementType2
|
||||
{
|
||||
Float3 Position;
|
||||
@@ -189,7 +210,9 @@ PACK_STRUCT(struct VB0SkinnedElementType2
|
||||
Float1010102 Tangent;
|
||||
Color32 BlendIndices;
|
||||
Half4 BlendWeights;
|
||||
|
||||
static GPUVertexLayout* GetLayout();
|
||||
});
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
typedef VB0SkinnedElementType2 VB0SkinnedElementType;
|
||||
//
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "GPUConstantBuffer.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Core/Types/Span.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
@@ -23,11 +24,6 @@ void GPUShaderProgram::Init(const GPUShaderProgramInitializer& initializer)
|
||||
#endif
|
||||
}
|
||||
|
||||
GPUShaderProgramVS::~GPUShaderProgramVS()
|
||||
{
|
||||
SAFE_DELETE(Layout);
|
||||
}
|
||||
|
||||
GPUShader::GPUShader()
|
||||
: GPUResource(SpawnParams(Guid::New(), TypeInitializer))
|
||||
{
|
||||
@@ -77,15 +73,15 @@ bool GPUShader::Create(MemoryReadStream& stream)
|
||||
|
||||
for (int32 permutationIndex = 0; permutationIndex < permutationsCount; permutationIndex++)
|
||||
{
|
||||
// Load cache
|
||||
uint32 cacheSize;
|
||||
stream.ReadUint32(&cacheSize);
|
||||
if (cacheSize > stream.GetLength() - stream.GetPosition())
|
||||
// Load bytecode
|
||||
uint32 bytecodeSize;
|
||||
stream.ReadUint32(&bytecodeSize);
|
||||
if (bytecodeSize > stream.GetLength() - stream.GetPosition())
|
||||
{
|
||||
LOG(Warning, "Invalid shader cache size.");
|
||||
LOG(Warning, "Invalid shader bytecode size.");
|
||||
return true;
|
||||
}
|
||||
byte* cache = stream.Move<byte>(cacheSize);
|
||||
byte* bytecode = stream.Move<byte>(bytecodeSize);
|
||||
|
||||
// Read bindings
|
||||
stream.ReadBytes(&initializer.Bindings, sizeof(ShaderBindings));
|
||||
@@ -96,7 +92,7 @@ bool GPUShader::Create(MemoryReadStream& stream)
|
||||
LOG(Warning, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name);
|
||||
continue;
|
||||
}
|
||||
GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream);
|
||||
GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, Span<byte>(bytecode, bytecodeSize), stream);
|
||||
if (shader == nullptr)
|
||||
{
|
||||
#if !GPU_ALLOW_TESSELLATION_SHADERS
|
||||
@@ -181,6 +177,24 @@ GPUShaderProgram* GPUShader::GetShader(ShaderStage stage, const StringAnsiView&
|
||||
return shader;
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUShader::ReadVertexLayout(MemoryReadStream& stream)
|
||||
{
|
||||
// [Deprecated in v1.10]
|
||||
byte inputLayoutSize;
|
||||
stream.ReadByte(&inputLayoutSize);
|
||||
if (inputLayoutSize == 0)
|
||||
return nullptr;
|
||||
void* elementsData = stream.Move(sizeof(VertexElement) * inputLayoutSize);
|
||||
if (inputLayoutSize > GPU_MAX_VS_ELEMENTS)
|
||||
{
|
||||
LOG(Error, "Incorrect input layout size.");
|
||||
return nullptr;
|
||||
}
|
||||
GPUVertexLayout::Elements elements;
|
||||
elements.Set((VertexElement*)elementsData, inputLayoutSize);
|
||||
return GPUVertexLayout::Get(elements);
|
||||
}
|
||||
|
||||
GPUResourceType GPUShader::GetResourceType() const
|
||||
{
|
||||
return GPUResourceType::Shader;
|
||||
|
||||
@@ -12,7 +12,7 @@ class GPUShaderProgram;
|
||||
/// <summary>
|
||||
/// The runtime version of the shaders cache supported by the all graphics back-ends. The same for all the shader cache formats (easier to sync and validate).
|
||||
/// </summary>
|
||||
#define GPU_SHADER_CACHE_VERSION 10
|
||||
#define GPU_SHADER_CACHE_VERSION 11
|
||||
|
||||
/// <summary>
|
||||
/// The GPU resource with shader programs that can run on the GPU and are able to perform rendering calculation using textures, vertices and other resources.
|
||||
@@ -134,7 +134,8 @@ public:
|
||||
|
||||
protected:
|
||||
GPUShaderProgram* GetShader(ShaderStage stage, const StringAnsiView& name, int32 permutationIndex) const;
|
||||
virtual GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, byte* cacheBytes, uint32 cacheSize, MemoryReadStream& stream) = 0;
|
||||
virtual GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, Span<byte> bytecode, MemoryReadStream& stream) = 0;
|
||||
static GPUVertexLayout* ReadVertexLayout(MemoryReadStream& stream);
|
||||
|
||||
public:
|
||||
// [GPUResource]
|
||||
|
||||
@@ -115,20 +115,11 @@ public:
|
||||
/// </summary>
|
||||
class GPUShaderProgramVS : public GPUShaderProgram
|
||||
{
|
||||
public:
|
||||
~GPUShaderProgramVS();
|
||||
|
||||
// Vertex elements input layout defined explicitly in the shader.
|
||||
// It's optional as it's been deprecated in favor or layouts defined by vertex buffers to allow data customizations.
|
||||
// Can be overriden by the vertex buffers provided upon draw call.
|
||||
// [Deprecated in v1.10]
|
||||
GPUVertexLayout* Layout = nullptr;
|
||||
|
||||
public:
|
||||
// Input element run-time data (see VertexShaderMeta::InputElement for compile-time data)
|
||||
// [Deprecated in v1.10]
|
||||
// [Deprecated in v1.10] Use VertexElement instead.
|
||||
PACK_STRUCT(struct InputElement
|
||||
{
|
||||
{
|
||||
byte Type; // VertexShaderMeta::InputType
|
||||
byte Index;
|
||||
byte Format; // PixelFormat
|
||||
@@ -136,19 +127,14 @@ public:
|
||||
uint32 AlignedByteOffset; // Fixed value or INPUT_LAYOUT_ELEMENT_ALIGN if auto
|
||||
byte InputSlotClass; // INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA or INPUT_LAYOUT_ELEMENT_PER_INSTANCE_DATA
|
||||
uint32 InstanceDataStepRate; // 0 if per-vertex
|
||||
});
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Gets input layout description handle (platform dependent).
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
virtual void* GetInputLayout() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets input layout description size (in bytes).
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
virtual byte GetInputLayoutSize() const = 0;
|
||||
// Vertex elements input layout defined explicitly in the shader.
|
||||
// It's optional as it's been deprecated in favor or layouts defined by vertex buffers to allow data customizations.
|
||||
// Can be overriden by the vertex buffers provided upon draw call.
|
||||
// (don't release it as it's managed by GPUVertexLayout::Get)
|
||||
// [Deprecated in v1.10]
|
||||
GPUVertexLayout* Layout = nullptr;
|
||||
|
||||
public:
|
||||
// [GPUShaderProgram]
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#endif
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Core/Types/Span.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUBuffer.h"
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
#include "Engine/Scripting/Enums.h"
|
||||
#endif
|
||||
@@ -18,10 +20,29 @@ struct VertexElementRaw
|
||||
|
||||
static_assert(sizeof(VertexElement) == sizeof(VertexElementRaw), "Incorrect size of the VertexElement!");
|
||||
|
||||
struct VertexBufferLayouts
|
||||
{
|
||||
GPUVertexLayout* Layouts[GPU_MAX_VB_BINDED];
|
||||
|
||||
bool operator==(const VertexBufferLayouts& other) const
|
||||
{
|
||||
return Platform::MemoryCompare(&Layouts, &other.Layouts, sizeof(Layouts)) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
uint32 GetHash(const VertexBufferLayouts& key)
|
||||
{
|
||||
uint32 hash = GetHash(key.Layouts[0]);
|
||||
for (int32 i = 1; i < GPU_MAX_VB_BINDED; i++)
|
||||
CombineHash(hash, GetHash(key.Layouts[i]));
|
||||
return hash;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
CriticalSection CacheLocker;
|
||||
Dictionary<uint32, GPUVertexLayout*> LayoutCache;
|
||||
Dictionary<VertexBufferLayouts, GPUVertexLayout*> VertexBufferCache;
|
||||
}
|
||||
|
||||
String VertexElement::ToString() const
|
||||
@@ -95,9 +116,50 @@ GPUVertexLayout* GPUVertexLayout::Get(const Elements& elements)
|
||||
return result;
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUVertexLayout::Get(const Span<GPUBuffer*>& vertexBuffers)
|
||||
{
|
||||
if (vertexBuffers.Length() == 0)
|
||||
return nullptr;
|
||||
if (vertexBuffers.Length() == 1)
|
||||
return vertexBuffers.Get()[0] ? vertexBuffers.Get()[0]->GetVertexLayout() : nullptr;
|
||||
|
||||
// Build hash key for set of buffers (in case there is layout sharing by different sets of buffers)
|
||||
VertexBufferLayouts layouts;
|
||||
for (int32 i = 0; i < vertexBuffers.Length(); i++)
|
||||
layouts.Layouts[i] = vertexBuffers.Get()[i] ? vertexBuffers.Get()[i]->GetVertexLayout() : nullptr;
|
||||
for (int32 i = vertexBuffers.Length(); i < GPU_MAX_VB_BINDED; i++)
|
||||
layouts.Layouts[i] = nullptr;
|
||||
|
||||
// Lookup existing cache
|
||||
CacheLocker.Lock();
|
||||
GPUVertexLayout* result;
|
||||
if (!VertexBufferCache.TryGet(layouts, result))
|
||||
{
|
||||
Elements elements;
|
||||
bool anyValid = false;
|
||||
for (int32 slot = 0; slot < vertexBuffers.Length(); slot++)
|
||||
{
|
||||
if (layouts.Layouts[slot])
|
||||
{
|
||||
anyValid = true;
|
||||
int32 start = elements.Count();
|
||||
elements.Add(layouts.Layouts[slot]->GetElements());
|
||||
for (int32 j = start; j < elements.Count() ;j++)
|
||||
elements.Get()[j].Slot = (byte)slot;
|
||||
}
|
||||
}
|
||||
result = anyValid ? Get(elements) : nullptr;
|
||||
VertexBufferCache.Add(layouts, result);
|
||||
}
|
||||
CacheLocker.Unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ClearVertexLayoutCache()
|
||||
{
|
||||
for (const auto& e : LayoutCache)
|
||||
Delete(e.Value);
|
||||
LayoutCache.Clear();
|
||||
VertexBufferCache.Clear();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "Engine/Graphics/GPUResource.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
|
||||
class GPUBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Defines input layout of vertex buffer data passed to the Vertex Shader.
|
||||
/// </summary>
|
||||
@@ -35,6 +37,13 @@ public:
|
||||
/// <returns>Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime.</returns>
|
||||
API_FUNCTION() static GPUVertexLayout* Get(const Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>>& elements);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertex layout for a given list of vertex buffers (sequence of binding slots based on layouts set on those buffers). Uses internal cache to skip creating layout if it's already exists for a given list.
|
||||
/// </summary>
|
||||
/// <param name="vertexBuffers">The list of vertex buffers for the layout.</param>
|
||||
/// <returns>Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime.</returns>
|
||||
API_FUNCTION() static GPUVertexLayout* Get(const Span<GPUBuffer*>& vertexBuffers);
|
||||
|
||||
public:
|
||||
// [GPUResource]
|
||||
GPUResourceType GetResourceType() const override
|
||||
|
||||
@@ -63,15 +63,15 @@ PACK_BEGIN() struct FLAXENGINE_API VertexElement
|
||||
};
|
||||
|
||||
// Type of the vertex element data.
|
||||
Types Type;
|
||||
API_FIELD() Types Type;
|
||||
// Index of the input vertex buffer slot (as provided in GPUContext::BindVB).
|
||||
byte Slot;
|
||||
API_FIELD() byte Slot;
|
||||
// Byte offset of this element relative to the start of a vertex buffer. Use value 0 to use auto-calculated offset based on previous elements in the layout (or for the first one).
|
||||
byte Offset;
|
||||
API_FIELD() byte Offset;
|
||||
// Flag used to mark data using hardware-instancing (element will be repeated for every instance). Empty to step data per-vertex when reading input buffer stream (rather than per-instance step).
|
||||
byte PerInstance;
|
||||
API_FIELD() byte PerInstance;
|
||||
// Format of the vertex element data.
|
||||
PixelFormat Format;
|
||||
API_FIELD() PixelFormat Format;
|
||||
|
||||
String ToString() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user