mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Correctly handle programs that don't create graphics queues
This commit is contained in:
@@ -2252,6 +2252,19 @@ void WrappedID3D12Device::StartFrameCapture(DeviceOwnedWindow devWnd)
|
||||
|
||||
RDCLOG("Starting capture");
|
||||
|
||||
if(m_Queue == NULL)
|
||||
{
|
||||
RDCLOG("Creating direct queue as none was found in the application");
|
||||
|
||||
// pretend this is the application's call and just release - everything else will be handled the
|
||||
// same (the queue will be kept alive internally)
|
||||
ID3D12CommandQueue *q = NULL;
|
||||
D3D12_COMMAND_QUEUE_DESC desc = {};
|
||||
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), (void **)&q);
|
||||
q->Release();
|
||||
}
|
||||
|
||||
WrappedID3D12CommandAllocator::PauseResets();
|
||||
|
||||
m_CaptureTimer.Restart();
|
||||
|
||||
@@ -1796,6 +1796,14 @@ void WrappedVulkan::StartFrameCapture(DeviceOwnedWindow devWnd)
|
||||
|
||||
RDCLOG("Starting capture");
|
||||
|
||||
if(m_Queue == VK_NULL_HANDLE && m_QueueFamilyIdx != ~0U)
|
||||
{
|
||||
RDCLOG("Creating desired queue as none was obtained by the application");
|
||||
|
||||
VkQueue q = VK_NULL_HANDLE;
|
||||
vkGetDeviceQueue(m_Device, m_QueueFamilyIdx, 0, &q);
|
||||
}
|
||||
|
||||
Atomic::Dec32(&m_ReuseEnabled);
|
||||
|
||||
m_CaptureTimer.Restart();
|
||||
|
||||
@@ -12,6 +12,7 @@ set(VULKAN_SRC
|
||||
vk/vk_adv_cbuffer_zoo.cpp
|
||||
vk/vk_buffer_truncation.cpp
|
||||
vk/vk_cbuffer_zoo.cpp
|
||||
vk/vk_compute_only.cpp
|
||||
vk/vk_custom_border_color.cpp
|
||||
vk/vk_dedicated_allocation.cpp
|
||||
vk/vk_descriptor_index.cpp
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020-2022 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d12_test.h"
|
||||
|
||||
RD_TEST(D3D12_Compute_Only, D3D12GraphicsTest)
|
||||
{
|
||||
static constexpr const char *Description =
|
||||
"Test that uses a compute only queue with no graphics queue";
|
||||
|
||||
std::string compute = R"EOSHADER(
|
||||
|
||||
cbuffer blah : register(b0)
|
||||
{
|
||||
uint4 mult;
|
||||
};
|
||||
|
||||
RWStructuredBuffer<uint4> bufin : register(u0);
|
||||
RWStructuredBuffer<uint4> bufout : register(u1);
|
||||
|
||||
[numthreads(1,1,1)]
|
||||
void main()
|
||||
{
|
||||
bufout[0].x += bufin[0].x * mult.x;
|
||||
bufout[0].y += bufin[0].y * mult.y;
|
||||
bufout[0].z += bufin[0].z * mult.z;
|
||||
bufout[0].w += bufin[0].w * mult.w;
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
int main()
|
||||
{
|
||||
headless = true;
|
||||
queueType = D3D12_COMMAND_LIST_TYPE_COMPUTE;
|
||||
|
||||
// initialise, create window, create device, etc
|
||||
if(!Init())
|
||||
return 3;
|
||||
|
||||
ID3DBlobPtr csblob = Compile(compute, "main", "cs_5_0");
|
||||
|
||||
ID3D12RootSignaturePtr sig = MakeSig({
|
||||
uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0), uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 1),
|
||||
constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0, 4),
|
||||
tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 2, 1, 3),
|
||||
});
|
||||
ID3D12PipelineStatePtr pso = MakePSO().RootSig(sig).CS(csblob);
|
||||
|
||||
ID3D12ResourcePtr bufin = MakeBuffer().Size(1024).UAV();
|
||||
ID3D12ResourcePtr bufout = MakeBuffer().Size(1024).UAV();
|
||||
|
||||
bufin->SetName(L"bufin");
|
||||
bufout->SetName(L"bufout");
|
||||
|
||||
ID3D12ResourcePtr tex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, 8, 8)
|
||||
.InitialState(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)
|
||||
.UAV();
|
||||
|
||||
tex->SetName(L"tex");
|
||||
|
||||
{
|
||||
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
|
||||
Reset(cmd);
|
||||
|
||||
float col[] = {0.25f, 0.5f, 0.75f, 1.0f};
|
||||
|
||||
D3D12_RECT rect = {};
|
||||
rect.right = rect.bottom = 8;
|
||||
cmd->ClearUnorderedAccessViewFloat(
|
||||
MakeUAV(tex).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateGPU(3),
|
||||
MakeUAV(tex).Format(DXGI_FORMAT_R32G32B32A32_FLOAT).CreateClearCPU(3), tex, col, 1, &rect);
|
||||
|
||||
cmd->Close();
|
||||
Submit({cmd});
|
||||
}
|
||||
|
||||
if(rdoc)
|
||||
rdoc->StartFrameCapture(NULL, NULL);
|
||||
|
||||
{
|
||||
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
|
||||
Reset(cmd);
|
||||
|
||||
uint32_t a[4] = {111, 111, 111, 111};
|
||||
uint32_t b[4] = {222, 222, 222, 222};
|
||||
|
||||
D3D12_RECT rect = {};
|
||||
rect.right = 1024;
|
||||
rect.bottom = 1;
|
||||
cmd->ClearUnorderedAccessViewUint(
|
||||
MakeUAV(bufin).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateGPU(0),
|
||||
MakeUAV(bufin).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateClearCPU(0), bufin, a, 1, &rect);
|
||||
cmd->ClearUnorderedAccessViewUint(
|
||||
MakeUAV(bufout).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateGPU(1),
|
||||
MakeUAV(bufout).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateClearCPU(1), bufin, b, 1,
|
||||
&rect);
|
||||
|
||||
setMarker(cmd, "Pre-Dispatch");
|
||||
|
||||
cmd->SetComputeRootSignature(sig);
|
||||
cmd->SetPipelineState(pso);
|
||||
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
|
||||
cmd->SetComputeRootUnorderedAccessView(0, bufin->GetGPUVirtualAddress());
|
||||
cmd->SetComputeRootUnorderedAccessView(1, bufout->GetGPUVirtualAddress());
|
||||
cmd->SetComputeRoot32BitConstant(2, 5, 0);
|
||||
cmd->SetComputeRoot32BitConstant(2, 6, 1);
|
||||
cmd->SetComputeRoot32BitConstant(2, 7, 2);
|
||||
cmd->SetComputeRoot32BitConstant(2, 8, 3);
|
||||
cmd->SetComputeRootDescriptorTable(3, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
|
||||
cmd->Dispatch(1, 1, 1);
|
||||
|
||||
setMarker(cmd, "Post-Dispatch");
|
||||
|
||||
cmd->Close();
|
||||
Submit({cmd});
|
||||
}
|
||||
|
||||
if(rdoc)
|
||||
rdoc->EndFrameCapture(NULL, NULL);
|
||||
|
||||
GPUSync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST();
|
||||
@@ -156,6 +156,19 @@ D3D12_ROOT_PARAMETER1 cbvParam(D3D12_SHADER_VISIBILITY vis, UINT space, UINT reg
|
||||
return ret;
|
||||
}
|
||||
|
||||
D3D12_ROOT_PARAMETER1 uavParam(D3D12_SHADER_VISIBILITY vis, UINT space, UINT reg)
|
||||
{
|
||||
D3D12_ROOT_PARAMETER1 ret;
|
||||
|
||||
ret.ShaderVisibility = vis;
|
||||
ret.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
ret.Descriptor.RegisterSpace = space;
|
||||
ret.Descriptor.ShaderRegister = reg;
|
||||
ret.Descriptor.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
D3D12_ROOT_PARAMETER1 constParam(D3D12_SHADER_VISIBILITY vis, UINT space, UINT reg, UINT num)
|
||||
{
|
||||
D3D12_ROOT_PARAMETER1 ret;
|
||||
|
||||
@@ -265,6 +265,7 @@ private:
|
||||
};
|
||||
|
||||
D3D12_ROOT_PARAMETER1 cbvParam(D3D12_SHADER_VISIBILITY vis, UINT space, UINT reg);
|
||||
D3D12_ROOT_PARAMETER1 uavParam(D3D12_SHADER_VISIBILITY vis, UINT space, UINT reg);
|
||||
|
||||
D3D12_ROOT_PARAMETER1 constParam(D3D12_SHADER_VISIBILITY vis, UINT space, UINT reg, UINT num);
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ void D3D12GraphicsTest::PostDeviceCreate()
|
||||
{
|
||||
{
|
||||
D3D12_COMMAND_QUEUE_DESC desc = {};
|
||||
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
desc.Type = queueType;
|
||||
dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), (void **)&queue);
|
||||
}
|
||||
|
||||
@@ -325,13 +325,13 @@ void D3D12GraphicsTest::PostDeviceCreate()
|
||||
|
||||
m_GPUSyncFence->SetName(L"GPUSync fence");
|
||||
|
||||
CHECK_HR(dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
__uuidof(ID3D12CommandAllocator), (void **)&m_Alloc));
|
||||
CHECK_HR(
|
||||
dev->CreateCommandAllocator(queueType, __uuidof(ID3D12CommandAllocator), (void **)&m_Alloc));
|
||||
|
||||
m_Alloc->SetName(L"Command allocator");
|
||||
|
||||
CHECK_HR(dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_Alloc, NULL,
|
||||
__uuidof(ID3D12GraphicsCommandList), (void **)&m_DebugList));
|
||||
CHECK_HR(dev->CreateCommandList(0, queueType, m_Alloc, NULL, __uuidof(ID3D12GraphicsCommandList),
|
||||
(void **)&m_DebugList));
|
||||
|
||||
// command buffers are allocated opened, close it immediately.
|
||||
m_DebugList->Close();
|
||||
@@ -1349,7 +1349,7 @@ ID3D12GraphicsCommandListPtr D3D12GraphicsTest::GetCommandBuffer()
|
||||
if(freeCommandBuffers.empty())
|
||||
{
|
||||
ID3D12GraphicsCommandListPtr list = NULL;
|
||||
CHECK_HR(dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_Alloc, NULL,
|
||||
CHECK_HR(dev->CreateCommandList(0, queueType, m_Alloc, NULL,
|
||||
__uuidof(ID3D12GraphicsCommandList), (void **)&list));
|
||||
// list starts opened, close it
|
||||
list->Close();
|
||||
|
||||
@@ -226,6 +226,7 @@ struct D3D12GraphicsTest : public GraphicsTest
|
||||
ID3D12CommandAllocatorPtr m_Alloc;
|
||||
ID3D12GraphicsCommandListPtr m_DebugList;
|
||||
|
||||
D3D12_COMMAND_LIST_TYPE queueType = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
ID3D12CommandQueuePtr queue;
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS opts = {};
|
||||
|
||||
@@ -179,6 +179,7 @@
|
||||
<ClCompile Include="d3d12\d3d12_amd_shader_extensions.cpp" />
|
||||
<ClCompile Include="d3d12\d3d12_buffer_truncation.cpp" />
|
||||
<ClCompile Include="d3d12\d3d12_cbuffer_zoo.cpp" />
|
||||
<ClCompile Include="d3d12\d3d12_compute_only.cpp" />
|
||||
<ClCompile Include="d3d12\d3d12_descriptor_indexing.cpp" />
|
||||
<ClCompile Include="d3d12\d3d12_discard_zoo.cpp" />
|
||||
<ClCompile Include="d3d12\d3d12_draw_zoo.cpp" />
|
||||
@@ -280,6 +281,7 @@
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="test_common.cpp" />
|
||||
<ClCompile Include="texture_zoo.cpp" />
|
||||
<ClCompile Include="vk\vk_compute_only.cpp" />
|
||||
<ClCompile Include="vk\vk_custom_border_color.cpp" />
|
||||
<ClCompile Include="vk\vk_dedicated_allocation.cpp" />
|
||||
<ClCompile Include="vk\vk_descriptor_reuse.cpp" />
|
||||
|
||||
@@ -628,6 +628,12 @@
|
||||
<ClCompile Include="gl\gl_depth_bounds.cpp">
|
||||
<Filter>OpenGL\demos</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vk\vk_compute_only.cpp">
|
||||
<Filter>Vulkan\demos</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d12\d3d12_compute_only.cpp">
|
||||
<Filter>D3D12\demos</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="D3D11">
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019-2022 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "vk_test.h"
|
||||
|
||||
RD_TEST(VK_Compute_Only, VulkanGraphicsTest)
|
||||
{
|
||||
static constexpr const char *Description =
|
||||
"Test that uses a compute only queue with no graphics queue.";
|
||||
|
||||
const std::string comp = R"EOSHADER(
|
||||
|
||||
#version 450 core
|
||||
|
||||
layout(push_constant) uniform PushData
|
||||
{
|
||||
uvec4 data;
|
||||
} push;
|
||||
|
||||
layout(binding = 0, std430) buffer inbuftype {
|
||||
uvec4 data[];
|
||||
} inbuf;
|
||||
|
||||
layout(binding = 1, std430) buffer outbuftype {
|
||||
uvec4 data[];
|
||||
} outbuf;
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main()
|
||||
{
|
||||
outbuf.data[0].x += inbuf.data[0].x * push.data.x;
|
||||
outbuf.data[0].y += inbuf.data[0].y * push.data.y;
|
||||
outbuf.data[0].z += inbuf.data[0].z * push.data.z;
|
||||
outbuf.data[0].w += inbuf.data[0].w * push.data.w;
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
int main()
|
||||
{
|
||||
headless = true;
|
||||
queueFlagsRequired = VK_QUEUE_COMPUTE_BIT;
|
||||
queueFlagsBanned = VK_QUEUE_GRAPHICS_BIT;
|
||||
|
||||
// initialise, create window, create context, etc
|
||||
if(!Init())
|
||||
return 3;
|
||||
|
||||
VkDescriptorSetLayout setLayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
||||
{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
{2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT},
|
||||
}));
|
||||
|
||||
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
|
||||
{setLayout},
|
||||
{
|
||||
vkh::PushConstantRange(VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(Vec4i)),
|
||||
}));
|
||||
|
||||
VkPipeline pipe = createComputePipeline(vkh::ComputePipelineCreateInfo(
|
||||
layout, CompileShaderModule(comp, ShaderLang::glsl, ShaderStage::comp, "main")));
|
||||
|
||||
AllocatedImage tex(
|
||||
this, vkh::ImageCreateInfo(4, 4, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
||||
|
||||
setName(tex.image, "tex");
|
||||
|
||||
VkImageView view = createImageView(
|
||||
vkh::ImageViewCreateInfo(tex.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT));
|
||||
|
||||
AllocatedBuffer bufin(this, vkh::BufferCreateInfo(1024, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
AllocatedBuffer bufout(this, vkh::BufferCreateInfo(1024, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
||||
|
||||
setName(bufin.buffer, "bufin");
|
||||
setName(bufout.buffer, "bufout");
|
||||
|
||||
VkDescriptorSet set = allocateDescriptorSet(setLayout);
|
||||
|
||||
vkh::updateDescriptorSets(
|
||||
device, {
|
||||
vkh::WriteDescriptorSet(set, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
{vkh::DescriptorBufferInfo(bufin.buffer)}),
|
||||
vkh::WriteDescriptorSet(set, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
{vkh::DescriptorBufferInfo(bufout.buffer)}),
|
||||
vkh::WriteDescriptorSet(
|
||||
set, 2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
{vkh::DescriptorImageInfo(view, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
||||
});
|
||||
|
||||
// clear the buffers
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
|
||||
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
||||
|
||||
vkCmdFillBuffer(cmd, bufin.buffer, 0, 1024, 111);
|
||||
vkCmdFillBuffer(cmd, bufout.buffer, 0, 1024, 222);
|
||||
|
||||
vkh::cmdPipelineBarrier(
|
||||
cmd,
|
||||
{
|
||||
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_GENERAL, tex.image),
|
||||
},
|
||||
{
|
||||
vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
bufin.buffer, 0, 1024),
|
||||
vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
|
||||
bufout.buffer, 0, 1024),
|
||||
});
|
||||
|
||||
vkCmdClearColorImage(cmd, tex.image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
vkh::ClearColorValue(0.25f, 0.5f, 0.75f, 1.0f), 1,
|
||||
vkh::ImageSubresourceRange());
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd});
|
||||
}
|
||||
|
||||
if(rdoc)
|
||||
rdoc->StartFrameCapture(NULL, NULL);
|
||||
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
|
||||
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipe);
|
||||
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, layout, 0, {set}, {});
|
||||
|
||||
setMarker(cmd, "Pre-Dispatch");
|
||||
|
||||
Vec4i push = {5, 6, 7, 8};
|
||||
vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(Vec4i), &push);
|
||||
vkCmdDispatch(cmd, 1, 1, 1);
|
||||
|
||||
setMarker(cmd, "Post-Dispatch");
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd});
|
||||
}
|
||||
|
||||
if(rdoc)
|
||||
rdoc->EndFrameCapture(NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST();
|
||||
@@ -143,7 +143,7 @@ RD_TEST(VK_Multi_Present, VulkanGraphicsTest)
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd}, {}, win);
|
||||
win->Submit(0, 1, {cmd}, {}, queue);
|
||||
}
|
||||
|
||||
VulkanWindow::MultiPresent(queue, presentWindows);
|
||||
|
||||
@@ -129,9 +129,9 @@ RD_TEST(VK_Multi_Thread_Windows, VulkanGraphicsTest)
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd}, {}, win, q);
|
||||
win->Submit(0, 1, {cmd}, {}, q);
|
||||
|
||||
Present(win, q);
|
||||
win->Present(q);
|
||||
} while(win);
|
||||
};
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ RD_TEST(VK_Synchronization_2, VulkanGraphicsTest)
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
|
||||
Submit(0, 1, {cmd}, {}, NULL, VK_NULL_HANDLE, true);
|
||||
Submit(0, 1, {cmd});
|
||||
|
||||
Present();
|
||||
|
||||
|
||||
+168
-122
@@ -586,15 +586,15 @@ bool VulkanGraphicsTest::Init()
|
||||
std::vector<VkQueueFamilyProperties> queueProps;
|
||||
vkh::getQueueFamilyProperties(queueProps, phys);
|
||||
|
||||
VkQueueFlags required = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
|
||||
|
||||
// if no queue has been selected, find it now
|
||||
if(queueFamilyIndex == ~0U)
|
||||
{
|
||||
// try to find an exact match first
|
||||
for(uint32_t q = 0; q < queueProps.size(); q++)
|
||||
{
|
||||
VkQueueFlags flags = queueProps[q].queueFlags;
|
||||
if((flags & required) == required)
|
||||
|
||||
if(flags == queueFlagsRequired)
|
||||
{
|
||||
queueFamilyIndex = q;
|
||||
queueCount = 1;
|
||||
@@ -605,7 +605,23 @@ bool VulkanGraphicsTest::Init()
|
||||
|
||||
if(queueFamilyIndex == ~0U)
|
||||
{
|
||||
TEST_ERROR("No graphics/compute queues available");
|
||||
// if we didn't find an exact match, look for any that does satisfy what we want
|
||||
for(uint32_t q = 0; q < queueProps.size(); q++)
|
||||
{
|
||||
VkQueueFlags flags = queueProps[q].queueFlags;
|
||||
|
||||
if(((flags & queueFlagsRequired) == queueFlagsRequired) && ((flags & queueFlagsBanned) == 0))
|
||||
{
|
||||
queueFamilyIndex = q;
|
||||
queueCount = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(queueFamilyIndex == ~0U)
|
||||
{
|
||||
TEST_ERROR("No satisfactory queue family available");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -638,13 +654,17 @@ bool VulkanGraphicsTest::Init()
|
||||
volkLoadDevice(device);
|
||||
|
||||
vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue);
|
||||
mainWindow = MakeWindow(screenWidth, screenHeight, "Autotesting");
|
||||
|
||||
if(!mainWindow->Initialised())
|
||||
if(!headless)
|
||||
{
|
||||
TEST_ERROR("Error creating surface");
|
||||
return false;
|
||||
};
|
||||
mainWindow = MakeWindow(screenWidth, screenHeight, "Autotesting");
|
||||
|
||||
if(!mainWindow->Initialised())
|
||||
{
|
||||
TEST_ERROR("Error creating surface");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
VmaVulkanFunctions funcs = {
|
||||
vkGetPhysicalDeviceProperties,
|
||||
@@ -680,6 +700,8 @@ bool VulkanGraphicsTest::Init()
|
||||
TEST_LOG("Running Vulkan test on %s (version %d.%d)", physProperties.deviceName,
|
||||
VK_VERSION_MAJOR(physProperties.apiVersion), VK_VERSION_MINOR(physProperties.apiVersion));
|
||||
|
||||
headlessCmds = new VulkanCommands(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -738,6 +760,9 @@ void VulkanGraphicsTest::Shutdown()
|
||||
|
||||
vmaDestroyAllocator(allocator);
|
||||
|
||||
if(headlessCmds)
|
||||
delete headlessCmds;
|
||||
|
||||
delete mainWindow;
|
||||
|
||||
vkDestroyDevice(device, NULL);
|
||||
@@ -789,27 +814,17 @@ void VulkanGraphicsTest::FinishUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlag
|
||||
}
|
||||
|
||||
void VulkanGraphicsTest::Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
|
||||
const std::vector<VkCommandBuffer> &seccmds, VulkanWindow *window,
|
||||
VkQueue q, bool sync2)
|
||||
const std::vector<VkCommandBuffer> &seccmds)
|
||||
{
|
||||
if(window == NULL)
|
||||
window = mainWindow;
|
||||
|
||||
if(q == VK_NULL_HANDLE)
|
||||
q = queue;
|
||||
|
||||
window->Submit(index, totalSubmits, cmds, seccmds, q, sync2);
|
||||
if(mainWindow)
|
||||
mainWindow->Submit(index, totalSubmits, cmds, seccmds, queue);
|
||||
else
|
||||
headlessCmds->Submit(cmds, seccmds, queue, VK_NULL_HANDLE, VK_NULL_HANDLE);
|
||||
}
|
||||
|
||||
void VulkanGraphicsTest::Present(VulkanWindow *window, VkQueue q)
|
||||
void VulkanGraphicsTest::Present()
|
||||
{
|
||||
if(!window)
|
||||
window = mainWindow;
|
||||
|
||||
if(q == VK_NULL_HANDLE)
|
||||
q = queue;
|
||||
|
||||
window->Present(q);
|
||||
mainWindow->Present(queue);
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo VulkanGraphicsTest::CompileShaderModule(
|
||||
@@ -845,25 +860,10 @@ VkCommandBuffer VulkanGraphicsTest::GetCommandBuffer(VkCommandBufferLevel level,
|
||||
if(window == NULL)
|
||||
window = mainWindow;
|
||||
|
||||
return window->GetCommandBuffer(level);
|
||||
}
|
||||
if(window)
|
||||
return window->GetCommandBuffer(level);
|
||||
|
||||
VkCommandBuffer VulkanWindow::GetCommandBuffer(VkCommandBufferLevel level)
|
||||
{
|
||||
std::vector<VkCommandBuffer> &buflist = freeCommandBuffers[level];
|
||||
|
||||
if(buflist.empty())
|
||||
{
|
||||
buflist.resize(4);
|
||||
|
||||
CHECK_VKR(vkAllocateCommandBuffers(
|
||||
m_Test->device, vkh::CommandBufferAllocateInfo(cmdPool, 4, level), &buflist[0]));
|
||||
}
|
||||
|
||||
VkCommandBuffer ret = buflist.back();
|
||||
buflist.pop_back();
|
||||
|
||||
return ret;
|
||||
return headlessCmds->GetCommandBuffer(level);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -1136,8 +1136,117 @@ VkSampler VulkanGraphicsTest::createSampler(const VkSamplerCreateInfo *info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
VulkanCommands::VulkanCommands(VulkanGraphicsTest *test)
|
||||
{
|
||||
m_Test = test;
|
||||
|
||||
CHECK_VKR(vkCreateCommandPool(
|
||||
m_Test->device, vkh::CommandPoolCreateInfo(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
||||
m_Test->queueFamilyIndex),
|
||||
NULL, &cmdPool));
|
||||
}
|
||||
|
||||
VulkanCommands::~VulkanCommands()
|
||||
{
|
||||
vkDestroyCommandPool(m_Test->device, cmdPool, NULL);
|
||||
|
||||
for(VkFence fence : fences)
|
||||
vkDestroyFence(m_Test->device, fence, NULL);
|
||||
}
|
||||
|
||||
VkCommandBuffer VulkanCommands::GetCommandBuffer(VkCommandBufferLevel level)
|
||||
{
|
||||
std::vector<VkCommandBuffer> &buflist = freeCommandBuffers[level];
|
||||
|
||||
if(buflist.empty())
|
||||
{
|
||||
buflist.resize(4);
|
||||
|
||||
CHECK_VKR(vkAllocateCommandBuffers(
|
||||
m_Test->device, vkh::CommandBufferAllocateInfo(cmdPool, 4, level), &buflist[0]));
|
||||
}
|
||||
|
||||
VkCommandBuffer ret = buflist.back();
|
||||
buflist.pop_back();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VulkanCommands::Submit(const std::vector<VkCommandBuffer> &cmds,
|
||||
const std::vector<VkCommandBuffer> &seccmds, VkQueue q,
|
||||
VkSemaphore wait, VkSemaphore signal)
|
||||
{
|
||||
VkFence fence;
|
||||
CHECK_VKR(vkCreateFence(m_Test->device, vkh::FenceCreateInfo(), NULL, &fence));
|
||||
|
||||
fences.insert(fence);
|
||||
|
||||
if(m_Test->hasExt(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME))
|
||||
{
|
||||
VkSubmitInfo2KHR submit = {VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR};
|
||||
|
||||
std::vector<VkCommandBufferSubmitInfoKHR> cmdSubmits;
|
||||
for(VkCommandBuffer cmd : cmds)
|
||||
cmdSubmits.push_back({VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR, NULL, cmd, 0});
|
||||
|
||||
submit.commandBufferInfoCount = (uint32_t)cmdSubmits.size();
|
||||
submit.pCommandBufferInfos = cmdSubmits.data();
|
||||
|
||||
VkSemaphoreSubmitInfoKHR waitInfo = {}, signalInfo = {};
|
||||
|
||||
if(wait != VK_NULL_HANDLE)
|
||||
{
|
||||
waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR;
|
||||
waitInfo.semaphore = wait;
|
||||
waitInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
|
||||
|
||||
submit.waitSemaphoreInfoCount = 1;
|
||||
submit.pWaitSemaphoreInfos = &waitInfo;
|
||||
}
|
||||
|
||||
if(signal != VK_NULL_HANDLE)
|
||||
{
|
||||
signalInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR;
|
||||
signalInfo.semaphore = signal;
|
||||
signalInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
|
||||
|
||||
submit.signalSemaphoreInfoCount = 1;
|
||||
submit.pSignalSemaphoreInfos = &signalInfo;
|
||||
}
|
||||
|
||||
CHECK_VKR(vkQueueSubmit2KHR(q, 1, &submit, fence));
|
||||
}
|
||||
else
|
||||
{
|
||||
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
|
||||
VkSubmitInfo submit = vkh::SubmitInfo(cmds);
|
||||
|
||||
if(wait != VK_NULL_HANDLE)
|
||||
{
|
||||
submit.waitSemaphoreCount = 1;
|
||||
submit.pWaitDstStageMask = &waitStage;
|
||||
submit.pWaitSemaphores = &wait;
|
||||
}
|
||||
|
||||
if(signal != VK_NULL_HANDLE)
|
||||
{
|
||||
submit.signalSemaphoreCount = 1;
|
||||
submit.pSignalSemaphores = &signal;
|
||||
}
|
||||
|
||||
CHECK_VKR(vkQueueSubmit(q, 1, &submit, fence));
|
||||
}
|
||||
|
||||
for(const VkCommandBuffer &cmd : cmds)
|
||||
pendingCommandBuffers[0].push_back(std::make_pair(cmd, fence));
|
||||
|
||||
for(const VkCommandBuffer &cmd : seccmds)
|
||||
pendingCommandBuffers[1].push_back(std::make_pair(cmd, fence));
|
||||
}
|
||||
|
||||
VulkanWindow::VulkanWindow(VulkanGraphicsTest *test, GraphicsWindow *win)
|
||||
: GraphicsWindow(win->title)
|
||||
: GraphicsWindow(win->title), VulkanCommands(test)
|
||||
{
|
||||
m_Test = test;
|
||||
m_Win = win;
|
||||
@@ -1145,10 +1254,6 @@ VulkanWindow::VulkanWindow(VulkanGraphicsTest *test, GraphicsWindow *win)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_Test->mutex);
|
||||
|
||||
CHECK_VKR(vkCreateCommandPool(
|
||||
m_Test->device, vkh::CommandPoolCreateInfo(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT),
|
||||
NULL, &cmdPool));
|
||||
|
||||
CHECK_VKR(
|
||||
vkCreateSemaphore(m_Test->device, vkh::SemaphoreCreateInfo(), NULL, &renderStartSemaphore));
|
||||
CHECK_VKR(
|
||||
@@ -1193,11 +1298,6 @@ VulkanWindow::~VulkanWindow()
|
||||
vkDestroySemaphore(m_Test->device, renderStartSemaphore, NULL);
|
||||
vkDestroySemaphore(m_Test->device, renderEndSemaphore, NULL);
|
||||
|
||||
vkDestroyCommandPool(m_Test->device, cmdPool, NULL);
|
||||
|
||||
for(VkFence fence : fences)
|
||||
vkDestroyFence(m_Test->device, fence, NULL);
|
||||
|
||||
if(surface)
|
||||
vkDestroySurfaceKHR(m_Test->instance, surface, NULL);
|
||||
}
|
||||
@@ -1328,75 +1428,16 @@ void VulkanWindow::Acquire()
|
||||
}
|
||||
|
||||
void VulkanWindow::Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
|
||||
const std::vector<VkCommandBuffer> &seccmds, VkQueue q, bool sync2)
|
||||
const std::vector<VkCommandBuffer> &seccmds, VkQueue q)
|
||||
{
|
||||
VkFence fence;
|
||||
CHECK_VKR(vkCreateFence(m_Test->device, vkh::FenceCreateInfo(), NULL, &fence));
|
||||
VkSemaphore signal = VK_NULL_HANDLE, wait = VK_NULL_HANDLE;
|
||||
|
||||
fences.insert(fence);
|
||||
if(index == 0)
|
||||
wait = renderStartSemaphore;
|
||||
if(index == totalSubmits - 1)
|
||||
signal = renderEndSemaphore;
|
||||
|
||||
if(sync2)
|
||||
{
|
||||
VkSubmitInfo2KHR submit = {VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR};
|
||||
|
||||
std::vector<VkCommandBufferSubmitInfoKHR> cmdSubmits;
|
||||
for(VkCommandBuffer cmd : cmds)
|
||||
cmdSubmits.push_back({VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR, NULL, cmd, 0});
|
||||
|
||||
submit.commandBufferInfoCount = (uint32_t)cmdSubmits.size();
|
||||
submit.pCommandBufferInfos = cmdSubmits.data();
|
||||
|
||||
VkSemaphoreSubmitInfoKHR renderStart = {}, renderEnd = {};
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
renderStart.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR;
|
||||
renderStart.semaphore = renderStartSemaphore;
|
||||
renderStart.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
|
||||
|
||||
submit.waitSemaphoreInfoCount = 1;
|
||||
submit.pWaitSemaphoreInfos = &renderStart;
|
||||
}
|
||||
|
||||
if(index == totalSubmits - 1)
|
||||
{
|
||||
renderEnd.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR;
|
||||
renderEnd.semaphore = renderEndSemaphore;
|
||||
renderEnd.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
|
||||
|
||||
submit.signalSemaphoreInfoCount = 1;
|
||||
submit.pSignalSemaphoreInfos = &renderEnd;
|
||||
}
|
||||
|
||||
CHECK_VKR(vkQueueSubmit2KHR(q, 1, &submit, fence));
|
||||
}
|
||||
else
|
||||
{
|
||||
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
|
||||
VkSubmitInfo submit = vkh::SubmitInfo(cmds);
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
submit.waitSemaphoreCount = 1;
|
||||
submit.pWaitDstStageMask = &waitStage;
|
||||
submit.pWaitSemaphores = &renderStartSemaphore;
|
||||
}
|
||||
|
||||
if(index == totalSubmits - 1)
|
||||
{
|
||||
submit.signalSemaphoreCount = 1;
|
||||
submit.pSignalSemaphores = &renderEndSemaphore;
|
||||
}
|
||||
|
||||
CHECK_VKR(vkQueueSubmit(q, 1, &submit, fence));
|
||||
}
|
||||
|
||||
for(const VkCommandBuffer &cmd : cmds)
|
||||
pendingCommandBuffers[0].push_back(std::make_pair(cmd, fence));
|
||||
|
||||
for(const VkCommandBuffer &cmd : seccmds)
|
||||
pendingCommandBuffers[1].push_back(std::make_pair(cmd, fence));
|
||||
VulkanCommands::Submit(cmds, seccmds, q, wait, signal);
|
||||
}
|
||||
|
||||
void VulkanWindow::MultiPresent(VkQueue queue, std::vector<VulkanWindow *> windows)
|
||||
@@ -1463,6 +1504,13 @@ void VulkanWindow::PostPresent(VkResult vkr)
|
||||
CHECK_VKR(queuePresentError);
|
||||
}
|
||||
|
||||
VulkanCommands::ProcessCompletions();
|
||||
|
||||
Acquire();
|
||||
}
|
||||
|
||||
void VulkanCommands::ProcessCompletions()
|
||||
{
|
||||
std::set<VkFence> doneFences;
|
||||
std::map<VkFence, VkResult> fenceStatus;
|
||||
|
||||
@@ -1494,8 +1542,6 @@ void VulkanWindow::PostPresent(VkResult vkr)
|
||||
vkDestroyFence(m_Test->device, *it, NULL);
|
||||
fences.erase(*it);
|
||||
}
|
||||
|
||||
Acquire();
|
||||
}
|
||||
|
||||
void VulkanWindow::DestroySwapchain()
|
||||
|
||||
@@ -107,7 +107,27 @@ struct AllocatedImage
|
||||
|
||||
struct VulkanGraphicsTest;
|
||||
|
||||
struct VulkanWindow : public GraphicsWindow
|
||||
struct VulkanCommands
|
||||
{
|
||||
public:
|
||||
VulkanCommands(VulkanGraphicsTest *test);
|
||||
~VulkanCommands();
|
||||
VkCommandBuffer GetCommandBuffer(VkCommandBufferLevel level);
|
||||
void Submit(const std::vector<VkCommandBuffer> &cmds, const std::vector<VkCommandBuffer> &seccmds,
|
||||
VkQueue q, VkSemaphore wait, VkSemaphore signal);
|
||||
void ProcessCompletions();
|
||||
|
||||
private:
|
||||
VulkanGraphicsTest *m_Test;
|
||||
|
||||
VkCommandPool cmdPool;
|
||||
std::set<VkFence> fences;
|
||||
|
||||
std::vector<VkCommandBuffer> freeCommandBuffers[2];
|
||||
std::vector<std::pair<VkCommandBuffer, VkFence>> pendingCommandBuffers[2];
|
||||
};
|
||||
|
||||
struct VulkanWindow : public GraphicsWindow, public VulkanCommands
|
||||
{
|
||||
VkFormat format;
|
||||
uint32_t imgIndex = 0;
|
||||
@@ -139,9 +159,8 @@ struct VulkanWindow : public GraphicsWindow
|
||||
return fbs[idx];
|
||||
}
|
||||
bool Initialised() { return swap != VK_NULL_HANDLE; }
|
||||
VkCommandBuffer GetCommandBuffer(VkCommandBufferLevel level);
|
||||
void Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
|
||||
const std::vector<VkCommandBuffer> &seccmds, VkQueue q, bool sync2);
|
||||
const std::vector<VkCommandBuffer> &seccmds, VkQueue q);
|
||||
static void MultiPresent(VkQueue queue, std::vector<VulkanWindow *> windows);
|
||||
void Present(VkQueue q);
|
||||
|
||||
@@ -162,12 +181,6 @@ private:
|
||||
VkSemaphore renderStartSemaphore = VK_NULL_HANDLE, renderEndSemaphore = VK_NULL_HANDLE;
|
||||
std::vector<VkFramebuffer> fbs;
|
||||
|
||||
VkCommandPool cmdPool;
|
||||
std::set<VkFence> fences;
|
||||
|
||||
std::vector<VkCommandBuffer> freeCommandBuffers[2];
|
||||
std::vector<std::pair<VkCommandBuffer, VkFence>> pendingCommandBuffers[2];
|
||||
|
||||
GraphicsWindow *m_Win;
|
||||
VulkanGraphicsTest *m_Test;
|
||||
};
|
||||
@@ -189,9 +202,8 @@ struct VulkanGraphicsTest : public GraphicsTest
|
||||
void FinishUsingBackbuffer(VkCommandBuffer cmd, VkAccessFlags prevUse, VkImageLayout layout,
|
||||
VulkanWindow *window = NULL);
|
||||
void Submit(int index, int totalSubmits, const std::vector<VkCommandBuffer> &cmds,
|
||||
const std::vector<VkCommandBuffer> &seccmds = {}, VulkanWindow *window = NULL,
|
||||
VkQueue q = VK_NULL_HANDLE, bool sync2 = false);
|
||||
void Present(VulkanWindow *window = NULL, VkQueue q = VK_NULL_HANDLE);
|
||||
const std::vector<VkCommandBuffer> &seccmds = {});
|
||||
void Present();
|
||||
|
||||
VkPipelineShaderStageCreateInfo CompileShaderModule(
|
||||
const std::string &source_text, ShaderLang lang, ShaderStage stage,
|
||||
@@ -256,6 +268,9 @@ struct VulkanGraphicsTest : public GraphicsTest
|
||||
// optional extensions, will be added to devExts if supported (allows fallback paths)
|
||||
std::vector<const char *> optDevExts;
|
||||
|
||||
VkQueueFlags queueFlagsRequired = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
|
||||
VkQueueFlags queueFlagsBanned = 0;
|
||||
|
||||
bool hasExt(const char *ext);
|
||||
|
||||
// a custom struct to pass to vkDeviceCreateInfo::pNext
|
||||
@@ -290,6 +305,8 @@ struct VulkanGraphicsTest : public GraphicsTest
|
||||
|
||||
VulkanWindow *mainWindow = NULL;
|
||||
|
||||
VulkanCommands *headlessCmds = NULL;
|
||||
|
||||
// VMA
|
||||
bool vmaDedicated = false;
|
||||
VmaAllocator allocator = VK_NULL_HANDLE;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import renderdoc as rd
|
||||
import rdtest
|
||||
import struct
|
||||
|
||||
|
||||
class D3D12_Compute_Only(rdtest.TestCase):
|
||||
demos_test_name = 'D3D12_Compute_Only'
|
||||
|
||||
def check_capture(self):
|
||||
tex = self.get_resource_by_name("tex").resourceId
|
||||
bufin = self.get_resource_by_name("bufin").resourceId
|
||||
bufout = self.get_resource_by_name("bufout").resourceId
|
||||
|
||||
self.check_pixel_value(tex, 0, 0, [0.25, 0.5, 0.75, 1.0])
|
||||
|
||||
self.controller.SetFrameEvent(self.find_action("Pre-Dispatch").eventId, True)
|
||||
|
||||
uints = struct.unpack_from('=4L', self.controller.GetBufferData(bufin, 0, 0), 0)
|
||||
|
||||
if not rdtest.value_compare(uints, [111, 111, 111, 111]):
|
||||
raise rdtest.TestFailureException(
|
||||
'bufin data is incorrect before dispatch: {}'.format(uints))
|
||||
|
||||
uints = struct.unpack_from('=4L', self.controller.GetBufferData(bufout, 0, 0), 0)
|
||||
|
||||
if not rdtest.value_compare(uints, [222, 222, 222, 222]):
|
||||
raise rdtest.TestFailureException(
|
||||
'bufin data is incorrect before dispatch: {}'.format(uints))
|
||||
|
||||
self.controller.SetFrameEvent(self.find_action("Post-Dispatch").eventId, True)
|
||||
|
||||
uints = struct.unpack_from('=4L', self.controller.GetBufferData(bufout, 0, 0), 0)
|
||||
|
||||
if not rdtest.value_compare(uints, [777, 888, 999, 1110]):
|
||||
raise rdtest.TestFailureException(
|
||||
'bufin data is incorrect after dispatch: {}'.format(uints))
|
||||
@@ -0,0 +1,36 @@
|
||||
import renderdoc as rd
|
||||
import rdtest
|
||||
import struct
|
||||
|
||||
|
||||
class VK_Compute_Only(rdtest.TestCase):
|
||||
demos_test_name = 'VK_Compute_Only'
|
||||
|
||||
def check_capture(self):
|
||||
tex = self.get_resource_by_name("tex").resourceId
|
||||
bufin = self.get_resource_by_name("bufin").resourceId
|
||||
bufout = self.get_resource_by_name("bufout").resourceId
|
||||
|
||||
self.check_pixel_value(tex, 0, 0, [0.25, 0.5, 0.75, 1.0])
|
||||
|
||||
self.controller.SetFrameEvent(self.find_action("Pre-Dispatch").eventId, True)
|
||||
|
||||
uints = struct.unpack_from('=4L', self.controller.GetBufferData(bufin, 0, 0), 0)
|
||||
|
||||
if not rdtest.value_compare(uints, [111, 111, 111, 111]):
|
||||
raise rdtest.TestFailureException(
|
||||
'bufin data is incorrect before dispatch: {}'.format(uints))
|
||||
|
||||
uints = struct.unpack_from('=4L', self.controller.GetBufferData(bufout, 0, 0), 0)
|
||||
|
||||
if not rdtest.value_compare(uints, [222, 222, 222, 222]):
|
||||
raise rdtest.TestFailureException(
|
||||
'bufout data is incorrect before dispatch: {}'.format(uints))
|
||||
|
||||
self.controller.SetFrameEvent(self.find_action("Post-Dispatch").eventId, True)
|
||||
|
||||
uints = struct.unpack_from('=4L', self.controller.GetBufferData(bufout, 0, 0), 0)
|
||||
|
||||
if not rdtest.value_compare(uints, [777, 888, 999, 1110]):
|
||||
raise rdtest.TestFailureException(
|
||||
'bufout data is incorrect after dispatch: {}'.format(uints))
|
||||
Reference in New Issue
Block a user