diff --git a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp index 50a3154bc..72f6bf1b8 100644 --- a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp @@ -286,7 +286,7 @@ float4 main() : SV_Target0 ID3D11BufferPtr cb = MakeBuffer().Constant().Data(cbufferdata); ID3D11Texture2DPtr fltTex = - MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, screenWidth, screenHeight).RTV(); + MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, screenWidth, screenHeight).RTV().SRV(); ID3D11RenderTargetViewPtr fltRT = MakeRTV(fltTex); while(Running()) @@ -308,6 +308,8 @@ float4 main() : SV_Target0 ctx->Draw(3, 0); + blitToSwap(fltTex); + Present(); } diff --git a/util/test/demos/d3d11/d3d11_test.cpp b/util/test/demos/d3d11/d3d11_test.cpp index 7ea434b76..3830238cb 100644 --- a/util/test/demos/d3d11/d3d11_test.cpp +++ b/util/test/demos/d3d11/d3d11_test.cpp @@ -305,6 +305,20 @@ void D3D11GraphicsTest::PostDeviceCreate() ctx4 = ctx; annot = ctx; + + std::string blitPixel = R"EOSHADER( + +Texture2D tex : register(t0); + +float4 main(float4 pos : SV_Position) : SV_Target0 +{ + return tex.Load(int3(pos.xy, 0)); +} + +)EOSHADER"; + + swapBlitVS = CreateVS(Compile(D3DFullscreenQuadVertex, "main", "vs_4_0")); + swapBlitPS = CreatePS(Compile(blitPixel, "main", "ps_5_0")); } void D3D11GraphicsTest::Shutdown() @@ -358,6 +372,61 @@ void D3D11GraphicsTest::popMarker() annot->EndEvent(); } +void D3D11GraphicsTest::blitToSwap(ID3D11Texture2DPtr tex) +{ + ID3D11VertexShaderPtr vs; + ctx->VSGetShader(&vs, NULL, NULL); + ID3D11PixelShaderPtr ps; + ctx->PSGetShader(&ps, NULL, NULL); + + ID3D11ShaderResourceViewPtr srv = NULL; + ctx->PSGetShaderResources(0, 1, &srv); + + D3D11_PRIMITIVE_TOPOLOGY topo; + ctx->IAGetPrimitiveTopology(&topo); + + ID3D11InputLayoutPtr layout; + ctx->IAGetInputLayout(&layout); + + ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + ctx->VSSetShader(swapBlitVS, NULL, 0); + ctx->PSSetShader(swapBlitPS, NULL, 0); + + D3D11_RASTERIZER_DESC oldRS = GetRasterState(); + D3D11_DEPTH_STENCIL_DESC oldDS = GetDepthState(); + + ctx->OMSetRenderTargets(1, &bbRTV.GetInterfacePtr(), NULL); + + D3D11_RASTERIZER_DESC rs = oldRS; + rs.CullMode = D3D11_CULL_NONE; + rs.FillMode = D3D11_FILL_SOLID; + rs.ScissorEnable = FALSE; + SetRasterState(rs); + + D3D11_DEPTH_STENCIL_DESC ds = oldDS; + ds.DepthEnable = FALSE; + ds.StencilEnable = FALSE; + SetDepthState(ds); + + ID3D11ShaderResourceViewPtr srcSRV = MakeSRV(tex); + ctx->PSSetShaderResources(0, 1, &srcSRV.GetInterfacePtr()); + + RSSetViewport({0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f}); + + ctx->IASetInputLayout(NULL); + + ctx->Draw(4, 0); + + ctx->IASetInputLayout(layout); + ctx->IASetPrimitiveTopology(topo); + ctx->VSSetShader(vs, NULL, 0); + ctx->PSSetShader(ps, NULL, 0); + ctx->PSSetShaderResources(0, 1, &srv.GetInterfacePtr()); + SetRasterState(oldRS); + SetDepthState(oldDS); +} + std::vector D3D11GraphicsTest::GetBufferData(ID3D11Buffer *buffer, uint32_t offset, uint32_t len) { D3D11_MAPPED_SUBRESOURCE mapped; diff --git a/util/test/demos/d3d11/d3d11_test.h b/util/test/demos/d3d11/d3d11_test.h index 43694d8d5..96199168e 100644 --- a/util/test/demos/d3d11/d3d11_test.h +++ b/util/test/demos/d3d11/d3d11_test.h @@ -159,6 +159,8 @@ struct D3D11GraphicsTest : public GraphicsTest void setMarker(const std::string &name); void popMarker(); + void blitToSwap(ID3D11Texture2DPtr tex); + DXGI_FORMAT backbufferFmt = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; int backbufferCount = 2; int backbufferMSAA = 1; @@ -168,6 +170,9 @@ struct D3D11GraphicsTest : public GraphicsTest DXGI_ADAPTER_DESC adapterDesc = {}; + ID3D11VertexShaderPtr swapBlitVS; + ID3D11PixelShaderPtr swapBlitPS; + D3D11_FEATURE_DATA_D3D11_OPTIONS opts; D3D11_FEATURE_DATA_D3D11_OPTIONS1 opts1; diff --git a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp index 5d43b48b7..8db5c76d0 100644 --- a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp @@ -385,6 +385,14 @@ float4 main() : SV_Target0 cmd->DrawInstanced(3, 1, 0, 0); + ResourceBarrier(cmd, rtvtex, D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + + blitToSwap(cmd, rtvtex, bb); + + ResourceBarrier(cmd, rtvtex, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + D3D12_RESOURCE_STATE_RENDER_TARGET); + FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET); cmd->Close(); diff --git a/util/test/demos/d3d12/d3d12_test.cpp b/util/test/demos/d3d12/d3d12_test.cpp index 33f5b3939..14a526646 100644 --- a/util/test/demos/d3d12/d3d12_test.cpp +++ b/util/test/demos/d3d12/d3d12_test.cpp @@ -332,7 +332,7 @@ bool D3D12GraphicsTest::Init() m_Sampler->SetName(L"Sampler heap"); - desc.NumDescriptors = 1024; + desc.NumDescriptors = 1030; desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; CHECK_HR(dev->CreateDescriptorHeap(&desc, __uuidof(ID3D12DescriptorHeap), (void **)&m_CBVUAVSRV)); @@ -380,6 +380,26 @@ bool D3D12GraphicsTest::Init() m_UploadBuffer->SetName(L"Upload buffer"); } + { + std::string blitPixel = R"EOSHADER( + +Texture2D tex : register(t0); + +float4 main(float4 pos : SV_Position) : SV_Target0 +{ + return tex.Load(int3(pos.xy, 0)); +} + +)EOSHADER"; + + ID3DBlobPtr vsblob = Compile(D3DFullscreenQuadVertex, "main", "vs_4_0"); + ID3DBlobPtr psblob = Compile(blitPixel, "main", "ps_4_0"); + + swapBlitSig = MakeSig( + {tableParam(D3D12_SHADER_VISIBILITY_PIXEL, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, 0, 1, 0)}); + swapBlitPso = MakePSO().RootSig(swapBlitSig).VS(vsblob).PS(psblob); + } + // mute useless messages D3D12_MESSAGE_ID mute[] = { // super spammy, mostly just perf warning @@ -798,6 +818,33 @@ void D3D12GraphicsTest::popMarker(ID3D12GraphicsCommandListPtr cmd) cmd->EndEvent(); } +void D3D12GraphicsTest::blitToSwap(ID3D12GraphicsCommandListPtr cmd, ID3D12ResourcePtr src, + ID3D12ResourcePtr dst) +{ + D3D12_CPU_DESCRIPTOR_HANDLE rtv = MakeRTV(dst).Format(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB).CreateCPU(0); + + cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + cmd->SetPipelineState(swapBlitPso); + cmd->SetGraphicsRootSignature(swapBlitSig); + + static UINT idx = 0; + idx++; + idx %= 6; + + D3D12_GPU_DESCRIPTOR_HANDLE handle = MakeSRV(src).CreateGPU(1024 + idx); + + cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr()); + cmd->SetGraphicsRootDescriptorTable(0, handle); + + RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f}); + RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight}); + + OMSetRenderTargets(cmd, {rtv}, {}); + + cmd->DrawInstanced(4, 1, 0, 0); +} + void D3D12GraphicsTest::ResourceBarrier(ID3D12GraphicsCommandListPtr cmd, ID3D12ResourcePtr res, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) { diff --git a/util/test/demos/d3d12/d3d12_test.h b/util/test/demos/d3d12/d3d12_test.h index ef953385a..d4b32024f 100644 --- a/util/test/demos/d3d12/d3d12_test.h +++ b/util/test/demos/d3d12/d3d12_test.h @@ -146,6 +146,8 @@ struct D3D12GraphicsTest : public GraphicsTest void setMarker(ID3D12GraphicsCommandListPtr cmd, const std::string &name); void popMarker(ID3D12GraphicsCommandListPtr cmd); + void blitToSwap(ID3D12GraphicsCommandListPtr cmd, ID3D12ResourcePtr src, ID3D12ResourcePtr dst); + void ResourceBarrier(ID3D12GraphicsCommandListPtr cmd, ID3D12ResourcePtr res, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after); void ResourceBarrier(ID3D12ResourcePtr res, D3D12_RESOURCE_STATES before, @@ -200,6 +202,9 @@ struct D3D12GraphicsTest : public GraphicsTest ID3D12ResourcePtr bbTex[2]; uint32_t texIdx = 0; + ID3D12RootSignaturePtr swapBlitSig; + ID3D12PipelineStatePtr swapBlitPso; + bool gpuva = false, m_12On7 = false; IDXGIFactory1Ptr m_Factory; diff --git a/util/test/demos/gl/gl_cbuffer_zoo.cpp b/util/test/demos/gl/gl_cbuffer_zoo.cpp index 53fba7272..8aee07cd2 100644 --- a/util/test/demos/gl/gl_cbuffer_zoo.cpp +++ b/util/test/demos/gl/gl_cbuffer_zoo.cpp @@ -584,6 +584,8 @@ void main() glDrawArrays(GL_TRIANGLES, 0, 3); + blitToSwap(colattach); + Present(); } diff --git a/util/test/demos/gl/gl_test.cpp b/util/test/demos/gl/gl_test.cpp index 581ab7d46..8cae33b3f 100644 --- a/util/test/demos/gl/gl_test.cpp +++ b/util/test/demos/gl/gl_test.cpp @@ -92,12 +92,16 @@ void OpenGLGraphicsTest::PostInit() TEST_LOG("Running GL test on %s / %s / %s", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); + + swapBlitFBO = MakeFBO(); } void OpenGLGraphicsTest::Shutdown() { ActivateContext(mainWindow, mainContext); + glDeleteFramebuffers(1, &swapBlitFBO); + if(!managedResources.bufs.empty()) glDeleteBuffers((GLsizei)managedResources.bufs.size(), &managedResources.bufs[0]); if(!managedResources.texs.empty()) @@ -374,6 +378,24 @@ void OpenGLGraphicsTest::popMarker() glPopDebugGroup(); } +void OpenGLGraphicsTest::blitToSwap(GLuint tex) +{ + GLint oldRead = 0, oldDraw = 0; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRead); + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldDraw); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, swapBlitFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + + glBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, oldRead); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDraw); +} + bool OpenGLGraphicsTest::Running() { if(!FrameLimit()) diff --git a/util/test/demos/gl/gl_test.h b/util/test/demos/gl/gl_test.h index 1beea9119..57dce902d 100644 --- a/util/test/demos/gl/gl_test.h +++ b/util/test/demos/gl/gl_test.h @@ -59,6 +59,8 @@ struct OpenGLGraphicsTest : public GraphicsTest void setMarker(const std::string &name); void popMarker(); + void blitToSwap(GLuint tex); + bool Running(); void Present(GraphicsWindow *window); void Present() { Present(mainWindow); } @@ -67,6 +69,8 @@ struct OpenGLGraphicsTest : public GraphicsTest bool coreProfile = true; bool gles = false; + GLuint swapBlitFBO; + GraphicsWindow *mainWindow = NULL; void *mainContext = NULL; bool inited = false; diff --git a/util/test/demos/vk/vk_test.cpp b/util/test/demos/vk/vk_test.cpp index 8dc6c2527..198cb313c 100644 --- a/util/test/demos/vk/vk_test.cpp +++ b/util/test/demos/vk/vk_test.cpp @@ -776,6 +776,24 @@ void VulkanGraphicsTest::popMarker(VkCommandBuffer cmd) vkCmdEndDebugUtilsLabelEXT(cmd); } +void VulkanGraphicsTest::blitToSwap(VkCommandBuffer cmd, VkImage src, VkImageLayout srcLayout, + VkImage dst, VkImageLayout dstLayout) +{ + VkImageBlit region = {}; + region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.srcSubresource.layerCount = 1; + region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.dstSubresource.layerCount = 1; + region.srcOffsets[1].x = mainWindow->scissor.extent.width; + region.srcOffsets[1].y = mainWindow->scissor.extent.height; + region.srcOffsets[1].z = 1; + region.dstOffsets[1].x = mainWindow->scissor.extent.width; + region.dstOffsets[1].y = mainWindow->scissor.extent.height; + region.dstOffsets[1].z = 1; + + vkCmdBlitImage(cmd, src, srcLayout, dst, dstLayout, 1, ®ion, VK_FILTER_LINEAR); +} + void VulkanGraphicsTest::pushMarker(VkQueue q, const std::string &name) { if(vkQueueBeginDebugUtilsLabelEXT) diff --git a/util/test/demos/vk/vk_test.h b/util/test/demos/vk/vk_test.h index fadd334f4..259ca76cc 100644 --- a/util/test/demos/vk/vk_test.h +++ b/util/test/demos/vk/vk_test.h @@ -206,6 +206,9 @@ struct VulkanGraphicsTest : public GraphicsTest void setMarker(VkQueue queue, const std::string &name); void popMarker(VkQueue queue); + void blitToSwap(VkCommandBuffer cmd, VkImage src, VkImageLayout srcLayout, VkImage dst, + VkImageLayout dstLayout); + template void setName(T obj, const std::string &name);