From 379c1ef89064941de71763266f3a7d843e425fc0 Mon Sep 17 00:00:00 2001 From: Try Date: Tue, 6 Jun 2023 00:29:37 +0200 Subject: [PATCH] mesh emulation in progress #38 --- Engine/gapi/spirv/meshconverter.cpp | 99 ++++++++++++-------- Engine/gapi/vulkan/vcommandbuffer.cpp | 10 +- Engine/gapi/vulkan/vmeshlethelper.cpp | 50 +++++----- Engine/gapi/vulkan/vmeshlethelper.h | 11 ++- Engine/gapi/vulkan/vmeshshaderemulated.cpp | 11 ++- Engine/shaders/mesh_compactage.comp | 24 ++--- Engine/shaders/mesh_prefix_pass.comp | 38 +++----- Examples/MeshShader/game.cpp | 102 ++++++++++++++------- Examples/MeshShader/game.h | 6 +- Examples/MeshShader/main.cpp | 5 +- Tests/shader/simple_test.spv14.mesh | 2 +- Tests/tests/gapi/gapi_test_common.h | 2 +- 12 files changed, 209 insertions(+), 151 deletions(-) diff --git a/Engine/gapi/spirv/meshconverter.cpp b/Engine/gapi/spirv/meshconverter.cpp index 09dd9241..5ec9238f 100644 --- a/Engine/gapi/spirv/meshconverter.cpp +++ b/Engine/gapi/spirv/meshconverter.cpp @@ -380,13 +380,11 @@ void MeshConverter::emitEngSsbo(libspirv::MutableBytecode& comp, spv::ExecutionM const uint32_t _ptr_Priate_uint = comp.OpTypePointer(fn,spv::StorageClassPrivate, uint_t); const uint32_t _runtimearr_uint = comp.OpTypeRuntimeArray(fn, uint_t); - const uint32_t DrawIndexedIndirectCommand = comp.OpTypeStruct (fn, {uint_t, uint_t, uint_t, int_t, uint_t}); - const uint32_t IndirectCommand = comp.OpTypeStruct (fn, {uint_t}); + const uint32_t DrawIndexedIndirectCommand = comp.OpTypeStruct (fn, {uint_t, uint_t, uint_t, uint_t, uint_t, int_t, uint_t, uint_t}); const uint32_t Descriptor = comp.OpTypeStruct (fn, {uint_t, uint_t, uint_t}); const uint32_t _runtimearr_desc = comp.OpTypeRuntimeArray(fn, Descriptor); - const uint32_t _runtimearr_cmd = comp.OpTypeRuntimeArray(fn, IndirectCommand); - const uint32_t EngineInternal0_t = comp.OpTypeStruct (fn, { _runtimearr_cmd }); // indirects + const uint32_t EngineInternal0_t = comp.OpTypeStruct (fn, { DrawIndexedIndirectCommand }); // indirects const uint32_t _ptr_Storage_EngineInternal0 = comp.OpTypePointer(fn,spv::StorageClassStorageBuffer, EngineInternal0_t); const uint32_t EngineInternal1_t = comp.OpTypeStruct (fn, {uint_t, uint_t, _runtimearr_desc}); // descritors @@ -409,11 +407,9 @@ void MeshConverter::emitEngSsbo(libspirv::MutableBytecode& comp, spv::ExecutionM fn = comp.findSectionEnd(libspirv::Bytecode::S_Annotations); fn.insert(spv::OpDecorate, {_runtimearr_uint, spv::DecorationArrayStride, 4}); - fn.insert(spv::OpDecorate, {_runtimearr_cmd, spv::DecorationArrayStride, 4}); fn.insert(spv::OpDecorate, {_runtimearr_desc, spv::DecorationArrayStride, 12}); - //fn.insert(spv::OpDecorate, {_runtimearr_cmd, spv::DecorationArrayStride, 20}); - fn.insert(spv::OpMemberDecorate, {IndirectCommand, 0, spv::DecorationOffset, 0}); + // fn.insert(spv::OpMemberDecorate, {IndirectCommand, 0, spv::DecorationOffset, 0}); fn.insert(spv::OpMemberDecorate, {Descriptor, 0, spv::DecorationOffset, 0}); fn.insert(spv::OpMemberDecorate, {Descriptor, 1, spv::DecorationOffset, 4}); @@ -424,6 +420,9 @@ void MeshConverter::emitEngSsbo(libspirv::MutableBytecode& comp, spv::ExecutionM fn.insert(spv::OpMemberDecorate, {DrawIndexedIndirectCommand, 2, spv::DecorationOffset, 8}); fn.insert(spv::OpMemberDecorate, {DrawIndexedIndirectCommand, 3, spv::DecorationOffset, 12}); fn.insert(spv::OpMemberDecorate, {DrawIndexedIndirectCommand, 4, spv::DecorationOffset, 16}); + fn.insert(spv::OpMemberDecorate, {DrawIndexedIndirectCommand, 5, spv::DecorationOffset, 20}); + fn.insert(spv::OpMemberDecorate, {DrawIndexedIndirectCommand, 6, spv::DecorationOffset, 24}); + fn.insert(spv::OpMemberDecorate, {DrawIndexedIndirectCommand, 7, spv::DecorationOffset, 28}); fn.insert(spv::OpDecorate, {vIndirectCmd, spv::DecorationDescriptorSet, 1}); fn.insert(spv::OpDecorate, {vIndirectCmd, spv::DecorationBinding, 0}); @@ -442,22 +441,26 @@ void MeshConverter::emitEngSsbo(libspirv::MutableBytecode& comp, spv::ExecutionM fn.insert(spv::OpDecorate, {EngineInternal2_t, spv::DecorationBlock}); fn.insert(spv::OpMemberDecorate, {EngineInternal2_t, 0, spv::DecorationOffset, 0}); fn.insert(spv::OpMemberDecorate, {EngineInternal2_t, 1, spv::DecorationOffset, 4}); + // fn.insert(spv::OpMemberDecorate, {EngineInternal2_t, 1, spv::DecorationCoherent}); fn = comp.findSectionEnd(libspirv::Bytecode::S_Debug); - fn.insert(spv::OpName, IndirectCommand, "IndirectCommand"); - fn.insert(spv::OpMemberName, IndirectCommand, 0, "indexCount"); + //fn.insert(spv::OpName, IndirectCommand, "IndirectCommand"); + //fn.insert(spv::OpMemberName, IndirectCommand, 0, "indexCount"); fn.insert(spv::OpName, Descriptor, "Descriptor"); fn.insert(spv::OpMemberName, Descriptor, 0, "drawId"); fn.insert(spv::OpMemberName, Descriptor, 1, "ptr"); fn.insert(spv::OpMemberName, Descriptor, 2, "indSz"); - fn.insert(spv::OpName, DrawIndexedIndirectCommand, "VkDrawIndexedIndirectCommand"); - fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 0, "indexCount"); - fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 1, "instanceCount"); - fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 2, "firstIndex"); - fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 3, "vertexOffset"); - fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 4, "firstInstance"); + fn.insert(spv::OpName, DrawIndexedIndirectCommand, "DrawIndexedIndirectCommand"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 0, "drawId"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 1, "indexCountSrc"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 2, "indexCount"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 3, "instanceCount"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 4, "firstIndex"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 5, "vertexOffset"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 6, "firstInstance"); + fn.insert(spv::OpMemberName, DrawIndexedIndirectCommand, 7, "padding0"); fn.insert(spv::OpName, EngineInternal0_t, "EngineInternal0"); fn.insert(spv::OpMemberName, EngineInternal0_t, 0, "indirect"); @@ -552,7 +555,8 @@ void MeshConverter::emitSetMeshOutputs(libspirv::MutableBytecode& comp, uint32_t const uint32_t drawId = comp.fetchAddBound(); const uint32_t rgDrawId = comp.fetchAddBound(); - fn.insert(spv::OpAccessChain, {_ptr_Input_uint, drawId, gl_WorkGroupID, const2}); // &gl_WorkGroupID.z (abused as drawid) + //fn.insert(spv::OpAccessChain, {_ptr_Input_uint, drawId, gl_WorkGroupID, const2}); // &gl_WorkGroupID.z (abused as drawid) + fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, drawId, vIndirectCmd, const0, const0}); //&EngineInternal0::indirect.drawId fn.insert(spv::OpLoad, {uint_t, rgDrawId, drawId}); // gl_LocalInvocationIndex==0 @@ -575,28 +579,6 @@ void MeshConverter::emitSetMeshOutputs(libspirv::MutableBytecode& comp, uint32_t fn.insert(spv::OpStore, {vTmp, rgTmp0}); - // vIndirectCmd[i].indexCount += N; - const uint32_t ptrCmdDest = comp.fetchAddBound(); - const uint32_t rgTmp1 = comp.fetchAddBound(); - fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, ptrCmdDest, vIndirectCmd, const0, rgDrawId, const0}); //&EngineInternal0::indirect[i] - fn.insert(spv::OpAtomicIAdd, {uint_t, rgTmp1, ptrCmdDest, const1/*scope*/, const0/*semantices*/, rgIboSize}); - - // vDecriptors - const uint32_t ptrDescDest = comp.fetchAddBound(); - fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, ptrDescDest, vDecriptors, const0}); //&EngineInternal1::grow - const uint32_t rgTmp2 = comp.fetchAddBound(); - fn.insert(spv::OpAtomicIAdd, {uint_t, rgTmp2, ptrDescDest, const1/*scope*/, const0/*semantices*/, const1}); - - const uint32_t descDestDr = comp.fetchAddBound(); - fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, descDestDr, vDecriptors, const2, rgTmp2, const0}); //&EngineInternal1::desc[].drawId - fn.insert(spv::OpStore, {descDestDr, rgDrawId}); - const uint32_t descDestInd = comp.fetchAddBound(); - fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, descDestInd, vDecriptors, const2, rgTmp2, const1}); //&EngineInternal1::desc[].ptr - fn.insert(spv::OpStore, {descDestInd, rgTmp0}); - const uint32_t descDestSz = comp.fetchAddBound(); - fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, descDestSz, vDecriptors, const2, rgTmp2, const2}); //&EngineInternal1::desc[].indSz - fn.insert(spv::OpStore, {descDestSz, rgIboSize}); - fn.insert(spv::OpBranch, {condBlockEnd}); fn.insert(spv::OpLabel, {condBlockEnd}); } @@ -640,6 +622,47 @@ void MeshConverter::emitSetMeshOutputs(libspirv::MutableBytecode& comp, uint32_t } } + // gl_LocalInvocationIndex==0 + { + const uint32_t cond0 = comp.fetchAddBound(); + fn.insert(spv::OpIEqual, {bool_t, cond0, rgThreadId, const0}); + + const uint32_t condBlockBegin = comp.fetchAddBound(); + const uint32_t condBlockEnd = comp.fetchAddBound(); + fn.insert(spv::OpSelectionMerge, {condBlockEnd, spv::SelectionControlMaskNone}); + fn.insert(spv::OpBranchConditional, {cond0, condBlockBegin, condBlockEnd}); + fn.insert(spv::OpLabel, {condBlockBegin}); + // fn.insert(spv::OpReturn, {}); + + const uint32_t rgTmp0 = comp.fetchAddBound(); + fn.insert(spv::OpLoad, {uint_t, rgTmp0, vTmp}); + + // vIndirectCmd[i].indexCountSrc += N; + const uint32_t ptrCmdDest = comp.fetchAddBound(); + const uint32_t rgTmp1 = comp.fetchAddBound(); + fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, ptrCmdDest, vIndirectCmd, const0, const1}); //&EngineInternal0::indirect.indexCountSrc + fn.insert(spv::OpAtomicIAdd, {uint_t, rgTmp1, ptrCmdDest, const1/*scope*/, const0/*semantices*/, rgIboSize}); + + // vDecriptors + const uint32_t ptrDescDest = comp.fetchAddBound(); + fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, ptrDescDest, vDecriptors, const0}); //&EngineInternal1::grow + const uint32_t rgTmp2 = comp.fetchAddBound(); + fn.insert(spv::OpAtomicIAdd, {uint_t, rgTmp2, ptrDescDest, const1/*scope*/, const0/*semantices*/, const1}); + + const uint32_t descDestDr = comp.fetchAddBound(); + fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, descDestDr, vDecriptors, const2, rgTmp2, const0}); //&EngineInternal1::desc[].drawId + fn.insert(spv::OpStore, {descDestDr, rgDrawId}); + const uint32_t descDestInd = comp.fetchAddBound(); + fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, descDestInd, vDecriptors, const2, rgTmp2, const1}); //&EngineInternal1::desc[].ptr + fn.insert(spv::OpStore, {descDestInd, rgTmp0}); + const uint32_t descDestSz = comp.fetchAddBound(); + fn.insert(spv::OpAccessChain, {_ptr_Storage_uint, descDestSz, vDecriptors, const2, rgTmp2, const2}); //&EngineInternal1::desc[].indSz + fn.insert(spv::OpStore, {descDestSz, rgIboSize}); + + fn.insert(spv::OpBranch, {condBlockEnd}); + fn.insert(spv::OpLabel, {condBlockEnd}); + } + fn.insert(spv::OpReturn, {}); fn.insert(spv::OpFunctionEnd, {}); } diff --git a/Engine/gapi/vulkan/vcommandbuffer.cpp b/Engine/gapi/vulkan/vcommandbuffer.cpp index e7ad534b..9841a84b 100644 --- a/Engine/gapi/vulkan/vcommandbuffer.cpp +++ b/Engine/gapi/vulkan/vcommandbuffer.cpp @@ -1136,16 +1136,8 @@ void VMeshCommandBuffer::dispatchMesh(size_t x, size_t y, size_t z) { if(px.meshPipeline()==VK_NULL_HANDLE) return; - assert(z==1); // abused as drawId auto& ms = *device.meshHelper; - - if(meshIndirectId==0) { - ms.firstDraw(cbHelper); - } - - device.vkCmdDispatchBase(cbHelper, - 0, 0, uint32_t(meshIndirectId), - uint32_t(x), uint32_t(y), 1); + ms.drawCompute(cbHelper, uint32_t(meshIndirectId), x,y,z); ms.drawIndirect(impl, uint32_t(meshIndirectId)); ++meshIndirectId; } diff --git a/Engine/gapi/vulkan/vmeshlethelper.cpp b/Engine/gapi/vulkan/vmeshlethelper.cpp index 6c590a43..eed9c622 100644 --- a/Engine/gapi/vulkan/vmeshlethelper.cpp +++ b/Engine/gapi/vulkan/vmeshlethelper.cpp @@ -18,20 +18,19 @@ VMeshletHelper::VMeshletHelper(VDevice& dev) : dev(dev) { const auto ms = MemUsage::StorageBuffer | MemUsage::Indirect | MemUsage::TransferDst | MemUsage::TransferSrc; const auto geo = MemUsage::StorageBuffer | MemUsage::IndexBuffer | MemUsage::TransferDst | MemUsage::TransferSrc; - indirectSrc = dev.allocator.alloc(nullptr, IndirectScratchSize, 1,1, ind, BufferHeap::Device); indirect = dev.allocator.alloc(nullptr, IndirectMemorySize, 1,1, ind, BufferHeap::Device); - meshlets = dev.allocator.alloc(nullptr, MeshletsMemorySize, 1,1, ms, BufferHeap::Device); + scratch = dev.allocator.alloc(nullptr, PipelineMemorySize, 1,1, geo, BufferHeap::Device); - // scratch = dev.allocator.alloc(nullptr, PipelineMemorySize, 1,1, geo, BufferHeap::Device); - scratch = dev.allocator.alloc(nullptr, PipelineMemorySize, 1,1, geo, BufferHeap::Upload); + // TODO + // assert(dev.props.ssbo.offsetAlign <= 32); { auto c = dev.dataMgr().get(); auto& cmd = reinterpret_cast(*c.get()); cmd.begin(); // drawcall-related parts should be set to zeros. - vkCmdFillBuffer(cmd.impl, indirectSrc.impl, 0, VK_WHOLE_SIZE, 0); + vkCmdFillBuffer(cmd.impl, indirect.impl, 0, VK_WHOLE_SIZE, 0); // meshlet counters vkCmdFillBuffer(cmd.impl, meshlets.impl, 0, sizeof(uint32_t)*2, 0); // heap counters @@ -52,11 +51,11 @@ VMeshletHelper::VMeshletHelper(VDevice& dev) : dev(dev) { engLay = initLayout(dev); engPool = initPool(dev,3); engSet = initDescriptors(dev,engPool,engLay); - initEngSet(engSet,3); + initEngSet(engSet,3,true); - compPool = initPool(dev,4); + compPool = initPool(dev,3); compSet = initDescriptors(dev,compPool,compactageLay.handler->impl); - initEngSet(compSet,4); + initEngSet(compSet,3,false); drawLay = initDrawLayout(dev); drawPool = initPool(dev,1); @@ -94,10 +93,7 @@ void VMeshletHelper::cleanup() { } void VMeshletHelper::bindCS(VkCommandBuffer impl, VkPipelineLayout lay) { - vkCmdBindDescriptorSets(impl, VK_PIPELINE_BIND_POINT_COMPUTE, - lay, 1, - 1,&engSet, - 0,nullptr); + currentCsLayout = lay; } void VMeshletHelper::bindVS(VkCommandBuffer impl, VkPipelineLayout lay) { @@ -108,9 +104,9 @@ void VMeshletHelper::bindVS(VkCommandBuffer impl, VkPipelineLayout lay) { 0,nullptr); } -void VMeshletHelper::drawIndirect(VkCommandBuffer impl, uint32_t id) { - assert(id prefixSumLay; DSharedPtr prefixSum; diff --git a/Engine/gapi/vulkan/vmeshshaderemulated.cpp b/Engine/gapi/vulkan/vmeshshaderemulated.cpp index 7ce6b0ba..7aafa273 100644 --- a/Engine/gapi/vulkan/vmeshshaderemulated.cpp +++ b/Engine/gapi/vulkan/vmeshshaderemulated.cpp @@ -26,16 +26,17 @@ VMeshShaderEmulated::VMeshShaderEmulated(VDevice& device, const void *source, si assert(code.findExecutionModel()==spv::ExecutionModelMeshEXT); MeshConverter conv(code); + // conv.options.deferredMeshShading = true; conv.exec(); //debugLog("mesh_orig.mesh.spv", reinterpret_cast(source),src_size/4); auto& comp = conv.computeShader(); - /* - debugLog("mesh_conv.comp.spv", comp.opcodes(), comp.size()); - std::system("spirv-cross.exe -V .\\mesh_conv.comp.spv"); - std::system("spirv-val.exe .\\mesh_conv.comp.spv"); - */ + + // debugLog("mesh_conv.comp.spv", comp.opcodes(), comp.size()); + // std::system("spirv-cross.exe -V .\\mesh_conv.comp.spv"); + // std::system("spirv-val.exe .\\mesh_conv.comp.spv"); + auto& vert = conv.vertexPassthrough(); diff --git a/Engine/shaders/mesh_compactage.comp b/Engine/shaders/mesh_compactage.comp index 999fc24a..293d298e 100644 --- a/Engine/shaders/mesh_compactage.comp +++ b/Engine/shaders/mesh_compactage.comp @@ -4,11 +4,6 @@ layout(local_size_x = 64) in; -struct IndirectCommand -{ - uint indexCount; -}; - struct Descriptor { uint drawId; @@ -16,20 +11,22 @@ struct Descriptor uint indSz; }; -struct VkDrawIndexedIndirectCommand +struct DrawIndexedIndirectCommand { + uint drawId; + uint indexCountSrc; uint indexCount; uint instanceCount; uint firstIndex; // prefix sum int vertexOffset; // can be abused to offset into var_buffer uint firstInstance; // caps: should be zero - uint vboOffset; // prefix sum + uint padding0; }; -layout(binding = 0, std430) restrict writeonly buffer EngineInternal0 +layout(binding = 0, std430) restrict buffer EngineInternal0 { - IndirectCommand cmd[]; -} indirectSrc; + DrawIndexedIndirectCommand indirect[]; +}; layout(binding = 1, std430) restrict buffer EngineInternal1 { @@ -44,11 +41,6 @@ layout(binding = 2, std430) restrict buffer EngineInternal2 uint heap[]; } var; -layout(binding = 3, std430) buffer EngineInternal3 -{ - VkDrawIndexedIndirectCommand cmd[]; -} indirect; - shared uint workId; shared uint iboOffset; @@ -72,7 +64,7 @@ void main() { const Descriptor d = mesh.desc[at]; if(gl_LocalInvocationIndex==0) { - iboOffset = atomicAdd(indirect.cmd[d.drawId].indexCount, d.indSz) + indirect.cmd[d.drawId].firstIndex; + iboOffset = atomicAdd(indirect[d.drawId].indexCount, d.indSz) + indirect[d.drawId].firstIndex; } barrier(); diff --git a/Engine/shaders/mesh_prefix_pass.comp b/Engine/shaders/mesh_prefix_pass.comp index 5617ee5b..6b4667ef 100644 --- a/Engine/shaders/mesh_prefix_pass.comp +++ b/Engine/shaders/mesh_prefix_pass.comp @@ -4,11 +4,6 @@ layout(local_size_x = 128) in; -struct IndirectCommand -{ - uint indexCount; -}; - struct Descriptor { uint drawId; @@ -16,20 +11,22 @@ struct Descriptor uint indSz; }; -struct VkDrawIndexedIndirectCommand +struct DrawIndexedIndirectCommand { + uint drawId; + uint indexCountSrc; uint indexCount; uint instanceCount; uint firstIndex; // prefix sum int vertexOffset; // can be abused to offset into var_buffer uint firstInstance; // caps: should be zero - uint vboOffset; // prefix sum + uint padding0; }; layout(binding = 0, std430) restrict buffer EngineInternal0 { - IndirectCommand cmd[]; -} indirectSrc; + DrawIndexedIndirectCommand indirect[]; +}; layout(binding = 1, std430) restrict buffer EngineInternal1 { @@ -44,11 +41,6 @@ layout(binding = 2, std430) restrict buffer EngineInternal2 uint heap[]; } var; -layout(binding = 3, std430) writeonly buffer EngineInternal3 -{ - VkDrawIndexedIndirectCommand cmd[]; -} indirect; - shared uint partialSummIbo[gl_WorkGroupSize.x]; layout(push_constant, std140) uniform UboPush { @@ -65,7 +57,7 @@ void main() { uint sumIbo = 0; [[loop]] for(uint i=b; i0 ? 1 : 0; prefixIbo += indexCount; - indirect.cmd[i].indexCount = 0; - indirect.cmd[i].instanceCount = inst; - indirect.cmd[i].firstIndex = firstIndex; - indirect.cmd[i].vertexOffset = 0; - indirect.cmd[i].firstInstance = 0; - indirect.cmd[i].vboOffset = 0; + indirect[i].indexCount = 0; + indirect[i].instanceCount = inst; + indirect[i].firstIndex = firstIndex; + indirect[i].vertexOffset = 0; + indirect[i].firstInstance = 0; + indirect[i].padding0 = 0; } barrier(); @@ -104,6 +96,6 @@ void main() { var.grow = 0; } for(uint i=b; i +#include #include #include #include @@ -15,44 +16,31 @@ Game::Game(Device& device) for(uint8_t i=0;i fence; diff --git a/Examples/MeshShader/main.cpp b/Examples/MeshShader/main.cpp index 6604413d..abf14a78 100644 --- a/Examples/MeshShader/main.cpp +++ b/Examples/MeshShader/main.cpp @@ -25,7 +25,7 @@ std::unique_ptr mkApi(const char* av) { int main(int argc, const char** argv) { Tempest::Application app; - const bool emulated = true; + const bool emulated = false; const char* msDev = nullptr; auto api = mkApi(argc>1 ? argv[1] : ""); @@ -43,6 +43,9 @@ int main(int argc, const char** argv) { Tempest::Log::i(msDev); Tempest::Log::i(emulated ? "mesh-shader-emulated" : "GL_EXT_mesh_shader"); + + app.setFont(Tempest::Application::defaultFont()); + Tempest::Device device{*api,msDev}; Game wx(device); diff --git a/Tests/shader/simple_test.spv14.mesh b/Tests/shader/simple_test.spv14.mesh index 79a07596..2f399e18 100644 --- a/Tests/shader/simple_test.spv14.mesh +++ b/Tests/shader/simple_test.spv14.mesh @@ -24,7 +24,7 @@ void main() { SetMeshOutputsEXT(3, 1); // Vertices position - gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(vertices[gl_LocalInvocationIndex], 0, 1); + gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(vertices[gl_LocalInvocationIndex], payload.dummy, 1); // Vertices color v_out[gl_LocalInvocationIndex] = vec4(colors[gl_LocalInvocationIndex], 1.0); diff --git a/Tests/tests/gapi/gapi_test_common.h b/Tests/tests/gapi/gapi_test_common.h index 5c78934a..07e274bc 100644 --- a/Tests/tests/gapi/gapi_test_common.h +++ b/Tests/tests/gapi/gapi_test_common.h @@ -1757,7 +1757,7 @@ void MeshShaderEmulated(const char* outImg) { Device device(api,msDev); auto vbo = device.vbo(vboData,3); - auto mesh = device.shader("shader/simple_test.mesh.sprv"); + auto mesh = device.shader("shader/simple_test.spv14.mesh.sprv"); auto frag = device.shader("shader/simple_test.frag.sprv"); auto pso = device.pipeline(RenderState(),Tempest::Shader(),mesh,frag);