diff --git a/Engine/gapi/directx12/dxcommandbuffer.cpp b/Engine/gapi/directx12/dxcommandbuffer.cpp index beac1eff..4c786567 100644 --- a/Engine/gapi/directx12/dxcommandbuffer.cpp +++ b/Engine/gapi/directx12/dxcommandbuffer.cpp @@ -399,6 +399,7 @@ bool DxCommandBuffer::isRecording() const { void Tempest::Detail::DxCommandBuffer::beginRendering(const AttachmentDesc* desc, size_t descSize, uint32_t w, uint32_t h, const TextureFormat* frm, AbstractGraphicsApi::Texture** att, AbstractGraphicsApi::Swapchain** sw, const uint32_t* imgId) { + resState.joinCompute(); resState.setRenderpass(*this,desc,descSize,frm,att,sw,imgId); D3D12_RENDER_PASS_RENDER_TARGET_DESC view[MaxFramebufferAttachments] = {}; @@ -475,7 +476,6 @@ void Tempest::Detail::DxCommandBuffer::beginRendering(const AttachmentDesc* desc void Tempest::Detail::DxCommandBuffer::endRendering() { impl->EndRenderPass(); - // resState.flushLayout(*this); } void DxCommandBuffer::setViewport(const Rect& r) { diff --git a/Engine/gapi/resourcestate.cpp b/Engine/gapi/resourcestate.cpp index f0afc184..8cd87e9e 100644 --- a/Engine/gapi/resourcestate.cpp +++ b/Engine/gapi/resourcestate.cpp @@ -3,7 +3,6 @@ using namespace Tempest; using namespace Tempest::Detail; - void ResourceState::setRenderpass(AbstractGraphicsApi::CommandBuffer& cmd, const AttachmentDesc* desc, size_t descSize, const TextureFormat* frm, AbstractGraphicsApi::Texture** att, @@ -67,20 +66,31 @@ void ResourceState::setLayout(AbstractGraphicsApi::Buffer& buf, ResourceAccess l bufState.push_back(s); } +void ResourceState::joinCompute() { + for(auto& i:bufState) { + if(i.buf==nullptr) + continue; + if((i.last & ResourceAccess::ComputeWrite)!=ResourceAccess::ComputeWrite) + continue; + i.next = ResourceAccess::ComputeRead; + i.outdated = true; + } + } + void ResourceState::flush(AbstractGraphicsApi::CommandBuffer& cmd) { AbstractGraphicsApi::BarrierDesc barrier[MaxBarriers]; uint8_t barrierCnt = 0; - for(auto& i:imgState) { + + for(auto& i:bufState) { if(!i.outdated) continue; + if(i.last==ResourceAccess::ComputeRead && i.next==ResourceAccess::ComputeRead) + continue; + auto& b = barrier[barrierCnt]; - b.swapchain = i.sw; - b.swId = i.id; - b.texture = i.img; - b.mip = uint32_t(-1); - b.prev = i.last; - b.next = i.next; - b.discard = i.discard; + b.buffer = i.buf; + b.prev = i.last; + b.next = i.next; ++barrierCnt; i.last = i.next; @@ -91,16 +101,17 @@ void ResourceState::flush(AbstractGraphicsApi::CommandBuffer& cmd) { } } - for(auto& i:bufState) { + for(auto& i:imgState) { if(!i.outdated) continue; - if(i.last==ResourceAccess::ComputeRead && i.next==ResourceAccess::ComputeRead) - continue; - auto& b = barrier[barrierCnt]; - b.buffer = i.buf; - b.prev = i.last; - b.next = i.next; + b.swapchain = i.sw; + b.swId = i.id; + b.texture = i.img; + b.mip = uint32_t(-1); + b.prev = i.last; + b.next = i.next; + b.discard = i.discard; ++barrierCnt; i.last = i.next; @@ -110,6 +121,7 @@ void ResourceState::flush(AbstractGraphicsApi::CommandBuffer& cmd) { barrierCnt = 0; } } + if(barrierCnt>0) cmd.barrier(barrier,barrierCnt); } diff --git a/Engine/gapi/resourcestate.h b/Engine/gapi/resourcestate.h index eec42010..7036ac47 100644 --- a/Engine/gapi/resourcestate.h +++ b/Engine/gapi/resourcestate.h @@ -19,6 +19,7 @@ class ResourceState { void setLayout (AbstractGraphicsApi::Texture& a, ResourceAccess lay, bool discard = false); void setLayout (AbstractGraphicsApi::Buffer& b, ResourceAccess lay); + void joinCompute(); void flush (AbstractGraphicsApi::CommandBuffer& cmd); void finalize (AbstractGraphicsApi::CommandBuffer& cmd); diff --git a/Engine/gapi/vulkan/vcommandbuffer.cpp b/Engine/gapi/vulkan/vcommandbuffer.cpp index 81339fa8..215e93f3 100644 --- a/Engine/gapi/vulkan/vcommandbuffer.cpp +++ b/Engine/gapi/vulkan/vcommandbuffer.cpp @@ -218,6 +218,7 @@ void VCommandBuffer::beginRendering(const AttachmentDesc* desc, size_t descSize, auto fb = fbo.get(); pass = fbo->pass; + resState.joinCompute(); resState.setRenderpass(*this,desc,descSize,frm,att,sw,imgId); VkClearValue clr[MaxFramebufferAttachments]; diff --git a/Tests/shader/comp_test.frag b/Tests/shader/comp_test.frag new file mode 100644 index 00000000..155099b1 --- /dev/null +++ b/Tests/shader/comp_test.frag @@ -0,0 +1,13 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec4 inColor; +layout(location = 0) out vec4 outColor; + +layout(binding = 0, std140) readonly buffer Input { + vec4 val[]; + } ssbo; + +void main() { + outColor = vec4(0.25,0.5,0.75,1.0);//ssbo.val[int(gl_FragCoord.x)]; + } diff --git a/Tests/shader/fillbuf.comp b/Tests/shader/fillbuf.comp new file mode 100644 index 00000000..1b9eae5b --- /dev/null +++ b/Tests/shader/fillbuf.comp @@ -0,0 +1,9 @@ +#version 440 + +layout(binding = 0, std140) buffer Input { + vec4 val[]; + } result; + +void main() { + result.val[gl_GlobalInvocationID.x] = vec4(0.25,0.5,0.75,1.0); + } diff --git a/Tests/tests/CMakeLists.txt b/Tests/tests/CMakeLists.txt index e591f460..1413109b 100644 --- a/Tests/tests/CMakeLists.txt +++ b/Tests/tests/CMakeLists.txt @@ -66,6 +66,9 @@ compile_shader(simple_test.frag) compile_shader(simple_test.comp) compile_shader(image_store_test.comp) +compile_shader(fillbuf.comp) +compile_shader(comp_test.frag) + compile_shader(ubo_input.vert) compile_shader(tess.vert) diff --git a/Tests/tests/gapi/directx_test.cpp b/Tests/tests/gapi/directx_test.cpp index ac5ad207..8cf785e0 100644 --- a/Tests/tests/gapi/directx_test.cpp +++ b/Tests/tests/gapi/directx_test.cpp @@ -104,6 +104,12 @@ TEST(DirectX12Api,ComputeImage) { #endif } +TEST(DirectX12Api,ComputeGraphics) { +#if defined(_MSC_VER) + GapiTestCommon::dispathToDraw("DirectX12Api_GraphicsCompute.png"); +#endif + } + TEST(DirectX12Api,MipMaps) { #if defined(_MSC_VER) GapiTestCommon::mipMaps ("DirectX12Api_MipMaps_RGBA8.png"); diff --git a/Tests/tests/gapi/gapi_test_common.h b/Tests/tests/gapi/gapi_test_common.h index d7386d79..0d43d1be 100644 --- a/Tests/tests/gapi/gapi_test_common.h +++ b/Tests/tests/gapi/gapi_test_common.h @@ -419,6 +419,56 @@ void ssboDispath() { } } +template +void dispathToDraw(const char* outImage) { + using namespace Tempest; + + try { + GraphicsApi api{ApiFlags::Validation}; + Device device(api); + + auto vbo = device.vbo(vboData,3); + auto ibo = device.ibo(iboData,3); + auto ssbo = device.ssbo(nullptr, sizeof(Vec4)*4); + auto tex = device.attachment(TextureFormat::RGBA8,4,4); + + auto cs = device.loadShader("shader/fillbuf.comp.sprv"); + auto psoC = device.pipeline(cs); + + auto vs = device.loadShader("shader/simple_test.vert.sprv"); + auto fs = device.loadShader("shader/comp_test.frag.sprv"); + auto psoG = device.pipeline(Topology::Triangles,RenderState(),vs,fs); + + auto uboCs = device.descriptors(psoC.layout()); + uboCs.set(0,ssbo); + + auto uboFs = device.descriptors(psoG.layout()); + uboFs.set(0,ssbo); + + auto cmd = device.commandBuffer(); + { + auto enc = cmd.startEncoding(device); + enc.setUniforms(psoC,uboCs); + enc.dispatch(4,1,1); + enc.setFramebuffer({{tex,Vec4(0,0,0,0),Tempest::Preserve}}); + enc.setUniforms(psoG,uboFs); + enc.draw(vbo,ibo); + } + + auto sync = device.fence(); + device.submit(cmd,sync); + sync.wait(); + + auto pm = device.readPixels(tex); + pm.save(outImage); + } + catch(std::system_error& e) { + if(e.code()==Tempest::GraphicsErrc::NoDevice) + Log::d("Skipping graphics testcase: ", e.what()); else + throw; + } + } + template void imageCompute(const char* outImage) { using namespace Tempest; diff --git a/Tests/tests/gapi/vulkan_test.cpp b/Tests/tests/gapi/vulkan_test.cpp index 4c3f42ab..d2857bea 100644 --- a/Tests/tests/gapi/vulkan_test.cpp +++ b/Tests/tests/gapi/vulkan_test.cpp @@ -93,6 +93,12 @@ TEST(VulkanApi,ComputeImage) { #endif } +TEST(VulkanApi,ComputeGraphics) { +#if !defined(__OSX__) + GapiTestCommon::dispathToDraw("VulkanApi_GraphicsCompute.png"); +#endif + } + TEST(VulkanApi,MipMaps) { #if !defined(__OSX__) GapiTestCommon::mipMaps ("VulkanApi_MipMaps_RGBA8.png");