Skip to content

Conversation

@keptsecret
Copy link
Contributor

No description provided.

Comment on lines +155 to +162
CHLSLCompiler::SOptions options = {};
options.stage = stage;
options.preprocessorOptions.sourceIdentifier = filePath;
options.preprocessorOptions.logger = params.utilities->getLogger();
options.preprocessorOptions.includeFinder = includeFinder.get();
shaderSrc = compiler->compileToSPIRV((const char*)shaderSrc->getContent()->getPointer(), options);

return params.utilities->getLogicalDevice()->compileShader({ shaderSrc.get() });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AnastaZIuk can we make @YasInvolved use CMake to make precompiled SPIR-V with NSC right way in a future PR to CI the shaders?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we can

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay now that master has the infrastructure for it, @AnastaZIuk decide if you want to teach @keptsecret how to do it, write a Wiki/Readme or have @Przemog1 do it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will get you a readme tutorial

Comment on lines 203 to 213
auto getRequiredAccessFlags = [&](const bitflag<IDeviceMemoryAllocation::E_MEMORY_PROPERTY_FLAGS>& properties)
{
bitflag<IDeviceMemoryAllocation::E_MAPPING_CPU_ACCESS_FLAGS> flags(IDeviceMemoryAllocation::EMCAF_NO_MAPPING_ACCESS);

if (properties.hasFlags(IDeviceMemoryAllocation::EMPF_HOST_READABLE_BIT))
flags |= IDeviceMemoryAllocation::EMCAF_READ;
if (properties.hasFlags(IDeviceMemoryAllocation::EMPF_HOST_WRITABLE_BIT))
flags |= IDeviceMemoryAllocation::EMCAF_WRITE;

return flags;
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only check for write flag on the mapping

Comment on lines 299 to 304
smart_refctd_ptr<IGPUBuffer> indicesBuffer;
params.utilities->createFilledDeviceLocalBufferOnDedMem(
SIntendedSubmitInfo{ .queue = params.transfer },
std::move(bufparams),
unitAABBIndices.data()
).move_into(indicesBuffer);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be slightly less complex (wouldn't have to take the utilities in the creation params) if you just shot off a single use commandbuffer with updateBuffer command since the update is less than 64kb (you just need the usage flag on the buffer to allow it)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utilities is still used to get logical device and logger elsewhere. Though we could pass those into creation params separately instead

.offset = 0,
.size = sizeof(SPushConstants)
};
return device->createPipelineLayout({ &pcRange , 1 }, nullptr, nullptr, nullptr, nullptr);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why no tcall the createPipelineLayoutFromPCRange

Comment on lines 35 to 46
singlePipeline = createPipeline(params, params.singlePipelineLayout.get(), "single.vertex.hlsl", "aabb_instances.fragment.hlsl");
if (!singlePipeline)
{
logger->log("Failed to create pipeline!", ILogger::ELL_ERROR);
return nullptr;
}
}

smart_refctd_ptr<IGPUGraphicsPipeline> batchPipeline = nullptr;
if (params.drawMode & ADM_DRAW_BATCH)
{
batchPipeline = createPipeline(params, params.batchPipelineLayout.get(), "aabb_instances.vertex.hlsl", "aabb_instances.fragment.hlsl");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't you default the layouts if they're missing?

SPushConstantRange pcRange = {
.stageFlags = IShader::E_SHADER_STAGE::ESS_VERTEX,
.offset = 0,
.size = sizeof(SPushConstants)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your createDefaultPipelineLayout needs to take an enum about what pipeline this is for, cause you use two different push constant structs

return true;
}

hlsl::float32_t4x4 DrawAABB::getTransformFromAABB(const hlsl::shapes::AABB<3, float>& aabb)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should return 3x4 not 4x4

Comment on lines 324 to 333
bool DrawAABB::renderSingle(IGPUCommandBuffer* commandBuffer, const hlsl::shapes::AABB<3, float>& aabb, const hlsl::float32_t4& color, const hlsl::float32_t4x4& cameraMat)
{
if (!(m_cachedCreationParams.drawMode & ADM_DRAW_SINGLE))
{
m_cachedCreationParams.utilities->getLogger()->log("DrawAABB has not been enabled for draw single!", ILogger::ELL_ERROR);
return false;
}

commandBuffer->bindGraphicsPipeline(m_singlePipeline.get());
commandBuffer->setLineWidth(1.f);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make a struct with command buffer pointer, camera viewProj matrix and line width to use for both functions

SSinglePushConstants pc;

hlsl::float32_t4x4 instanceTransform = getTransformFromAABB(aabb);
pc.instance.transform = hlsl::mul(cameraMat, instanceTransform);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

promoted_mul to mul 4x4 with 3x4

Comment on lines 374 to 380
std::vector<InstanceData> instances(aabbInstances.size());
for (uint32_t i = 0; i < aabbInstances.size(); i++)
{
auto& inst = instances[i];
inst = aabbInstances[i];
inst.transform = hlsl::mul(cameraMat, inst.transform);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we skip having this temporary vector and do this loop as a lambda we call instead of the memcpy below?

auto instancesIt = instances.begin();
const uint32_t instancesPerIter = streaming->getBuffer()->getSize() / sizeof(InstanceData);
using suballocator_t = core::LinearAddressAllocatorST<offset_t>;
while (instancesIt != instances.end())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll deadlock if the streaming buffer is not large enough, check aabbInstances.size()>instancesPerIter and return false

Copy link
Contributor Author

@keptsecret keptsecret Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that why we loop below this? We update and draw AABBs in batches that fit the streaming buffer size. Or am I misunderstanding how the streaming buffer works?

Comment on lines +1 to +43
include(${NBL_ROOT_PATH}/cmake/common.cmake)

set(NBL_EXT_INTERNAL_INCLUDE_DIR "${NBL_ROOT_PATH}/include")

set(NBL_EXT_DEBUG_DRAW_H
${NBL_EXT_INTERNAL_INCLUDE_DIR}/nbl/ext/DebugDraw/CDrawAABB.h
)

set(NBL_EXT_DEBUG_DRAW_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/CDrawAABB.cpp"
)

nbl_create_ext_library_project(
DEBUG_DRAW
"${NBL_EXT_DEBUG_DRAW_H}"
"${NBL_EXT_DEBUG_DRAW_SRC}"
"${NBL_EXT_DEBUG_DRAW_EXTERNAL_INCLUDE}"
""
""
)

# this should be standard for all extensions
set(_ARCHIVE_ENTRY_KEY_ "nbl/ext/DebugDraw/builtin/hlsl") # then each one has unique archive key
get_filename_component(_ARCHIVE_ABSOLUTE_ENTRY_PATH_ "${NBL_EXT_INTERNAL_INCLUDE_DIR}" ABSOLUTE)
get_filename_component(_OUTPUT_DIRECTORY_SOURCE_ "${CMAKE_CURRENT_BINARY_DIR}/src" ABSOLUTE)
get_filename_component(_OUTPUT_DIRECTORY_HEADER_ "${CMAKE_CURRENT_BINARY_DIR}/include" ABSOLUTE)

target_compile_definitions(${LIB_NAME} PRIVATE _ARCHIVE_ABSOLUTE_ENTRY_PATH_="${_ARCHIVE_ABSOLUTE_ENTRY_PATH_}")
target_compile_definitions(${LIB_NAME} PRIVATE _ARCHIVE_ENTRY_KEY_="${_ARCHIVE_ENTRY_KEY_}")

if(NBL_EMBED_BUILTIN_RESOURCES)
set(_BR_TARGET_ extDebugDrawbuiltinResourceData)

LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "common.hlsl")
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "single.vertex.hlsl") # (*)
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "aabb_instances.vertex.hlsl") # (*)
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "aabb_instances.fragment.hlsl") # (*)

ADD_CUSTOM_BUILTIN_RESOURCES(${_BR_TARGET_} RESOURCES_TO_EMBED "${_ARCHIVE_ABSOLUTE_ENTRY_PATH_}" "${_ARCHIVE_ENTRY_KEY_}" "nbl::ext::debug_draw::builtin" "${_OUTPUT_DIRECTORY_HEADER_}" "${_OUTPUT_DIRECTORY_SOURCE_}")
LINK_BUILTIN_RESOURCES_TO_TARGET(${LIB_NAME} ${_BR_TARGET_})
endif()

add_library(Nabla::ext::DebugDraw ALIAS ${LIB_NAME})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AnastaZIuk review the Cmake please

Comment on lines +57 to +68
if(NBL_BUILD_DEBUG_DRAW)
add_subdirectory(DebugDraw)
set(NBL_EXT_DEBUG_DRAW_INCLUDE_DIRS
${NBL_EXT_DEBUG_DRAW_INCLUDE_DIRS}
PARENT_SCOPE
)
set(NBL_EXT_DEBUG_DRAW_LIB
${NBL_EXT_DEBUG_DRAW_LIB}
PARENT_SCOPE
)
endif()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AnastaZIuk review please

@devshgraphicsprogramming
Copy link
Member

conflict on examples_tests needs resolving (probably just merge master to both branches)


DrawMode drawMode = ADM_DRAW_BOTH;

core::smart_refctd_ptr<video::IUtilities> utilities;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it absolutely silly to keep the utilities around, when all you need from it is the logical device and logger

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger should be configurable and you should ask for it here (you can default it to utilities' if its nullptr), it shouldn't be stolen from utilities by default.

if you need utilities then place along side the transfer queue in SCreationParameters

the logical device needs to be neither in SCachedCreationParameters or SCreationParameters, should be extracted and kept as a member.

Comment on lines +55 to +59
assert(bool(assetManager));
assert(bool(assetManager->getSystem()));
assert(bool(utilities));
assert(bool(transfer));
assert(bool(renderpass));
Copy link
Member

@devshgraphicsprogramming devshgraphicsprogramming Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is NOT how one validates!

the only assert thats okay out of this bunch is

assert(bool(assetManager->getSystem()));

Comment on lines +49 to +50
core::smart_refctd_ptr<video::IGPUPipelineLayout> singlePipelineLayout;
core::smart_refctd_ptr<video::IGPUPipelineLayout> batchPipelineLayout;
Copy link
Member

@devshgraphicsprogramming devshgraphicsprogramming Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be default initialized to nullptr, since you provide fallbacks/defaults if null

struct DrawParameters
{
video::IGPUCommandBuffer* commandBuffer = nullptr;
hlsl::float32_t4x4 cameraMat = hlsl::float32_t4x4(1);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't do defaults for camera matrix, makes no sense

return true;
}

static hlsl::float32_t3x4 getTransformFromAABB(const hlsl::shapes::AABB<3, float>& aabb);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be inline too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants