Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support non-normalized, non-float vertex buffers and unaligned vertex buffers #1382

Merged
merged 6 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Apps/Playground/Scripts/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,11 @@
"title": "CesiumMan from Khronos Sample Assets",
"playgroundId": "#4GWX8M",
"referenceImage": "CesiumMan.png"
},
{
"title": "Two vertex buffers pointing to one buffer",
"playgroundId": "#RZNHXT#7",
"referenceImage": "two-vertex-buffers.png"
}
]
}
86 changes: 43 additions & 43 deletions Apps/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Apps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
"getNightly": "node scripts/getNightly.js"
},
"dependencies": {
"babylonjs": "^7.6.2",
"babylonjs-gltf2interface": "^7.6.2",
"babylonjs-gui": "^7.6.2",
"babylonjs-loaders": "^7.6.2",
"babylonjs-materials": "^7.6.2",
"babylonjs": "^7.7.2",
"babylonjs-gltf2interface": "^7.7.2",
"babylonjs-gui": "^7.7.2",
"babylonjs-loaders": "^7.7.2",
"babylonjs-materials": "^7.7.2",
"chai": "^4.3.4",
"jsc-android": "^241213.1.0",
"mocha": "^9.2.2",
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ FetchContent_Declare(OpenXR-SDK
GIT_TAG 458984d7f59d1ae6dc1b597d94b02e4f7132eaba)
FetchContent_Declare(SPIRV-Cross
GIT_REPOSITORY https://github.com/BabylonJS/SPIRV-Cross.git
GIT_TAG 014d1ebe42c4177520fbcfd1e9a17238e532f1a6)
GIT_TAG 578a291759db6fe7c3f4735d3512c0526ad18efc)
# --------------------------------------------------

FetchContent_MakeAvailable(CMakeExtensions)
Expand Down
9 changes: 7 additions & 2 deletions Core/Graphics/Source/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
namespace Babylon::Graphics
{
Texture::Texture(DeviceContext& deviceContext)
: m_deviceID{deviceContext.GetDeviceId()}
, m_deviceContext{deviceContext}
: m_deviceID{deviceContext.GetDeviceId()}
, m_deviceContext{deviceContext}
{
}

Expand Down Expand Up @@ -36,6 +36,11 @@ namespace Babylon::Graphics

// Always create with BGFX_TEXTURE_BLIT_DST to match web behavior.
m_handle = bgfx::createTexture2D(width, height, hasMips, numLayers, format, flags | BGFX_TEXTURE_BLIT_DST);
if (!bgfx::isValid(m_handle))
{
throw std::runtime_error{"Failed to create texture"};
}

m_ownsHandle = true;
m_width = width;
m_height = height;
Expand Down
55 changes: 26 additions & 29 deletions Plugins/NativeEngine/Source/IndexBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Babylon
{
IndexBuffer::IndexBuffer(Graphics::DeviceContext& deviceContext, const gsl::span<uint8_t> bytes, uint16_t flags, bool dynamic)
IndexBuffer::IndexBuffer(Graphics::DeviceContext& deviceContext, gsl::span<const uint8_t> bytes, uint16_t flags, bool dynamic)
: m_deviceContext{deviceContext}
, m_deviceID{deviceContext.GetDeviceId()}
, m_bytes{bytes.data(), bytes.data() + bytes.size()}
Expand Down Expand Up @@ -41,7 +41,7 @@ namespace Babylon
m_disposed = true;
}

void IndexBuffer::Update(const gsl::span<uint8_t> bytes, uint32_t startIndex)
void IndexBuffer::Update(gsl::span<const uint8_t> bytes, uint32_t startIndex)
{
if (!m_dynamic)
{
Expand All @@ -66,45 +66,42 @@ namespace Babylon
}
}

void IndexBuffer::Set(bgfx::Encoder* encoder, uint32_t firstIndex, uint32_t numIndices)
void IndexBuffer::Build()
{
if (!m_buildCalled)
if (!bgfx::isValid(m_handle))
{
m_buildCalled = true;
Build();
}
auto releaseFn = [](void*, void* userData) {
delete reinterpret_cast<decltype(m_bytes)*>(userData);
};

if (m_dynamic)
{
encoder->setIndexBuffer(m_dynamicHandle, firstIndex, numIndices);
}
else
{
encoder->setIndexBuffer(m_handle, firstIndex, numIndices);
auto* bytesPtr = new decltype(m_bytes){std::move(m_bytes)};
const bgfx::Memory* memory = bgfx::makeRef(bytesPtr->data(), static_cast<uint32_t>(bytesPtr->size()), releaseFn, bytesPtr);

if (m_dynamic)
{
m_dynamicHandle = bgfx::createDynamicIndexBuffer(memory, m_flags);
bghgary marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
m_handle = bgfx::createIndexBuffer(memory, m_flags);
}

if (!bgfx::isValid(m_handle))
{
throw std::runtime_error{"Failed to create index buffer"};
bghgary marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

void IndexBuffer::Build()
void IndexBuffer::Set(bgfx::Encoder* encoder, uint32_t firstIndex, uint32_t numIndices)
{
auto releaseFn = [](void*, void* userData) {
delete reinterpret_cast<decltype(m_bytes)*>(userData);
};

auto* bytesPtr = new decltype(m_bytes){std::move(m_bytes)};
const bgfx::Memory* memory = bgfx::makeRef(bytesPtr->data(), static_cast<uint32_t>(bytesPtr->size()), releaseFn, bytesPtr);

if (m_dynamic)
{
m_dynamicHandle = bgfx::createDynamicIndexBuffer(memory, m_flags);
encoder->setIndexBuffer(m_dynamicHandle, firstIndex, numIndices);
}
else
{
m_handle = bgfx::createIndexBuffer(memory, m_flags);
}

if (!bgfx::isValid(m_handle))
{
throw std::runtime_error{"Failed to create index buffer"};
encoder->setIndexBuffer(m_handle, firstIndex, numIndices);
}
}
}
9 changes: 4 additions & 5 deletions Plugins/NativeEngine/Source/IndexBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Babylon
class IndexBuffer final
{
public:
IndexBuffer(Graphics::DeviceContext& deviceContext, const gsl::span<uint8_t> bytes, uint16_t flags, bool dynamic);
IndexBuffer(Graphics::DeviceContext& deviceContext, gsl::span<const uint8_t> bytes, uint16_t flags, bool dynamic);
~IndexBuffer();

// No copy or move semantics
Expand All @@ -25,20 +25,19 @@ namespace Babylon

void Dispose();

void Update(const gsl::span<uint8_t> bytes, uint32_t startIndex);
void Update(gsl::span<const uint8_t> bytes, uint32_t startIndex);

void Build();

void Set(bgfx::Encoder* encoder, uint32_t firstIndex, uint32_t numIndices);

private:
void Build();

Graphics::DeviceContext& m_deviceContext;
const uintptr_t m_deviceID{};

std::vector<uint8_t> m_bytes{};
const uint16_t m_flags{};
const bool m_dynamic{};
bool m_buildCalled{};

union
{
Expand Down
33 changes: 31 additions & 2 deletions Plugins/NativeEngine/Source/NativeEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ namespace Babylon

std::function<std::pair<uint32_t, uint32_t>(uint32_t x, uint32_t y)> GetPixelMapper(bimg::Orientation::Enum orientation, uint32_t width, uint32_t height)
{
// clang-format off
switch (orientation)
{
// clang-format off
case bimg::Orientation::R0: return [](uint32_t x, uint32_t y) { return std::make_pair(x, y); };
case bimg::Orientation::R90: return [height](uint32_t x, uint32_t y) { return std::make_pair(height - y - 1, x); };
case bimg::Orientation::R180: return [width, height](uint32_t x, uint32_t y) { return std::make_pair(width - x - 1, height - y - 1); };
Expand All @@ -127,8 +127,8 @@ namespace Babylon
case bimg::Orientation::HFlipR270: return [](uint32_t x, uint32_t y) { return std::make_pair(y, x); };
case bimg::Orientation::VFlip: return [height](uint32_t x, uint32_t y) { return std::make_pair(x, height - y - 1); };
default: throw std::runtime_error{"Unexpected image orientation."};
// clang-format on
}
// clang-format on
}

using RGBA8ImageData = gsl::span<uint32_t>;
Expand Down Expand Up @@ -719,6 +719,12 @@ namespace Babylon
, m_boundFrameBuffer{&m_defaultFrameBuffer}
, m_boundFrameBufferNeedsRebinding{m_deviceContext, *m_cancellationSource, true}
{
// Set features supported by the NativeEngine from Babylon.js.
if (!info[0].IsUndefined())
{
auto jsInfo = info[0].As<Napi::Object>();
m_jsInfo.NonFloatVertexBuffers = jsInfo.Get("nonFloatVertexBuffers").As<Napi::Boolean>();
}
}

NativeEngine::~NativeEngine()
Expand Down Expand Up @@ -851,6 +857,29 @@ namespace Babylon
const bool normalized = info[7].As<Napi::Boolean>().Value();
const uint32_t divisor = info[8].As<Napi::Number>().Uint32Value();

if (!m_jsInfo.NonFloatVertexBuffers)
{
auto rendererType = bgfx::getCaps()->rendererType;

// clang-format off
bool nonFloatVertexBuffers = !normalized
&& (rendererType == bgfx::RendererType::Direct3D11 ||
rendererType == bgfx::RendererType::Direct3D12 ||
rendererType == bgfx::RendererType::Vulkan)
&& (type == bgfx::AttribType::Int8 ||
type == bgfx::AttribType::Uint8 ||
type == bgfx::AttribType::Uint10 ||
type == bgfx::AttribType::Int16 ||
type == bgfx::AttribType::Uint16);
// clang-format on

if (nonFloatVertexBuffers)
{
JsConsoleLogger::LogError(info.Env(), "Non-normalized, non-float vertex buffer is not supported for D3D11, D3D12, and Vulkan. Please update to a newer version of Babylon.js.");
return;
}
}

try
{
vertexArray->RecordVertexBuffer(vertexBuffer, location, byteOffset, byteStride, numElements, type, normalized, divisor);
Expand Down
6 changes: 6 additions & 0 deletions Plugins/NativeEngine/Source/NativeEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,5 +275,11 @@ namespace Babylon

// TODO: This should be changed to a non-owning ref once multi-update is available.
NativeDataStream* m_commandStream{};

// Information from the JS side used for backwards compatibility.
struct
{
bool NonFloatVertexBuffers{};
} m_jsInfo;
};
}
Loading