Add GPUVertexLayout to graphics backends
This commit is contained in:
@@ -25,6 +25,9 @@
|
||||
// Maximum amount of binded vertex buffers at the same time
|
||||
#define GPU_MAX_VB_BINDED 4
|
||||
|
||||
// Maximum amount of vertex shader input elements in a layout
|
||||
#define GPU_MAX_VS_ELEMENTS 16
|
||||
|
||||
// Maximum amount of thread groups per dimension for compute dispatch
|
||||
#define GPU_MAX_CS_DISPATCH_THREAD_GROUPS 65535
|
||||
|
||||
@@ -33,6 +36,7 @@
|
||||
|
||||
// Enable/disable assertion for graphics layers
|
||||
#define GPU_ENABLE_ASSERTION 1
|
||||
#define GPU_ENABLE_ASSERTION_LOW_LAYERS (!BUILD_RELEASE)
|
||||
|
||||
// Enable/disable dynamic textures quality streaming
|
||||
#define GPU_ENABLE_TEXTURES_STREAMING 1
|
||||
|
||||
@@ -479,6 +479,8 @@ void GPUDevice::DumpResourcesToLog() const
|
||||
LOG_STR(Info, output.ToStringView());
|
||||
}
|
||||
|
||||
extern void ClearVertexLayoutCache();
|
||||
|
||||
void GPUDevice::preDispose()
|
||||
{
|
||||
Locker.Lock();
|
||||
@@ -494,6 +496,7 @@ void GPUDevice::preDispose()
|
||||
SAFE_DELETE_GPU_RESOURCE(_res->PS_Clear);
|
||||
SAFE_DELETE_GPU_RESOURCE(_res->PS_DecodeYUY2);
|
||||
SAFE_DELETE_GPU_RESOURCE(_res->FullscreenTriangleVB);
|
||||
ClearVertexLayoutCache();
|
||||
|
||||
Locker.Unlock();
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class GPUBuffer;
|
||||
class GPUSampler;
|
||||
class GPUPipelineState;
|
||||
class GPUConstantBuffer;
|
||||
class GPUVertexLayout;
|
||||
class GPUTasksContext;
|
||||
class GPUTasksExecutor;
|
||||
class GPUSwapChain;
|
||||
@@ -396,6 +397,13 @@ public:
|
||||
/// <returns>The sampler.</returns>
|
||||
API_FUNCTION() virtual GPUSampler* CreateSampler() = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the vertex buffer layout.
|
||||
/// </summary>
|
||||
/// <returns>The vertex buffer layout.</returns>
|
||||
API_FUNCTION() virtual GPUVertexLayout* CreateVertexLayout(const Array<struct VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>>& elements) = 0;
|
||||
typedef Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>> VertexElements;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the native window swap chain.
|
||||
/// </summary>
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
#include "Engine/Core/Enums.h"
|
||||
#include "Engine/Graphics/Enums.h"
|
||||
|
||||
// [Deprecated in v1.10]
|
||||
#define INPUT_LAYOUT_ELEMENT_ALIGN 0xffffffff
|
||||
// [Deprecated in v1.10]
|
||||
#define INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA 0
|
||||
// [Deprecated in v1.10]
|
||||
#define INPUT_LAYOUT_ELEMENT_PER_INSTANCE_DATA 1
|
||||
|
||||
/// <summary>
|
||||
/// Maximum amount of input elements for vertex shader programs
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
#define VERTEX_SHADER_MAX_INPUT_ELEMENTS 16
|
||||
|
||||
@@ -26,7 +30,8 @@
|
||||
#define SHADER_PERMUTATIONS_MAX_PARAMS_COUNT 4
|
||||
|
||||
/// <summary>
|
||||
/// Maximum allowed amount of constant buffers that can be binded to the pipeline (maximum slot index is MAX_CONSTANT_BUFFER_SLOTS-1)
|
||||
/// Maximum allowed amount of constant buffers that can be binded to the pipeline (maximum slot index is MAX_CONSTANT_BUFFER_SLOTS-1)
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
#define MAX_CONSTANT_BUFFER_SLOTS 4
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
|
||||
static FORCE_INLINE uint32 HashPermutation(const StringAnsiView& name, int32 permutationIndex)
|
||||
@@ -12,6 +13,21 @@ static FORCE_INLINE uint32 HashPermutation(const StringAnsiView& name, int32 per
|
||||
return GetHash(name) * 37 + permutationIndex;
|
||||
}
|
||||
|
||||
void GPUShaderProgram::Init(const GPUShaderProgramInitializer& initializer)
|
||||
{
|
||||
_name = initializer.Name;
|
||||
_bindings = initializer.Bindings;
|
||||
_flags = initializer.Flags;
|
||||
#if !BUILD_RELEASE
|
||||
_owner = initializer.Owner;
|
||||
#endif
|
||||
}
|
||||
|
||||
GPUShaderProgramVS::~GPUShaderProgramVS()
|
||||
{
|
||||
SAFE_DELETE(Layout);
|
||||
}
|
||||
|
||||
GPUShader::GPUShader()
|
||||
: GPUResource(SpawnParams(Guid::New(), TypeInitializer))
|
||||
{
|
||||
@@ -104,33 +120,32 @@ bool GPUShader::Create(MemoryReadStream& stream)
|
||||
|
||||
// Constant Buffers
|
||||
const byte constantBuffersCount = stream.ReadByte();
|
||||
const byte maximumConstantBufferSlot = stream.ReadByte();
|
||||
if (constantBuffersCount > 0)
|
||||
for (int32 i = 0; i < constantBuffersCount; i++)
|
||||
{
|
||||
ASSERT(maximumConstantBufferSlot < MAX_CONSTANT_BUFFER_SLOTS);
|
||||
|
||||
for (int32 i = 0; i < constantBuffersCount; i++)
|
||||
// Load info
|
||||
const byte slotIndex = stream.ReadByte();
|
||||
if (slotIndex >= GPU_MAX_CB_BINDED)
|
||||
{
|
||||
// Load info
|
||||
const byte slotIndex = stream.ReadByte();
|
||||
uint32 size;
|
||||
stream.ReadUint32(&size);
|
||||
|
||||
// Create CB
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
String name = String::Format(TEXT("{}.CB{}"), ToString(), i);
|
||||
#else
|
||||
String name;
|
||||
#endif
|
||||
ASSERT(_constantBuffers[slotIndex] == nullptr);
|
||||
const auto cb = GPUDevice::Instance->CreateConstantBuffer(size, name);
|
||||
if (cb == nullptr)
|
||||
{
|
||||
LOG(Warning, "Failed to create shader constant buffer.");
|
||||
return true;
|
||||
}
|
||||
_constantBuffers[slotIndex] = cb;
|
||||
LOG(Warning, "Failed to create shader constant buffer.");
|
||||
return true;
|
||||
}
|
||||
uint32 size;
|
||||
stream.ReadUint32(&size);
|
||||
|
||||
// Create CB
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
String cbName = String::Format(TEXT("{}.CB{}"), ToString(), i);
|
||||
#else
|
||||
String cbName;
|
||||
#endif
|
||||
ASSERT(_constantBuffers[slotIndex] == nullptr);
|
||||
const auto cb = GPUDevice::Instance->CreateConstantBuffer(size, cbName);
|
||||
if (cb == nullptr)
|
||||
{
|
||||
LOG(Warning, "Failed to create shader constant buffer.");
|
||||
return true;
|
||||
}
|
||||
_constantBuffers[slotIndex] = cb;
|
||||
}
|
||||
|
||||
// Don't read additional data
|
||||
|
||||
@@ -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 9
|
||||
#define GPU_SHADER_CACHE_VERSION 10
|
||||
|
||||
/// <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.
|
||||
@@ -23,7 +23,7 @@ API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUShader : public GPUResource
|
||||
|
||||
protected:
|
||||
Dictionary<uint32, GPUShaderProgram*> _shaders;
|
||||
GPUConstantBuffer* _constantBuffers[MAX_CONSTANT_BUFFER_SLOTS];
|
||||
GPUConstantBuffer* _constantBuffers[GPU_MAX_CB_BINDED];
|
||||
|
||||
GPUShader();
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Config.h"
|
||||
|
||||
class GPUShader;
|
||||
class GPUVertexLayout;
|
||||
|
||||
/// <summary>
|
||||
/// The shader program metadata container. Contains description about resources used by the shader.
|
||||
@@ -18,17 +19,17 @@ struct FLAXENGINE_API ShaderBindings
|
||||
uint32 UsedSRsMask;
|
||||
uint32 UsedUAsMask;
|
||||
|
||||
bool IsUsingCB(uint32 slotIndex) const
|
||||
FORCE_INLINE bool IsUsingCB(uint32 slotIndex) const
|
||||
{
|
||||
return (UsedCBsMask & (1u << slotIndex)) != 0u;
|
||||
}
|
||||
|
||||
bool IsUsingSR(uint32 slotIndex) const
|
||||
FORCE_INLINE bool IsUsingSR(uint32 slotIndex) const
|
||||
{
|
||||
return (UsedSRsMask & (1u << slotIndex)) != 0u;
|
||||
}
|
||||
|
||||
bool IsUsingUA(uint32 slotIndex) const
|
||||
FORCE_INLINE bool IsUsingUA(uint32 slotIndex) const
|
||||
{
|
||||
return (UsedUAsMask & (1u << slotIndex)) != 0u;
|
||||
}
|
||||
@@ -57,15 +58,7 @@ protected:
|
||||
GPUShader* _owner;
|
||||
#endif
|
||||
|
||||
void Init(const GPUShaderProgramInitializer& initializer)
|
||||
{
|
||||
_name = initializer.Name;
|
||||
_bindings = initializer.Bindings;
|
||||
_flags = initializer.Flags;
|
||||
#if !BUILD_RELEASE
|
||||
_owner = initializer.Owner;
|
||||
#endif
|
||||
}
|
||||
void Init(const GPUShaderProgramInitializer& initializer);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -122,8 +115,18 @@ 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]
|
||||
PACK_STRUCT(struct InputElement
|
||||
{
|
||||
byte Type; // VertexShaderMeta::InputType
|
||||
@@ -135,14 +138,15 @@ public:
|
||||
uint32 InstanceDataStepRate; // 0 if per-vertex
|
||||
});
|
||||
|
||||
public:
|
||||
/// <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;
|
||||
|
||||
@@ -173,7 +177,7 @@ public:
|
||||
class GPUShaderProgramHS : public GPUShaderProgram
|
||||
{
|
||||
protected:
|
||||
int32 _controlPointsCount;
|
||||
int32 _controlPointsCount = 0;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
103
Source/Engine/Graphics/Shaders/GPUVertexLayout.cpp
Normal file
103
Source/Engine/Graphics/Shaders/GPUVertexLayout.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "GPUVertexLayout.h"
|
||||
#if GPU_ENABLE_ASSERTION_LOW_LAYERS
|
||||
#include "Engine/Core/Log.h"
|
||||
#endif
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
#include "Engine/Scripting/Enums.h"
|
||||
#endif
|
||||
|
||||
// VertexElement has been designed to be POD and memory-comparable for faster hashing and comparision.
|
||||
struct VertexElementRaw
|
||||
{
|
||||
uint32 Words[2];
|
||||
};
|
||||
|
||||
static_assert(sizeof(VertexElement) == sizeof(VertexElementRaw), "Incorrect size of the VertexElement!");
|
||||
|
||||
namespace
|
||||
{
|
||||
CriticalSection CacheLocker;
|
||||
Dictionary<uint32, GPUVertexLayout*> LayoutCache;
|
||||
}
|
||||
|
||||
String VertexElement::ToString() const
|
||||
{
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
return String::Format(TEXT("{}, format {}, offset {}, per-instance {}, slot {}"), ScriptingEnum::ToString(Type), ScriptingEnum::ToString(Format), Offset, PerInstance, Slot);
|
||||
#else
|
||||
return TEXT("VertexElement");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool VertexElement::operator==(const VertexElement& other) const
|
||||
{
|
||||
auto thisRaw = (const VertexElementRaw*)this;
|
||||
auto otherRaw = (const VertexElementRaw*)&other;
|
||||
return thisRaw->Words[0] == otherRaw->Words[0] && thisRaw->Words[1] == otherRaw->Words[1];
|
||||
}
|
||||
|
||||
uint32 GetHash(const VertexElement& key)
|
||||
{
|
||||
auto keyRaw = (const VertexElementRaw*)&key;
|
||||
uint32 hash = keyRaw->Words[0];
|
||||
CombineHash(hash, keyRaw->Words[1]);
|
||||
return hash;
|
||||
}
|
||||
|
||||
GPUVertexLayout::GPUVertexLayout()
|
||||
: GPUResource(SpawnParams(Guid::New(), TypeInitializer))
|
||||
{
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUVertexLayout::Get(const Elements& elements)
|
||||
{
|
||||
// Hash input layout
|
||||
uint32 hash = 0;
|
||||
for (const VertexElement& element : elements)
|
||||
{
|
||||
CombineHash(hash, GetHash(element));
|
||||
}
|
||||
|
||||
// Lookup existing cache
|
||||
CacheLocker.Lock();
|
||||
GPUVertexLayout* result;
|
||||
if (!LayoutCache.TryGet(hash, result))
|
||||
{
|
||||
result = GPUDevice::Instance->CreateVertexLayout(elements);
|
||||
if (!result)
|
||||
{
|
||||
#if GPU_ENABLE_ASSERTION_LOW_LAYERS
|
||||
for (auto& e : elements)
|
||||
LOG(Error, " {}", e.ToString());
|
||||
#endif
|
||||
LOG(Error, "Failed to create vertex layout");
|
||||
CacheLocker.Unlock();
|
||||
return nullptr;
|
||||
}
|
||||
LayoutCache.Add(hash, result);
|
||||
}
|
||||
#if GPU_ENABLE_ASSERTION_LOW_LAYERS
|
||||
else if (result->GetElements() != elements)
|
||||
{
|
||||
for (auto& e : result->GetElements())
|
||||
LOG(Error, " (a) {}", e.ToString());
|
||||
for (auto& e : elements)
|
||||
LOG(Error, " (b) {}", e.ToString());
|
||||
LOG(Fatal, "Vertex layout cache collision for hash {}", hash);
|
||||
}
|
||||
#endif
|
||||
CacheLocker.Unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ClearVertexLayoutCache()
|
||||
{
|
||||
for (const auto& e : LayoutCache)
|
||||
Delete(e.Value);
|
||||
LayoutCache.Clear();
|
||||
}
|
||||
44
Source/Engine/Graphics/Shaders/GPUVertexLayout.h
Normal file
44
Source/Engine/Graphics/Shaders/GPUVertexLayout.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "VertexElement.h"
|
||||
#include "Engine/Graphics/GPUResource.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
|
||||
/// <summary>
|
||||
/// Defines input layout of vertex buffer data passed to the Vertex Shader.
|
||||
/// </summary>
|
||||
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUVertexLayout : public GPUResource
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUVertexLayout);
|
||||
typedef Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>> Elements;
|
||||
|
||||
protected:
|
||||
Elements _elements;
|
||||
|
||||
GPUVertexLayout();
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the list of elements used by this layout.
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE const Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>>& GetElements() const
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="elements">The list of elements 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 Array<VertexElement, FixedAllocation<GPU_MAX_VS_ELEMENTS>>& elements);
|
||||
|
||||
public:
|
||||
// [GPUResource]
|
||||
GPUResourceType GetResourceType() const override
|
||||
{
|
||||
return GPUResourceType::Descriptor;
|
||||
}
|
||||
};
|
||||
86
Source/Engine/Graphics/Shaders/VertexElement.h
Normal file
86
Source/Engine/Graphics/Shaders/VertexElement.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Graphics/PixelFormat.h"
|
||||
|
||||
/// <summary>
|
||||
/// Vertex buffer data element. Defines access to data passed to Vertex Shader.
|
||||
/// </summary>
|
||||
API_STRUCT(NoDefault)
|
||||
PACK_BEGIN() struct FLAXENGINE_API VertexElement
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(VertexElement);
|
||||
|
||||
/// <summary>
|
||||
/// Types of vertex elements.
|
||||
/// </summary>
|
||||
API_ENUM() enum class Types : byte
|
||||
{
|
||||
// Undefined.
|
||||
Unknown = 0,
|
||||
// Vertex position.
|
||||
Position = 1,
|
||||
// Vertex color.
|
||||
Color = 2,
|
||||
// Vertex normal vector.
|
||||
Normal = 3,
|
||||
// Vertex tangent vector.
|
||||
Tangent = 4,
|
||||
// Skinned bone blend indices.
|
||||
BlendIndices = 5,
|
||||
// Skinned bone blend weights.
|
||||
BlendWeight = 6,
|
||||
// Primary texture coordinate (UV).
|
||||
TexCoord0 = 7,
|
||||
// Additional texture coordinate (UV1).
|
||||
TexCoord1 = 8,
|
||||
// Additional texture coordinate (UV2).
|
||||
TexCoord2 = 9,
|
||||
// Additional texture coordinate (UV3).
|
||||
TexCoord3 = 10,
|
||||
// Additional texture coordinate (UV4).
|
||||
TexCoord4 = 11,
|
||||
// Additional texture coordinate (UV5).
|
||||
TexCoord5 = 12,
|
||||
// Additional texture coordinate (UV6).
|
||||
TexCoord6 = 13,
|
||||
// Additional texture coordinate (UV7).
|
||||
TexCoord7 = 14,
|
||||
// General purpose attribute (at index 0).
|
||||
Attribute0 = 15,
|
||||
// General purpose attribute (at index 1).
|
||||
Attribute1 = 16,
|
||||
// General purpose attribute (at index 2).
|
||||
Attribute2 = 17,
|
||||
// General purpose attribute (at index 3).
|
||||
Attribute3 = 18,
|
||||
// Texture coordinate.
|
||||
TexCoord = TexCoord0,
|
||||
// General purpose attribute.
|
||||
Attribute = Attribute0,
|
||||
MAX
|
||||
};
|
||||
|
||||
// Type of the vertex element data.
|
||||
Types Type;
|
||||
// Index of the input vertex buffer slot (as provided in GPUContext::BindVB).
|
||||
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;
|
||||
// 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;
|
||||
// Format of the vertex element data.
|
||||
PixelFormat Format;
|
||||
|
||||
String ToString() const;
|
||||
|
||||
bool operator==(const VertexElement& other) const;
|
||||
|
||||
FORCE_INLINE bool operator!=(const VertexElement& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
} PACK_END();
|
||||
|
||||
uint32 FLAXENGINE_API GetHash(const VertexElement& key);
|
||||
@@ -10,11 +10,13 @@
|
||||
#include "GPUTimerQueryDX11.h"
|
||||
#include "GPUBufferDX11.h"
|
||||
#include "GPUSamplerDX11.h"
|
||||
#include "GPUVertexLayoutDX11.h"
|
||||
#include "GPUSwapChainDX11.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Utilities.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
#include "Engine/Engine/CommandLine.h"
|
||||
|
||||
#if !USE_EDITOR && PLATFORM_WINDOWS
|
||||
@@ -146,6 +148,29 @@ static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureL
|
||||
return false;
|
||||
}
|
||||
|
||||
GPUVertexLayoutDX11::GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements& elements)
|
||||
: GPUResourceBase<GPUDeviceDX11, GPUVertexLayout>(device, StringView::Empty)
|
||||
, InputElementsCount(elements.Count())
|
||||
{
|
||||
_elements = elements;
|
||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||
for (int32 i = 0; i < _elements.Count(); i++)
|
||||
{
|
||||
const VertexElement& src = _elements.Get()[i];
|
||||
D3D11_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
||||
uint32& offset = offsets[src.Slot];
|
||||
if (src.Offset != 0)
|
||||
offset = src.Offset;
|
||||
dst.SemanticName = RenderToolsDX::GetVertexInputSemantic(src.Type, dst.SemanticIndex);
|
||||
dst.Format = RenderToolsDX::ToDxgiFormat(src.Format);
|
||||
dst.InputSlot = src.Slot;
|
||||
dst.AlignedByteOffset = offset;
|
||||
dst.InputSlotClass = src.PerInstance ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
|
||||
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
||||
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
}
|
||||
}
|
||||
|
||||
GPUDevice* GPUDeviceDX11::Create()
|
||||
{
|
||||
// Configuration
|
||||
@@ -807,6 +832,11 @@ GPUSampler* GPUDeviceDX11::CreateSampler()
|
||||
return New<GPUSamplerDX11>(this);
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceDX11::CreateVertexLayout(const VertexElements& elements)
|
||||
{
|
||||
return New<GPUVertexLayoutDX11>(this, elements);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceDX11::CreateSwapChain(Window* window)
|
||||
{
|
||||
return New<GPUSwapChainDX11>(this, window);
|
||||
|
||||
@@ -128,6 +128,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
class GPUConstantBufferDX11 : public GPUResourceDX11<GPUConstantBuffer>
|
||||
{
|
||||
private:
|
||||
|
||||
ID3D11Buffer* _resource;
|
||||
|
||||
public:
|
||||
@@ -36,7 +35,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the constant buffer object.
|
||||
/// </summary>
|
||||
@@ -47,7 +45,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// [GPUResourceDX11]
|
||||
ID3D11Resource* GetResource() override
|
||||
{
|
||||
@@ -55,7 +52,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// [GPUResourceDX11]
|
||||
void OnReleaseGPU() final override
|
||||
{
|
||||
@@ -69,11 +65,9 @@ public:
|
||||
class GPUShaderDX11 : public GPUResourceDX11<GPUShader>
|
||||
{
|
||||
private:
|
||||
|
||||
Array<GPUConstantBufferDX11, FixedAllocation<MAX_CONSTANT_BUFFER_SLOTS>> _cbs;
|
||||
Array<GPUConstantBufferDX11, FixedAllocation<GPU_MAX_CB_BINDED>> _cbs;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GPUShaderDX11"/> class.
|
||||
/// </summary>
|
||||
@@ -85,13 +79,11 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// [GPUShader]
|
||||
GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, byte* cacheBytes, uint32 cacheSize, MemoryReadStream& stream) override;
|
||||
void OnReleaseGPU() override;
|
||||
|
||||
public:
|
||||
|
||||
// [GPUResourceDX11]
|
||||
ID3D11Resource* GetResource() final override
|
||||
{
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if GRAPHICS_API_DIRECTX11
|
||||
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "GPUDeviceDX11.h"
|
||||
|
||||
/// <summary>
|
||||
/// Vertex layout object for DirectX 11 backend.
|
||||
/// </summary>
|
||||
class GPUVertexLayoutDX11 : public GPUResourceBase<GPUDeviceDX11, GPUVertexLayout>
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements& elements);
|
||||
|
||||
uint32 InputElementsCount;
|
||||
D3D11_INPUT_ELEMENT_DESC InputElements[GPU_MAX_VS_ELEMENTS];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,10 +10,12 @@
|
||||
#include "GPUTimerQueryDX12.h"
|
||||
#include "GPUBufferDX12.h"
|
||||
#include "GPUSamplerDX12.h"
|
||||
#include "GPUVertexLayoutDX12.h"
|
||||
#include "GPUSwapChainDX12.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Engine/CommandLine.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
@@ -34,6 +36,29 @@ static bool CheckDX12Support(IDXGIAdapter* adapter)
|
||||
return false;
|
||||
}
|
||||
|
||||
GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements)
|
||||
: GPUResourceDX12<GPUVertexLayout>(device, StringView::Empty)
|
||||
, InputElementsCount(elements.Count())
|
||||
{
|
||||
_elements = elements;
|
||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||
for (int32 i = 0; i < _elements.Count(); i++)
|
||||
{
|
||||
const VertexElement& src = _elements.Get()[i];
|
||||
D3D12_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
||||
uint32& offset = offsets[src.Slot];
|
||||
if (src.Offset != 0)
|
||||
offset = src.Offset;
|
||||
dst.SemanticName = RenderToolsDX::GetVertexInputSemantic(src.Type, dst.SemanticIndex);
|
||||
dst.Format = RenderToolsDX::ToDxgiFormat(src.Format);
|
||||
dst.InputSlot = src.Slot;
|
||||
dst.AlignedByteOffset = offset;
|
||||
dst.InputSlotClass = src.PerInstance ? D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA : D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
||||
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
}
|
||||
}
|
||||
|
||||
GPUDevice* GPUDeviceDX12::Create()
|
||||
{
|
||||
#if PLATFORM_XBOX_SCARLETT || PLATFORM_XBOX_ONE
|
||||
@@ -843,6 +868,11 @@ GPUSampler* GPUDeviceDX12::CreateSampler()
|
||||
return New<GPUSamplerDX12>(this);
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceDX12::CreateVertexLayout(const VertexElements& elements)
|
||||
{
|
||||
return New<GPUVertexLayoutDX12>(this, elements);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceDX12::CreateSwapChain(Window* window)
|
||||
{
|
||||
return New<GPUSwapChainDX12>(this, window);
|
||||
|
||||
@@ -196,6 +196,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
@@ -22,7 +22,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Last uploaded data address.
|
||||
/// </summary>
|
||||
@@ -35,7 +34,6 @@ public:
|
||||
class GPUShaderDX12 : public GPUResourceDX12<GPUShader>
|
||||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GPUShaderDX12"/> class.
|
||||
/// </summary>
|
||||
@@ -47,7 +45,6 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// [GPUShader]
|
||||
GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, byte* cacheBytes, uint32 cacheSize, MemoryReadStream& stream) override;
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
{
|
||||
return (void*)_data.Get();
|
||||
}
|
||||
|
||||
uint32 GetBufferSize() const override
|
||||
{
|
||||
return _data.Count();
|
||||
@@ -65,6 +66,7 @@ public:
|
||||
{
|
||||
return (void*)_inputLayout;
|
||||
}
|
||||
|
||||
byte GetInputLayoutSize() const override
|
||||
{
|
||||
return _inputLayoutSize;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if GRAPHICS_API_DIRECTX12
|
||||
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "GPUDeviceDX12.h"
|
||||
|
||||
/// <summary>
|
||||
/// Vertex layout object for DirectX 12 backend.
|
||||
/// </summary>
|
||||
class GPUVertexLayoutDX12 : public GPUResourceDX12<GPUVertexLayout>
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements);
|
||||
|
||||
uint32 InputElementsCount;
|
||||
D3D12_INPUT_ELEMENT_DESC InputElements[GPU_MAX_VS_ELEMENTS];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -273,4 +273,62 @@ String RenderToolsDX::GetD3DErrorString(HRESULT errorCode)
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
LPCSTR RenderToolsDX::GetVertexInputSemantic(VertexElement::Types type, UINT& semanticIndex)
|
||||
{
|
||||
static_assert((int32)VertexElement::Types::MAX == 16, "Update code below.");
|
||||
semanticIndex = 0;
|
||||
switch (type)
|
||||
{
|
||||
case VertexElement::Types::Position:
|
||||
return "POSITION";
|
||||
case VertexElement::Types::Color:
|
||||
return "COLOR";
|
||||
case VertexElement::Types::Normal:
|
||||
return "NORMAL";
|
||||
case VertexElement::Types::Tangent:
|
||||
return "TANGENT";
|
||||
case VertexElement::Types::BlendIndices:
|
||||
return "BLENDINDICES";
|
||||
case VertexElement::Types::BlendWeight:
|
||||
return "BLENDWEIGHT";
|
||||
case VertexElement::Types::TexCoord0:
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord1:
|
||||
semanticIndex = 1;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord2:
|
||||
semanticIndex = 2;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord3:
|
||||
semanticIndex = 3;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord4:
|
||||
semanticIndex = 4;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord5:
|
||||
semanticIndex = 5;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord6:
|
||||
semanticIndex = 6;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::TexCoord7:
|
||||
semanticIndex = 7;
|
||||
return "TEXCOORD";
|
||||
case VertexElement::Types::Attribute0:
|
||||
return "ATTRIBUTE";
|
||||
case VertexElement::Types::Attribute1:
|
||||
semanticIndex = 1;
|
||||
return "ATTRIBUTE";
|
||||
case VertexElement::Types::Attribute2:
|
||||
semanticIndex = 2;
|
||||
return "ATTRIBUTE";
|
||||
case VertexElement::Types::Attribute3:
|
||||
semanticIndex = 3;
|
||||
return "ATTRIBUTE";
|
||||
default:
|
||||
LOG(Fatal, "Invalid vertex shader element semantic type");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Graphics//RenderTools.h"
|
||||
#include "Engine/Graphics/Enums.h"
|
||||
#include "Engine/Graphics/Shaders/VertexElement.h"
|
||||
#include "IncludeDirectXHeaders.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
|
||||
@@ -112,6 +113,8 @@ namespace RenderToolsDX
|
||||
const String& errorString = GetD3DErrorString(result);
|
||||
LOG(Error, "DirectX error: {0} at {1}:{2}", errorString, String(file), line);
|
||||
}
|
||||
|
||||
LPCSTR GetVertexInputSemantic(VertexElement::Types type, UINT& semanticIndex);
|
||||
};
|
||||
|
||||
#if GPU_ENABLE_ASSERTION
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "GPUTimerQueryNull.h"
|
||||
#include "GPUBufferNull.h"
|
||||
#include "GPUSamplerNull.h"
|
||||
#include "GPUVertexLayoutNull.h"
|
||||
#include "GPUSwapChainNull.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Graphics/Async/GPUTasksManager.h"
|
||||
@@ -172,6 +173,11 @@ GPUSampler* GPUDeviceNull::CreateSampler()
|
||||
return New<GPUSamplerNull>();
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceNull::CreateVertexLayout(const VertexElements& elements)
|
||||
{
|
||||
return New<GPUVertexLayoutNull>(elements);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceNull::CreateSwapChain(Window* window)
|
||||
{
|
||||
return New<GPUSwapChainNull>(window);
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
22
Source/Engine/GraphicsDevice/Null/GPUVertexLayoutNull.h
Normal file
22
Source/Engine/GraphicsDevice/Null/GPUVertexLayoutNull.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if GRAPHICS_API_NULL
|
||||
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
|
||||
/// <summary>
|
||||
/// Vertex layout for Null backend.
|
||||
/// </summary>
|
||||
class GPUVertexLayoutNull : public GPUVertexLayout
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutNull(const Elements& elements)
|
||||
: GPUVertexLayout()
|
||||
{
|
||||
_elements = elements;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "GPUTimerQueryVulkan.h"
|
||||
#include "GPUBufferVulkan.h"
|
||||
#include "GPUSamplerVulkan.h"
|
||||
#include "GPUVertexLayoutVulkan.h"
|
||||
#include "GPUSwapChainVulkan.h"
|
||||
#include "RenderToolsVulkan.h"
|
||||
#include "QueueVulkan.h"
|
||||
@@ -448,6 +449,50 @@ uint32 GetHash(const FramebufferVulkan::Key& key)
|
||||
return hash;
|
||||
}
|
||||
|
||||
GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements)
|
||||
: GPUResourceVulkan<GPUVertexLayout>(device, StringView::Empty)
|
||||
{
|
||||
_elements = elements;
|
||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
||||
{
|
||||
VkVertexInputBindingDescription& binding = Bindings[i];
|
||||
binding.binding = i;
|
||||
binding.stride = 0;
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
}
|
||||
uint32 bindingsCount = 0;
|
||||
for (int32 i = 0; i < _elements.Count(); i++)
|
||||
{
|
||||
const VertexElement& src = _elements.Get()[i];
|
||||
uint32& offset = offsets[src.Slot];
|
||||
if (src.Offset != 0)
|
||||
offset = src.Offset;
|
||||
const int32 size = PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
|
||||
ASSERT_LOW_LAYER(src.Slot < GPU_MAX_VB_BINDED);
|
||||
VkVertexInputBindingDescription& binding = Bindings[src.Slot];
|
||||
binding.binding = src.Slot;
|
||||
binding.stride = Math::Max(binding.stride, (uint32_t)(offset + size));
|
||||
binding.inputRate = src.PerInstance ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkVertexInputAttributeDescription& attribute = Attributes[i];
|
||||
attribute.location = i;
|
||||
attribute.binding = src.Slot;
|
||||
attribute.format = RenderToolsVulkan::ToVulkanFormat(src.Format);
|
||||
attribute.offset = offset;
|
||||
|
||||
bindingsCount = Math::Max(bindingsCount, (uint32)src.Slot + 1);
|
||||
offset += size;
|
||||
}
|
||||
|
||||
RenderToolsVulkan::ZeroStruct(CreateInfo, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
CreateInfo.vertexBindingDescriptionCount = bindingsCount;
|
||||
CreateInfo.pVertexBindingDescriptions = Bindings;
|
||||
CreateInfo.vertexAttributeDescriptionCount = _elements.Count();
|
||||
CreateInfo.pVertexAttributeDescriptions = Attributes;
|
||||
}
|
||||
|
||||
FramebufferVulkan::FramebufferVulkan(GPUDeviceVulkan* device, const Key& key, const VkExtent2D& extent, uint32 layers)
|
||||
: Device(device)
|
||||
, Handle(VK_NULL_HANDLE)
|
||||
@@ -2072,6 +2117,11 @@ GPUSampler* GPUDeviceVulkan::CreateSampler()
|
||||
return New<GPUSamplerVulkan>(this);
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceVulkan::CreateVertexLayout(const VertexElements& elements)
|
||||
{
|
||||
return New<GPUVertexLayoutVulkan>(this, elements);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceVulkan::CreateSwapChain(Window* window)
|
||||
{
|
||||
return New<GPUSwapChainVulkan>(this, window);
|
||||
|
||||
@@ -610,6 +610,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
23
Source/Engine/GraphicsDevice/Vulkan/GPUVertexLayoutVulkan.h
Normal file
23
Source/Engine/GraphicsDevice/Vulkan/GPUVertexLayoutVulkan.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if GRAPHICS_API_VULKAN
|
||||
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
#include "GPUDeviceVulkan.h"
|
||||
|
||||
/// <summary>
|
||||
/// Vertex layout object for Vulkan backend.
|
||||
/// </summary>
|
||||
class GPUVertexLayoutVulkan : public GPUResourceVulkan<GPUVertexLayout>
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements);
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo CreateInfo;
|
||||
VkVertexInputBindingDescription Bindings[GPU_MAX_VB_BINDED];
|
||||
VkVertexInputAttributeDescription Attributes[GPU_MAX_VS_ELEMENTS];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ShaderFunctionReader.h"
|
||||
#include "Engine/Graphics/Config.h"
|
||||
|
||||
#if COMPILE_WITH_SHADER_COMPILER
|
||||
|
||||
@@ -115,9 +116,9 @@ namespace ShaderProcessing
|
||||
for (int32 i = 0; i < _cache.Count(); i++)
|
||||
{
|
||||
auto& f = _cache[i];
|
||||
if (f.Slot >= MAX_CONSTANT_BUFFER_SLOTS)
|
||||
if (f.Slot >= GPU_MAX_CB_BINDED)
|
||||
{
|
||||
parser->OnError(String::Format(TEXT("Constant buffer {0} is using invalid slot {1}. Maximum supported slot is {2}."), String(f.Name), f.Slot, MAX_CONSTANT_BUFFER_SLOTS - 1));
|
||||
parser->OnError(String::Format(TEXT("Constant buffer {0} is using invalid slot {1}. Maximum supported slot is {2}."), String(f.Name), f.Slot, GPU_MAX_CB_BINDED - 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,14 +30,12 @@ struct ShaderPermutation
|
||||
class ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Virtual destructor
|
||||
/// </summary>
|
||||
virtual ~ShaderFunctionMeta() = default;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Function name
|
||||
/// </summary>
|
||||
@@ -59,7 +57,6 @@ public:
|
||||
Array<ShaderPermutation> Permutations;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Checks if definition name has been added to the given permutation
|
||||
/// </summary>
|
||||
@@ -117,7 +114,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets shader function meta stage type.
|
||||
/// </summary>
|
||||
@@ -130,9 +126,9 @@ public:
|
||||
class VertexShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Input element type
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
enum class InputType : byte
|
||||
{
|
||||
@@ -150,6 +146,7 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Input element
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
struct InputElement
|
||||
{
|
||||
@@ -195,14 +192,13 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Input layout description
|
||||
/// [Deprecated in v1.10]
|
||||
/// </summary>
|
||||
Array<InputElement> InputLayout;
|
||||
|
||||
public:
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -216,14 +212,12 @@ public:
|
||||
class HullShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The input control points count (valid range: 1-32).
|
||||
/// </summary>
|
||||
int32 ControlPointsCount;
|
||||
|
||||
public:
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -237,7 +231,6 @@ public:
|
||||
class DomainShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -251,7 +244,6 @@ public:
|
||||
class GeometryShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -265,7 +257,6 @@ public:
|
||||
class PixelShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -279,7 +270,6 @@ public:
|
||||
class ComputeShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -309,7 +299,6 @@ struct ConstantBufferMeta
|
||||
class ShaderMeta
|
||||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Vertex Shaders
|
||||
/// </summary>
|
||||
@@ -346,18 +335,16 @@ public:
|
||||
Array<ConstantBufferMeta> CB;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets amount of shaders attached (not counting permutations)
|
||||
/// Gets amount of shaders attached (not counting permutations).
|
||||
/// </summary>
|
||||
/// <returns>Amount of all shader programs</returns>
|
||||
uint32 GetShadersCount() const
|
||||
int32 GetShadersCount() const
|
||||
{
|
||||
return VS.Count() + HS.Count() + DS.Count() + GS.Count() + PS.Count() + CS.Count();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all shader functions (all types)
|
||||
/// Gets all shader functions (all types).
|
||||
/// </summary>
|
||||
/// <param name="functions">Output collections of functions</param>
|
||||
void GetShaders(Array<const ShaderFunctionMeta*>& functions) const
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "ShadersCompilation.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Platform/File.h"
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
@@ -14,7 +13,6 @@
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
#include "Engine/Utilities/StringConverter.h"
|
||||
|
||||
namespace IncludedFiles
|
||||
{
|
||||
@@ -68,24 +66,12 @@ bool ShaderCompiler::Compile(ShaderCompilationContext* context)
|
||||
|
||||
// [Output] Constant Buffers
|
||||
{
|
||||
const int32 cbsCount = _constantBuffers.Count();
|
||||
ASSERT(cbsCount == meta->CB.Count());
|
||||
|
||||
// Find maximum used slot index
|
||||
byte maxCbSlot = 0;
|
||||
for (int32 i = 0; i < cbsCount; i++)
|
||||
ASSERT(_constantBuffers.Count() == meta->CB.Count());
|
||||
output->WriteByte((byte)_constantBuffers.Count());
|
||||
for (const ShaderResourceBuffer& cb : _constantBuffers)
|
||||
{
|
||||
maxCbSlot = Math::Max(maxCbSlot, _constantBuffers[i].Slot);
|
||||
}
|
||||
|
||||
output->WriteByte(static_cast<byte>(cbsCount));
|
||||
output->WriteByte(maxCbSlot);
|
||||
// TODO: do we still need to serialize max cb slot?
|
||||
|
||||
for (int32 i = 0; i < cbsCount; i++)
|
||||
{
|
||||
output->WriteByte(_constantBuffers[i].Slot);
|
||||
output->WriteUint32(_constantBuffers[i].Size);
|
||||
output->WriteByte(cb.Slot);
|
||||
output->WriteUint32(cb.Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1254,6 +1254,11 @@ namespace Flax.Build.Bindings
|
||||
|
||||
// Read 'struct' keyword
|
||||
var token = context.Tokenizer.NextToken();
|
||||
if (token.Value == "PACK_BEGIN")
|
||||
{
|
||||
context.Tokenizer.SkipUntil(TokenType.RightParent);
|
||||
token = context.Tokenizer.NextToken();
|
||||
}
|
||||
if (token.Value != "struct")
|
||||
throw new ParseException(ref context, $"Invalid {ApiTokens.Struct} usage (expected 'struct' keyword but got '{token.Value} {context.Tokenizer.NextToken().Value}').");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user