Add stride to GPUVertexLayout
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include "GPUBufferDescription.h"
|
#include "GPUBufferDescription.h"
|
||||||
#include "PixelFormatExtensions.h"
|
#include "PixelFormatExtensions.h"
|
||||||
#include "RenderTask.h"
|
#include "RenderTask.h"
|
||||||
|
#include "Shaders/GPUVertexLayout.h"
|
||||||
#include "Async/Tasks/GPUCopyResourceTask.h"
|
#include "Async/Tasks/GPUCopyResourceTask.h"
|
||||||
#include "Engine/Core/Utilities.h"
|
#include "Engine/Core/Utilities.h"
|
||||||
#include "Engine/Core/Types/String.h"
|
#include "Engine/Core/Types/String.h"
|
||||||
@@ -75,6 +76,20 @@ GPUBufferDescription GPUBufferDescription::Vertex(GPUVertexLayout* layout, uint3
|
|||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPUBufferDescription GPUBufferDescription::Vertex(GPUVertexLayout* layout, uint32 elementsCount, const void* data)
|
||||||
|
{
|
||||||
|
const uint32 stride = layout ? layout->GetStride() : 0;
|
||||||
|
CHECK_RETURN_DEBUG(stride, GPUBufferDescription());
|
||||||
|
return Vertex(layout, stride, elementsCount, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
GPUBufferDescription GPUBufferDescription::Vertex(GPUVertexLayout* layout, uint32 elementsCount, GPUResourceUsage usage)
|
||||||
|
{
|
||||||
|
const uint32 stride = layout ? layout->GetStride() : 0;
|
||||||
|
CHECK_RETURN_DEBUG(stride, GPUBufferDescription());
|
||||||
|
return Vertex(layout, stride, elementsCount, usage);
|
||||||
|
}
|
||||||
|
|
||||||
void GPUBufferDescription::Clear()
|
void GPUBufferDescription::Clear()
|
||||||
{
|
{
|
||||||
Platform::MemoryClear(this, sizeof(GPUBufferDescription));
|
Platform::MemoryClear(this, sizeof(GPUBufferDescription));
|
||||||
|
|||||||
@@ -202,6 +202,24 @@ public:
|
|||||||
/// <returns>The buffer description.</returns>
|
/// <returns>The buffer description.</returns>
|
||||||
static GPUBufferDescription Vertex(GPUVertexLayout* layout, uint32 elementStride, uint32 elementsCount, GPUResourceUsage usage = GPUResourceUsage::Default);
|
static GPUBufferDescription Vertex(GPUVertexLayout* layout, uint32 elementStride, uint32 elementsCount, GPUResourceUsage usage = GPUResourceUsage::Default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates vertex buffer description.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layout">The vertex buffer layout.</param>
|
||||||
|
/// <param name="elementsCount">The elements count.</param>
|
||||||
|
/// <param name="data">The data.</param>
|
||||||
|
/// <returns>The buffer description.</returns>
|
||||||
|
static GPUBufferDescription Vertex(GPUVertexLayout* layout, uint32 elementsCount, const void* data);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates vertex buffer description.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layout">The vertex buffer layout.</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 elementsCount, GPUResourceUsage usage = GPUResourceUsage::Default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates vertex buffer description.
|
/// Creates vertex buffer description.
|
||||||
/// [Deprecated in v1.10]
|
/// [Deprecated in v1.10]
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Engine/Core/Collections/Dictionary.h"
|
#include "Engine/Core/Collections/Dictionary.h"
|
||||||
|
#include "Engine/Core/Math/Math.h"
|
||||||
#include "Engine/Core/Types/Span.h"
|
#include "Engine/Core/Types/Span.h"
|
||||||
#include "Engine/Graphics/GPUDevice.h"
|
#include "Engine/Graphics/GPUDevice.h"
|
||||||
#include "Engine/Graphics/GPUBuffer.h"
|
#include "Engine/Graphics/GPUBuffer.h"
|
||||||
|
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||||
#if GPU_ENABLE_RESOURCE_NAMING
|
#if GPU_ENABLE_RESOURCE_NAMING
|
||||||
#include "Engine/Scripting/Enums.h"
|
#include "Engine/Scripting/Enums.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -74,6 +76,20 @@ GPUVertexLayout::GPUVertexLayout()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPUVertexLayout::SetElements(const Elements& elements, uint32 offsets[GPU_MAX_VS_ELEMENTS])
|
||||||
|
{
|
||||||
|
_elements = elements;
|
||||||
|
uint32 strides[GPU_MAX_VB_BINDED] = {};
|
||||||
|
for (int32 i = 0; i < elements.Count(); i++)
|
||||||
|
{
|
||||||
|
const VertexElement& e = elements[i];
|
||||||
|
strides[e.Slot] = Math::Max(strides[e.Slot], offsets[i]);
|
||||||
|
}
|
||||||
|
_stride = 0;
|
||||||
|
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
||||||
|
_stride += strides[i];
|
||||||
|
}
|
||||||
|
|
||||||
GPUVertexLayout* GPUVertexLayout::Get(const Elements& elements)
|
GPUVertexLayout* GPUVertexLayout::Get(const Elements& elements)
|
||||||
{
|
{
|
||||||
// Hash input layout
|
// Hash input layout
|
||||||
@@ -144,7 +160,7 @@ GPUVertexLayout* GPUVertexLayout::Get(const Span<GPUBuffer*>& vertexBuffers)
|
|||||||
anyValid = true;
|
anyValid = true;
|
||||||
int32 start = elements.Count();
|
int32 start = elements.Count();
|
||||||
elements.Add(layouts.Layouts[slot]->GetElements());
|
elements.Add(layouts.Layouts[slot]->GetElements());
|
||||||
for (int32 j = start; j < elements.Count() ;j++)
|
for (int32 j = start; j < elements.Count(); j++)
|
||||||
elements.Get()[j].Slot = (byte)slot;
|
elements.Get()[j].Slot = (byte)slot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,15 @@ API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUVertexLayout : public GPUReso
|
|||||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUVertexLayout);
|
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUVertexLayout);
|
||||||
typedef Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>> Elements;
|
typedef Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>> Elements;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
Elements _elements;
|
Elements _elements;
|
||||||
|
uint32 _stride;
|
||||||
|
|
||||||
|
protected:
|
||||||
GPUVertexLayout();
|
GPUVertexLayout();
|
||||||
|
|
||||||
|
void SetElements(const Elements& elements, uint32 offsets[GPU_MAX_VS_ELEMENTS]);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the list of elements used by this layout.
|
/// Gets the list of elements used by this layout.
|
||||||
@@ -30,6 +34,14 @@ public:
|
|||||||
return _elements;
|
return _elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the size in bytes of all elements in the layout structure (including their offsets).
|
||||||
|
/// </summary>
|
||||||
|
API_PROPERTY() FORCE_INLINE uint32 GetStride() const
|
||||||
|
{
|
||||||
|
return _stride;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the vertex layout for a given list of elements. Uses internal cache to skip creating layout if it's already exists for a given list.
|
/// Gets the vertex layout for a given list of elements. Uses internal cache to skip creating layout if it's already exists for a given list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -152,11 +152,10 @@ GPUVertexLayoutDX11::GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements&
|
|||||||
: GPUResourceBase<GPUDeviceDX11, GPUVertexLayout>(device, StringView::Empty)
|
: GPUResourceBase<GPUDeviceDX11, GPUVertexLayout>(device, StringView::Empty)
|
||||||
, InputElementsCount(elements.Count())
|
, InputElementsCount(elements.Count())
|
||||||
{
|
{
|
||||||
_elements = elements;
|
|
||||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||||
for (int32 i = 0; i < _elements.Count(); i++)
|
for (int32 i = 0; i < elements.Count(); i++)
|
||||||
{
|
{
|
||||||
const VertexElement& src = _elements.Get()[i];
|
const VertexElement& src = elements.Get()[i];
|
||||||
D3D11_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
D3D11_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
||||||
uint32& offset = offsets[src.Slot];
|
uint32& offset = offsets[src.Slot];
|
||||||
if (src.Offset != 0)
|
if (src.Offset != 0)
|
||||||
@@ -169,6 +168,7 @@ GPUVertexLayoutDX11::GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements&
|
|||||||
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
||||||
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
||||||
}
|
}
|
||||||
|
SetElements(elements, offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUDevice* GPUDeviceDX11::Create()
|
GPUDevice* GPUDeviceDX11::Create()
|
||||||
|
|||||||
@@ -40,11 +40,10 @@ GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements&
|
|||||||
: GPUResourceDX12<GPUVertexLayout>(device, StringView::Empty)
|
: GPUResourceDX12<GPUVertexLayout>(device, StringView::Empty)
|
||||||
, InputElementsCount(elements.Count())
|
, InputElementsCount(elements.Count())
|
||||||
{
|
{
|
||||||
_elements = elements;
|
|
||||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||||
for (int32 i = 0; i < _elements.Count(); i++)
|
for (int32 i = 0; i < elements.Count(); i++)
|
||||||
{
|
{
|
||||||
const VertexElement& src = _elements.Get()[i];
|
const VertexElement& src = elements.Get()[i];
|
||||||
D3D12_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
D3D12_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
||||||
uint32& offset = offsets[src.Slot];
|
uint32& offset = offsets[src.Slot];
|
||||||
if (src.Offset != 0)
|
if (src.Offset != 0)
|
||||||
@@ -57,6 +56,7 @@ GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements&
|
|||||||
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
||||||
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
||||||
}
|
}
|
||||||
|
SetElements(elements, offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUDevice* GPUDeviceDX12::Create()
|
GPUDevice* GPUDeviceDX12::Create()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public:
|
|||||||
GPUVertexLayoutNull(const Elements& elements)
|
GPUVertexLayoutNull(const Elements& elements)
|
||||||
: GPUVertexLayout()
|
: GPUVertexLayout()
|
||||||
{
|
{
|
||||||
_elements = elements;
|
SetElements(elements, {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -452,7 +452,6 @@ uint32 GetHash(const FramebufferVulkan::Key& key)
|
|||||||
GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements)
|
GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements)
|
||||||
: GPUResourceVulkan<GPUVertexLayout>(device, StringView::Empty)
|
: GPUResourceVulkan<GPUVertexLayout>(device, StringView::Empty)
|
||||||
{
|
{
|
||||||
_elements = elements;
|
|
||||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||||
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
||||||
{
|
{
|
||||||
@@ -462,9 +461,9 @@ GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elem
|
|||||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
}
|
}
|
||||||
uint32 bindingsCount = 0;
|
uint32 bindingsCount = 0;
|
||||||
for (int32 i = 0; i < _elements.Count(); i++)
|
for (int32 i = 0; i < elements.Count(); i++)
|
||||||
{
|
{
|
||||||
const VertexElement& src = _elements.Get()[i];
|
const VertexElement& src = elements.Get()[i];
|
||||||
uint32& offset = offsets[src.Slot];
|
uint32& offset = offsets[src.Slot];
|
||||||
if (src.Offset != 0)
|
if (src.Offset != 0)
|
||||||
offset = src.Offset;
|
offset = src.Offset;
|
||||||
@@ -485,11 +484,12 @@ GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elem
|
|||||||
bindingsCount = Math::Max(bindingsCount, (uint32)src.Slot + 1);
|
bindingsCount = Math::Max(bindingsCount, (uint32)src.Slot + 1);
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
SetElements(elements, offsets);
|
||||||
|
|
||||||
RenderToolsVulkan::ZeroStruct(CreateInfo, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
RenderToolsVulkan::ZeroStruct(CreateInfo, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||||
CreateInfo.vertexBindingDescriptionCount = bindingsCount;
|
CreateInfo.vertexBindingDescriptionCount = bindingsCount;
|
||||||
CreateInfo.pVertexBindingDescriptions = Bindings;
|
CreateInfo.pVertexBindingDescriptions = Bindings;
|
||||||
CreateInfo.vertexAttributeDescriptionCount = _elements.Count();
|
CreateInfo.vertexAttributeDescriptionCount = elements.Count();
|
||||||
CreateInfo.pVertexAttributeDescriptions = Attributes;
|
CreateInfo.pVertexAttributeDescriptions = Attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user