From ec8564642a5a6903914fd1e1eb94922b614860cf Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 23 May 2019 13:06:33 +0100 Subject: [PATCH] Refactor demo API test initialisation order * Instead of only doing a very lightweight check to see if the API is available up-front, we now share the API initialisation among all API tests far enough to determine availability of extensions, features, etc. Then we can precisely determine which tests are available and which aren't before running. --- util/test/demos/d3d11/d3d11_1_many_uavs.cpp | 4 +- .../demos/d3d11/d3d11_array_interpolator.cpp | 4 +- .../demos/d3d11/d3d11_binding_hazards.cpp | 4 +- .../d3d11/d3d11_byte_address_buffers.cpp | 2 +- util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp | 4 +- .../demos/d3d11/d3d11_counter_query_pred.cpp | 4 +- util/test/demos/d3d11/d3d11_debug_shader.cpp | 2 +- .../d3d11_deferred_updatesubresource.cpp | 4 +- util/test/demos/d3d11/d3d11_discard_view.cpp | 4 +- .../demos/d3d11/d3d11_divergent_shader.cpp | 4 +- util/test/demos/d3d11/d3d11_draw_zoo.cpp | 4 +- .../d3d11/d3d11_empty_compute_dispatch.cpp | 4 +- .../test/demos/d3d11/d3d11_empty_drawcall.cpp | 4 +- .../demos/d3d11/d3d11_empty_viewports.cpp | 4 +- util/test/demos/d3d11/d3d11_many_rtvs.cpp | 4 +- util/test/demos/d3d11/d3d11_map_overrun.cpp | 4 +- .../demos/d3d11/d3d11_midframe_create.cpp | 4 +- util/test/demos/d3d11/d3d11_mip_gen_rt.cpp | 4 +- util/test/demos/d3d11/d3d11_mip_rtv.cpp | 4 +- .../demos/d3d11/d3d11_overdraw_stress.cpp | 4 +- util/test/demos/d3d11/d3d11_overlay_test.cpp | 4 +- .../demos/d3d11/d3d11_primitive_restart.cpp | 4 +- .../test/demos/d3d11/d3d11_refcount_check.cpp | 4 +- .../demos/d3d11/d3d11_resource_lifetimes.cpp | 4 +- util/test/demos/d3d11/d3d11_saturate.cpp | 4 +- .../demos/d3d11/d3d11_simple_dispatch.cpp | 4 +- .../demos/d3d11/d3d11_simple_triangle.cpp | 4 +- util/test/demos/d3d11/d3d11_streamout.cpp | 4 +- .../demos/d3d11/d3d11_stripped_shaders.cpp | 4 +- ...d11_structured_buffer_misaligned_dirty.cpp | 4 +- .../d3d11/d3d11_structured_buffer_nested.cpp | 4 +- .../d3d11/d3d11_structured_buffer_read.cpp | 4 +- util/test/demos/d3d11/d3d11_test.cpp | 185 +++---- util/test/demos/d3d11/d3d11_test.h | 7 +- util/test/demos/d3d11/d3d11_texture_3d.cpp | 4 +- .../test/demos/d3d11/d3d11_video_textures.cpp | 7 +- util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp | 4 +- util/test/demos/d3d12/d3d12_helpers.h | 8 - util/test/demos/d3d12/d3d12_overlay_test.cpp | 4 +- .../demos/d3d12/d3d12_resource_lifetimes.cpp | 4 +- .../demos/d3d12/d3d12_simple_triangle.cpp | 4 +- util/test/demos/d3d12/d3d12_test.cpp | 205 +++----- util/test/demos/d3d12/d3d12_test.h | 4 +- .../test/demos/d3d12/d3d12_video_textures.cpp | 4 +- util/test/demos/dx/d3d_helpers.cpp | 74 +++ util/test/demos/dx/d3d_helpers.h | 15 +- util/test/demos/gl/gl_buffer_updates.cpp | 4 +- util/test/demos/gl/gl_cbuffer_zoo.cpp | 4 +- util/test/demos/gl/gl_depthstencil_fbo.cpp | 4 +- util/test/demos/gl/gl_dx_interop.cpp | 17 +- util/test/demos/gl/gl_entry_points.cpp | 4 +- util/test/demos/gl/gl_large_bcn_arrays.cpp | 4 +- util/test/demos/gl/gl_map_overrun.cpp | 4 +- .../demos/gl/gl_midframe_context_create.cpp | 4 +- util/test/demos/gl/gl_mip_gen_rt.cpp | 4 +- util/test/demos/gl/gl_multi_window.cpp | 4 +- util/test/demos/gl/gl_overlay_test.cpp | 4 +- util/test/demos/gl/gl_resource_lifetimes.cpp | 4 +- .../demos/gl/gl_runtime_bind_prog_to_pipe.cpp | 4 +- .../demos/gl/gl_separable_geometry_shader.cpp | 4 +- util/test/demos/gl/gl_simple_triangle.cpp | 4 +- util/test/demos/gl/gl_spirv_shader.cpp | 4 +- .../demos/gl/gl_structured_buffer_nested.cpp | 4 +- util/test/demos/gl/gl_test.cpp | 3 + util/test/demos/gl/gl_test.h | 4 +- util/test/demos/gl/gl_test_linux.cpp | 41 +- util/test/demos/gl/gl_test_win32.cpp | 70 ++- .../demos/gl/gl_unsized_ms_fbo_attachment.cpp | 4 +- util/test/demos/gl/gl_vao_0.cpp | 4 +- util/test/demos/linux/linux_platform.h | 1 + util/test/demos/main.cpp | 47 +- util/test/demos/test_common.cpp | 72 ++- util/test/demos/test_common.h | 29 +- util/test/demos/vk/vk_adv_cbuffer_zoo.cpp | 49 +- util/test/demos/vk/vk_awkward_triangle.cpp | 4 +- util/test/demos/vk/vk_buffer_address.cpp | 32 +- util/test/demos/vk/vk_cbuffer_zoo.cpp | 10 +- util/test/demos/vk/vk_descriptor_index.cpp | 27 +- util/test/demos/vk/vk_discard_rects.cpp | 10 +- util/test/demos/vk/vk_draw_zoo.cpp | 4 +- util/test/demos/vk/vk_indirect.cpp | 12 +- util/test/demos/vk/vk_overlay_test.cpp | 4 +- util/test/demos/vk/vk_resource_lifetimes.cpp | 4 +- util/test/demos/vk/vk_sample_locations.cpp | 10 +- util/test/demos/vk/vk_secondary_cmdbuf.cpp | 4 +- util/test/demos/vk/vk_simple_triangle.cpp | 4 +- .../demos/vk/vk_structured_buffer_nested.cpp | 4 +- util/test/demos/vk/vk_test.cpp | 484 +++++++++++------- util/test/demos/vk/vk_test.h | 20 +- util/test/demos/vk/vk_video_textures.cpp | 12 +- util/test/demos/vk/vk_vs_max_desc_set.cpp | 4 +- 91 files changed, 932 insertions(+), 775 deletions(-) diff --git a/util/test/demos/d3d11/d3d11_1_many_uavs.cpp b/util/test/demos/d3d11/d3d11_1_many_uavs.cpp index ba72b1656..3d49399d9 100644 --- a/util/test/demos/d3d11/d3d11_1_many_uavs.cpp +++ b/util/test/demos/d3d11/d3d11_1_many_uavs.cpp @@ -41,12 +41,12 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { d3d11_1 = true; // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11ComputeShaderPtr cs = CreateCS(Compile(compute, "main", "cs_5_0")); diff --git a/util/test/demos/d3d11/d3d11_array_interpolator.cpp b/util/test/demos/d3d11/d3d11_array_interpolator.cpp index 57916ce8d..9dc0925b8 100644 --- a/util/test/demos/d3d11/d3d11_array_interpolator.cpp +++ b/util/test/demos/d3d11/d3d11_array_interpolator.cpp @@ -75,10 +75,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_binding_hazards.cpp b/util/test/demos/d3d11/d3d11_binding_hazards.cpp index 646c7fb5a..10338888c 100644 --- a/util/test/demos/d3d11/d3d11_binding_hazards.cpp +++ b/util/test/demos/d3d11/d3d11_binding_hazards.cpp @@ -48,13 +48,13 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // so that running individually we get errors debugDevice = true; // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11ComputeShaderPtr cs = CreateCS(Compile(compute, "main", "cs_5_0")); diff --git a/util/test/demos/d3d11/d3d11_byte_address_buffers.cpp b/util/test/demos/d3d11/d3d11_byte_address_buffers.cpp index 1c66aaff4..ef790a0ac 100644 --- a/util/test/demos/d3d11/d3d11_byte_address_buffers.cpp +++ b/util/test/demos/d3d11/d3d11_byte_address_buffers.cpp @@ -48,7 +48,7 @@ void main() int main(int argc, char **argv) { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11ComputeShaderPtr cs = CreateCS(Compile(compute, "main", "cs_5_0")); diff --git a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp index 2811ca175..bd86c7948 100644 --- a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp @@ -236,10 +236,10 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_counter_query_pred.cpp b/util/test/demos/d3d11/d3d11_counter_query_pred.cpp index 05e1f9942..847c8794c 100644 --- a/util/test/demos/d3d11/d3d11_counter_query_pred.cpp +++ b/util/test/demos/d3d11/d3d11_counter_query_pred.cpp @@ -30,10 +30,10 @@ struct Counter_Query_Pred : D3D11GraphicsTest "Tests use of D3D11 counters, queries and predication. " "for any dead-simple tests that don't require any particular API use"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; DefaultA2V vertData[] = { diff --git a/util/test/demos/d3d11/d3d11_debug_shader.cpp b/util/test/demos/d3d11/d3d11_debug_shader.cpp index 088e41453..dc6c8c1b7 100644 --- a/util/test/demos/d3d11/d3d11_debug_shader.cpp +++ b/util/test/demos/d3d11/d3d11_debug_shader.cpp @@ -206,7 +206,7 @@ float4 main(v2f IN) : SV_Target0 int main(int argc, char **argv) { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_deferred_updatesubresource.cpp b/util/test/demos/d3d11/d3d11_deferred_updatesubresource.cpp index 43422f8ff..2cb43093b 100644 --- a/util/test/demos/d3d11/d3d11_deferred_updatesubresource.cpp +++ b/util/test/demos/d3d11/d3d11_deferred_updatesubresource.cpp @@ -49,10 +49,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11DeviceContextPtr defctx; diff --git a/util/test/demos/d3d11/d3d11_discard_view.cpp b/util/test/demos/d3d11/d3d11_discard_view.cpp index be37ec6c8..e5cee3f1c 100644 --- a/util/test/demos/d3d11/d3d11_discard_view.cpp +++ b/util/test/demos/d3d11/d3d11_discard_view.cpp @@ -42,12 +42,12 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { d3d11_1 = true; // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DFullscreenQuadVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_divergent_shader.cpp b/util/test/demos/d3d11/d3d11_divergent_shader.cpp index 75bfa6cfd..1eb9fe131 100644 --- a/util/test/demos/d3d11/d3d11_divergent_shader.cpp +++ b/util/test/demos/d3d11/d3d11_divergent_shader.cpp @@ -125,10 +125,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_draw_zoo.cpp b/util/test/demos/d3d11/d3d11_draw_zoo.cpp index f55b0a138..257f25e47 100644 --- a/util/test/demos/d3d11/d3d11_draw_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_draw_zoo.cpp @@ -81,10 +81,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_empty_compute_dispatch.cpp b/util/test/demos/d3d11/d3d11_empty_compute_dispatch.cpp index b0ddfa4fb..201eab128 100644 --- a/util/test/demos/d3d11/d3d11_empty_compute_dispatch.cpp +++ b/util/test/demos/d3d11/d3d11_empty_compute_dispatch.cpp @@ -40,10 +40,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11ComputeShaderPtr cs = CreateCS(Compile(compute, "main", "cs_5_0")); diff --git a/util/test/demos/d3d11/d3d11_empty_drawcall.cpp b/util/test/demos/d3d11/d3d11_empty_drawcall.cpp index 2c5b93354..0c9fe84b2 100644 --- a/util/test/demos/d3d11/d3d11_empty_drawcall.cpp +++ b/util/test/demos/d3d11/d3d11_empty_drawcall.cpp @@ -28,10 +28,10 @@ struct Empty_Drawcall : D3D11GraphicsTest { static constexpr const char *Description = "Test a drawcall of 0 size"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_empty_viewports.cpp b/util/test/demos/d3d11/d3d11_empty_viewports.cpp index 4975deedb..2596b9cdd 100644 --- a/util/test/demos/d3d11/d3d11_empty_viewports.cpp +++ b/util/test/demos/d3d11/d3d11_empty_viewports.cpp @@ -29,10 +29,10 @@ struct Empty_Viewports : D3D11GraphicsTest static constexpr const char *Description = "Test setting some viewports that are empty, but enabled"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_many_rtvs.cpp b/util/test/demos/d3d11/d3d11_many_rtvs.cpp index c4809d9b0..eb9120727 100644 --- a/util/test/demos/d3d11/d3d11_many_rtvs.cpp +++ b/util/test/demos/d3d11/d3d11_many_rtvs.cpp @@ -42,10 +42,10 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DFullscreenQuadVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_map_overrun.cpp b/util/test/demos/d3d11/d3d11_map_overrun.cpp index cc948821c..0079a042d 100644 --- a/util/test/demos/d3d11/d3d11_map_overrun.cpp +++ b/util/test/demos/d3d11/d3d11_map_overrun.cpp @@ -70,10 +70,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_midframe_create.cpp b/util/test/demos/d3d11/d3d11_midframe_create.cpp index 4c061c8d9..50559879a 100644 --- a/util/test/demos/d3d11/d3d11_midframe_create.cpp +++ b/util/test/demos/d3d11/d3d11_midframe_create.cpp @@ -49,10 +49,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_mip_gen_rt.cpp b/util/test/demos/d3d11/d3d11_mip_gen_rt.cpp index fb19cd1a0..60dd8afd8 100644 --- a/util/test/demos/d3d11/d3d11_mip_gen_rt.cpp +++ b/util/test/demos/d3d11/d3d11_mip_gen_rt.cpp @@ -72,10 +72,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_mip_rtv.cpp b/util/test/demos/d3d11/d3d11_mip_rtv.cpp index e034eeb71..437555de2 100644 --- a/util/test/demos/d3d11/d3d11_mip_rtv.cpp +++ b/util/test/demos/d3d11/d3d11_mip_rtv.cpp @@ -42,10 +42,10 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DFullscreenQuadVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_overdraw_stress.cpp b/util/test/demos/d3d11/d3d11_overdraw_stress.cpp index 70b8340b6..40bcfc7a0 100644 --- a/util/test/demos/d3d11/d3d11_overdraw_stress.cpp +++ b/util/test/demos/d3d11/d3d11_overdraw_stress.cpp @@ -28,10 +28,10 @@ struct Overdraw_Stress : D3D11GraphicsTest { static constexpr const char *Description = "Renders a lot of overlapping triangles"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_overlay_test.cpp b/util/test/demos/d3d11/d3d11_overlay_test.cpp index eda04da1f..3858e766f 100644 --- a/util/test/demos/d3d11/d3d11_overlay_test.cpp +++ b/util/test/demos/d3d11/d3d11_overlay_test.cpp @@ -29,10 +29,10 @@ struct D3D11_Overlay_Test : D3D11GraphicsTest static constexpr const char *Description = "Makes a couple of draws that show off all the overlays in some way"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/d3d11/d3d11_primitive_restart.cpp b/util/test/demos/d3d11/d3d11_primitive_restart.cpp index d3228ebec..b24eea4bb 100644 --- a/util/test/demos/d3d11/d3d11_primitive_restart.cpp +++ b/util/test/demos/d3d11/d3d11_primitive_restart.cpp @@ -29,10 +29,10 @@ struct Primitive_Restart : D3D11GraphicsTest static constexpr const char *Description = "Test of primitive restart in triangle strips with -1 index"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_refcount_check.cpp b/util/test/demos/d3d11/d3d11_refcount_check.cpp index 51b2d0416..852f94e74 100644 --- a/util/test/demos/d3d11/d3d11_refcount_check.cpp +++ b/util/test/demos/d3d11/d3d11_refcount_check.cpp @@ -30,10 +30,10 @@ struct Refcount_Check : D3D11GraphicsTest "Ensures that the device etc doesn't delete itself when there are still outstanding " "references, and also that it *does* delete itself when any cycle is detected."; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11Debug *dbg = NULL; diff --git a/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp b/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp index 1c871817a..21cb0756f 100644 --- a/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp +++ b/util/test/demos/d3d11/d3d11_resource_lifetimes.cpp @@ -59,10 +59,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/d3d11/d3d11_saturate.cpp b/util/test/demos/d3d11/d3d11_saturate.cpp index 5417e4595..bdf243790 100644 --- a/util/test/demos/d3d11/d3d11_saturate.cpp +++ b/util/test/demos/d3d11/d3d11_saturate.cpp @@ -57,10 +57,10 @@ void main(float4 pos : SV_Position, out float4 a : SV_Target0, out float4 b : SV )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DFullscreenQuadVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_simple_dispatch.cpp b/util/test/demos/d3d11/d3d11_simple_dispatch.cpp index 1f3fba48e..33b94dab7 100644 --- a/util/test/demos/d3d11/d3d11_simple_dispatch.cpp +++ b/util/test/demos/d3d11/d3d11_simple_dispatch.cpp @@ -46,10 +46,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3D11ComputeShaderPtr cs = CreateCS(Compile(compute, "main", "cs_5_0")); diff --git a/util/test/demos/d3d11/d3d11_simple_triangle.cpp b/util/test/demos/d3d11/d3d11_simple_triangle.cpp index 66a98ecf1..bd4e75430 100644 --- a/util/test/demos/d3d11/d3d11_simple_triangle.cpp +++ b/util/test/demos/d3d11/d3d11_simple_triangle.cpp @@ -30,10 +30,10 @@ struct D3D11_Simple_Triangle : D3D11GraphicsTest "Just draws a simple triangle, using normal pipeline. Basic test that can be used " "for any dead-simple tests that don't require any particular API use"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/d3d11/d3d11_streamout.cpp b/util/test/demos/d3d11/d3d11_streamout.cpp index 00ef190d1..8077e0648 100644 --- a/util/test/demos/d3d11/d3d11_streamout.cpp +++ b/util/test/demos/d3d11/d3d11_streamout.cpp @@ -28,10 +28,10 @@ struct StreamOut : D3D11GraphicsTest { static constexpr const char *Description = "Test using D3D11's streamout feature"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_stripped_shaders.cpp b/util/test/demos/d3d11/d3d11_stripped_shaders.cpp index 4fba8fc3c..27d8ff8e4 100644 --- a/util/test/demos/d3d11/d3d11_stripped_shaders.cpp +++ b/util/test/demos/d3d11/d3d11_stripped_shaders.cpp @@ -29,10 +29,10 @@ struct Stripped_Shaders : D3D11GraphicsTest static constexpr const char *Description = "Tests shaders with their debug/reflection info stripped out and stored in separate blobs"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblobUnstripped = NULL; diff --git a/util/test/demos/d3d11/d3d11_structured_buffer_misaligned_dirty.cpp b/util/test/demos/d3d11/d3d11_structured_buffer_misaligned_dirty.cpp index 53b3459fb..24e2c9ddd 100644 --- a/util/test/demos/d3d11/d3d11_structured_buffer_misaligned_dirty.cpp +++ b/util/test/demos/d3d11/d3d11_structured_buffer_misaligned_dirty.cpp @@ -51,10 +51,10 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; if(!opts.MapNoOverwriteOnDynamicBufferSRV) diff --git a/util/test/demos/d3d11/d3d11_structured_buffer_nested.cpp b/util/test/demos/d3d11/d3d11_structured_buffer_nested.cpp index 36f380609..ff14b11a4 100644 --- a/util/test/demos/d3d11/d3d11_structured_buffer_nested.cpp +++ b/util/test/demos/d3d11/d3d11_structured_buffer_nested.cpp @@ -75,10 +75,10 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_structured_buffer_read.cpp b/util/test/demos/d3d11/d3d11_structured_buffer_read.cpp index a16c72cad..a14e5b225 100644 --- a/util/test/demos/d3d11/d3d11_structured_buffer_read.cpp +++ b/util/test/demos/d3d11/d3d11_structured_buffer_read.cpp @@ -51,10 +51,10 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_test.cpp b/util/test/demos/d3d11/d3d11_test.cpp index 80822ec8e..feed07cf1 100644 --- a/util/test/demos/d3d11/d3d11_test.cpp +++ b/util/test/demos/d3d11/d3d11_test.cpp @@ -32,34 +32,63 @@ typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID, void **); -bool D3D11GraphicsTest::Init(int argc, char **argv) +namespace { - // parse parameters here to override parameters - GraphicsTest::Init(argc, argv); +HMODULE d3d11 = NULL; +HMODULE dxgi = NULL; +HMODULE d3dcompiler = NULL; +IDXGIFactoryPtr factory; +IDXGIAdapterPtr adapter; +bool warp = false; +}; - // D3D11 specific can go here - // ... +void D3D11GraphicsTest::Prepare(int argc, char **argv) +{ + GraphicsTest::Prepare(argc, argv); - HMODULE d3d11 = LoadLibraryA("d3d11.dll"); - HMODULE dxgi = LoadLibraryA("dxgi.dll"); - HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_46.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_45.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_44.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); + static bool prepared = false; - if(!d3d11 || !dxgi || !d3dcompiler) + if(!prepared) { - TEST_ERROR("Couldn't load D3D11"); - return false; + prepared = true; + + d3d11 = LoadLibraryA("d3d11.dll"); + dxgi = LoadLibraryA("dxgi.dll"); + d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_46.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_45.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_44.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); + + PFN_CREATE_DXGI_FACTORY createFactory = + (PFN_CREATE_DXGI_FACTORY)GetProcAddress(dxgi, "CreateDXGIFactory"); + + HRESULT hr = S_OK; + + hr = createFactory(__uuidof(IDXGIFactory), (void **)&factory); + + if(SUCCEEDED(hr)) + adapter = ChooseD3DAdapter(factory, argc, argv, warp); } - PFN_CREATE_DXGI_FACTORY createFactory = - (PFN_CREATE_DXGI_FACTORY)GetProcAddress(dxgi, "CreateDXGIFactory"); + if(!d3d11) + Avail = "d3d11.dll is not available"; + else if(!dxgi) + Avail = "dxgi.dll is not available"; + else if(!d3dcompiler) + Avail = "d3dcompiler_XX.dll is not available"; + else if(!factory) + Avail = "Couldn't create DXGI factory"; +} + +bool D3D11GraphicsTest::Init() +{ + if(!GraphicsTest::Init()) + return false; dyn_D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11, "D3D11CreateDevice"); dyn_D3D11CreateDeviceAndSwapChain = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress( @@ -75,83 +104,14 @@ bool D3D11GraphicsTest::Init(int argc, char **argv) if(d3d11_1) features[0] = D3D_FEATURE_LEVEL_11_1; + if(warp) + driver = D3D_DRIVER_TYPE_WARP; + + if(adapter) + driver = D3D_DRIVER_TYPE_UNKNOWN; + HRESULT hr = S_OK; - IDXGIFactoryPtr factory = NULL; - - hr = createFactory(__uuidof(IDXGIFactory), (void **)&factory); - - if(factory.GetInterfacePtr() == NULL || FAILED(hr)) - { - TEST_ERROR("CreateDXGIFactory failed: %x", hr); - return false; - } - - struct AdapterInfo - { - IDXGIAdapterPtr adapter; - DXGI_ADAPTER_DESC desc; - }; - - std::vector adapters; - - for(UINT i = 0; i < 10; i++) - { - IDXGIAdapterPtr a; - hr = factory->EnumAdapters(i, &a); - if(hr == S_OK && a) - { - DXGI_ADAPTER_DESC desc; - a->GetDesc(&desc); - adapters.push_back({a, desc}); - } - else - { - break; - } - } - - IDXGIAdapterPtr adapter = NULL; - - for(int i = 0; i < argc; i++) - { - if(!strcmp(argv[i], "--warp")) - { - driver = D3D_DRIVER_TYPE_WARP; - break; - } - if(!strcmp(argv[i], "--gpu") && i + 1 < argc) - { - std::string needle = strlower(argv[i + 1]); - - if(needle == "warp") - { - driver = D3D_DRIVER_TYPE_WARP; - break; - } - - const bool nv = (needle == "nv" || needle == "nvidia"); - const bool amd = (needle == "amd"); - const bool intel = (needle == "intel"); - - for(size_t a = 0; a < adapters.size(); a++) - { - std::string haystack = strlower(Wide2UTF8(adapters[a].desc.Description)); - - if(haystack.find(needle) != std::string::npos || (nv && adapters[a].desc.VendorId == 0x10DE) || - (amd && adapters[a].desc.VendorId == 0x1002) || - (intel && adapters[a].desc.VendorId == 0x8086)) - { - driver = D3D_DRIVER_TYPE_UNKNOWN; - adapter = adapters[a].adapter; - break; - } - } - - break; - } - } - UINT flags = createFlags | (debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0); if(headless) @@ -200,7 +160,7 @@ bool D3D11GraphicsTest::Init(int argc, char **argv) swapDesc.SampleDesc.Count = backbufferMSAA; swapDesc.SampleDesc.Quality = 0; swapDesc.OutputWindow = win->wnd; - swapDesc.Windowed = fullscreen ? FALSE : TRUE; + swapDesc.Windowed = TRUE; swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapDesc.Flags = 0; @@ -258,37 +218,6 @@ GraphicsWindow *D3D11GraphicsTest::MakeWindow(int width, int height, const char return new Win32Window(width, height, title); } -bool D3D11GraphicsTest::IsSupported() -{ - static bool checked = false, result = false; - - if(checked) - return result; - - checked = true; - - HMODULE d3d11 = LoadLibraryA("d3d11.dll"); - HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_46.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_45.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_44.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); - - if(d3d11) - FreeLibrary(d3d11); - if(d3dcompiler) - FreeLibrary(d3dcompiler); - - if(d3d11 && d3dcompiler) - result = true; - - return result; -} - void D3D11GraphicsTest::PostDeviceCreate() { { diff --git a/util/test/demos/d3d11/d3d11_test.h b/util/test/demos/d3d11/d3d11_test.h index aa87f043f..f412ec715 100644 --- a/util/test/demos/d3d11/d3d11_test.h +++ b/util/test/demos/d3d11/d3d11_test.h @@ -45,10 +45,10 @@ struct D3D11GraphicsTest : public GraphicsTest { static const TestAPI API = TestAPI::D3D11; - bool Init(int argc, char **argv); + void Prepare(int argc, char **argv); + bool Init(); void Shutdown(); GraphicsWindow *MakeWindow(int width, int height, const char *title); - bool IsSupported(); void PostDeviceCreate(); @@ -185,4 +185,7 @@ struct D3D11GraphicsTest : public GraphicsTest ID3D11DeviceContext1Ptr ctx1; ID3D11DeviceContext2Ptr ctx2; ID3DUserDefinedAnnotationPtr annot; + +private: + static bool prepared_d3d11; }; \ No newline at end of file diff --git a/util/test/demos/d3d11/d3d11_texture_3d.cpp b/util/test/demos/d3d11/d3d11_texture_3d.cpp index 37e171beb..bd09735ff 100644 --- a/util/test/demos/d3d11/d3d11_texture_3d.cpp +++ b/util/test/demos/d3d11/d3d11_texture_3d.cpp @@ -60,10 +60,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d11/d3d11_video_textures.cpp b/util/test/demos/d3d11/d3d11_video_textures.cpp index 66cde2584..a700f5af8 100644 --- a/util/test/demos/d3d11/d3d11_video_textures.cpp +++ b/util/test/demos/d3d11/d3d11_video_textures.cpp @@ -214,11 +214,8 @@ float4 main(v2f IN) : SV_Target0 return S_OK; } - int main(int argc, char **argv) + int main() { - // call this early to parse any data path parameters - GraphicsTest::Init(argc, argv); - // check for the existence of the test video std::string video_filename = GetDataPath("h264_yu420p_192x108_24fps.mp4"); @@ -273,7 +270,7 @@ float4 main(v2f IN) : SV_Target0 } // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; IMFMediaEnginePtr engine = NULL; diff --git a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp index d6a23d322..80fe4c68f 100644 --- a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp @@ -259,10 +259,10 @@ float4 main() : SV_Target0 float3_1 root_d; }; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_5_0"); diff --git a/util/test/demos/d3d12/d3d12_helpers.h b/util/test/demos/d3d12/d3d12_helpers.h index 6bf65f64a..751d64a80 100644 --- a/util/test/demos/d3d12/d3d12_helpers.h +++ b/util/test/demos/d3d12/d3d12_helpers.h @@ -27,16 +27,8 @@ #include #include "dx/d3d_helpers.h" #include "dx/official/d3d12.h" -#include "dx/official/dxgi1_4.h" - -#define COM_SMARTPTR(classname) _COM_SMARTPTR_TYPEDEF(classname, __uuidof(classname)) COM_SMARTPTR(ID3DBlob); -COM_SMARTPTR(IDXGISwapChain); -COM_SMARTPTR(IDXGISwapChain1); -COM_SMARTPTR(IDXGIFactory4); -COM_SMARTPTR(IDXGIAdapter); -COM_SMARTPTR(IDXGISurface); COM_SMARTPTR(ID3D12Debug); COM_SMARTPTR(ID3D12Debug1); diff --git a/util/test/demos/d3d12/d3d12_overlay_test.cpp b/util/test/demos/d3d12/d3d12_overlay_test.cpp index 32785f48f..cd7e722e7 100644 --- a/util/test/demos/d3d12/d3d12_overlay_test.cpp +++ b/util/test/demos/d3d12/d3d12_overlay_test.cpp @@ -29,10 +29,10 @@ struct D3D12_Overlay_Test : D3D12GraphicsTest static constexpr const char *Description = "Makes a couple of draws that show off all the overlays in some way"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/d3d12/d3d12_resource_lifetimes.cpp b/util/test/demos/d3d12/d3d12_resource_lifetimes.cpp index fef993c01..39b08895d 100644 --- a/util/test/demos/d3d12/d3d12_resource_lifetimes.cpp +++ b/util/test/demos/d3d12/d3d12_resource_lifetimes.cpp @@ -59,10 +59,10 @@ float4 main(v2f IN) : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/d3d12/d3d12_simple_triangle.cpp b/util/test/demos/d3d12/d3d12_simple_triangle.cpp index 195d11ca8..030ad0dd6 100644 --- a/util/test/demos/d3d12/d3d12_simple_triangle.cpp +++ b/util/test/demos/d3d12/d3d12_simple_triangle.cpp @@ -30,10 +30,10 @@ struct D3D12_Simple_Triangle : D3D12GraphicsTest "Just draws a simple triangle, using normal pipeline. Basic test that can be used " "for any dead-simple tests that don't require any particular API use"; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/d3d12/d3d12_test.cpp b/util/test/demos/d3d12/d3d12_test.cpp index 3a8ee6f94..e3616c3f3 100644 --- a/util/test/demos/d3d12/d3d12_test.cpp +++ b/util/test/demos/d3d12/d3d12_test.cpp @@ -32,34 +32,80 @@ typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY2)(UINT, REFIID, void **); -bool D3D12GraphicsTest::Init(int argc, char **argv) +namespace { - // parse parameters here to override parameters - GraphicsTest::Init(argc, argv); +HMODULE d3d12 = NULL; +HMODULE dxgi = NULL; +HMODULE d3dcompiler = NULL; +IDXGIFactory4Ptr factory; +IDXGIAdapterPtr adapter; +}; - // D3D12 specific can go here - // ... +void D3D12GraphicsTest::Prepare(int argc, char **argv) +{ + GraphicsTest::Prepare(argc, argv); - HMODULE d3d12 = LoadLibraryA("d3d12.dll"); - HMODULE dxgi = LoadLibraryA("dxgi.dll"); - HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_46.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_45.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_44.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); + static bool prepared = false; - if(!d3d12 || !dxgi || !d3dcompiler) + if(!prepared) { - TEST_ERROR("Couldn't load D3D12"); - return false; + prepared = true; + + d3d12 = LoadLibraryA("d3d12.dll"); + dxgi = LoadLibraryA("dxgi.dll"); + d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_46.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_45.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_44.dll"); + if(!d3dcompiler) + d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); + + if(d3d12) + { + PFN_CREATE_DXGI_FACTORY2 createFactory2 = + (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(dxgi, "CreateDXGIFactory2"); + + if(createFactory2) + { + HRESULT hr = createFactory2(debugDevice ? DXGI_CREATE_FACTORY_DEBUG : 0, + __uuidof(IDXGIFactory4), (void **)&factory); + + if(SUCCEEDED(hr)) + { + bool warp = false; + + adapter = ChooseD3DAdapter(factory, argc, argv, warp); + + if(warp) + factory->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&adapter); + } + } + } } - PFN_CREATE_DXGI_FACTORY2 createFactory2 = - (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(dxgi, "CreateDXGIFactory2"); + if(!d3d12) + Avail = "d3d12.dll is not available"; + else if(!dxgi) + Avail = "dxgi.dll is not available"; + else if(!d3dcompiler) + Avail = "d3dcompiler_XX.dll is not available"; + else if(!factory) + Avail = "Couldn't create DXGI factory"; + + m_Factory = factory; +} + +bool D3D12GraphicsTest::Init() +{ + // parse parameters here to override parameters + if(!GraphicsTest::Init()) + return false; + + // we can assume d3d12, dxgi and d3dcompiler are valid since we shouldn't be running the test if + // Prepare() failed dyn_D3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d12, "D3D12CreateDevice"); @@ -105,95 +151,9 @@ bool D3D12GraphicsTest::Init(int argc, char **argv) { HRESULT hr = S_OK; - hr = createFactory2(debugDevice ? DXGI_CREATE_FACTORY_DEBUG : 0, __uuidof(IDXGIFactory4), - (void **)&m_Factory); - - if(m_Factory.GetInterfacePtr() == NULL || FAILED(hr)) - { - TEST_ERROR("CreateDXGIFactory2 failed: %x", hr); - return false; - } - - struct AdapterInfo - { - IDXGIAdapterPtr adapter; - DXGI_ADAPTER_DESC desc; - }; - - std::vector adapters; - - for(UINT i = 0; i < 10; i++) - { - IDXGIAdapterPtr a; - hr = m_Factory->EnumAdapters(i, &a); - if(hr == S_OK && a) - { - DXGI_ADAPTER_DESC desc; - a->GetDesc(&desc); - adapters.push_back({a, desc}); - } - else - { - break; - } - } - - IDXGIAdapterPtr warp = NULL; - m_Factory->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&warp); - - IDXGIAdapterPtr adapter = NULL; - - for(int i = 0; i < argc; i++) - { - if(!strcmp(argv[i], "--warp")) - { - adapter = warp; - break; - } - if(!strcmp(argv[i], "--gpu") && i + 1 < argc) - { - std::string needle = strlower(argv[i + 1]); - - if(needle == "warp") - { - adapter = warp; - break; - } - - const bool nv = (needle == "nv" || needle == "nvidia"); - const bool amd = (needle == "amd"); - const bool intel = (needle == "intel"); - - for(size_t a = 0; a < adapters.size(); a++) - { - std::string haystack = strlower(Wide2UTF8(adapters[a].desc.Description)); - - if(haystack.find(needle) != std::string::npos || - (nv && adapters[a].desc.VendorId == 0x10DE) || - (amd && adapters[a].desc.VendorId == 0x1002) || - (intel && adapters[a].desc.VendorId == 0x8086)) - { - adapter = adapters[a].adapter; - break; - } - } - - break; - } - } - hr = dyn_D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void **)&dev); - // if it failed, try again on warp - if(FAILED(hr)) - { - adapter = warp; - if(adapter) - hr = dyn_D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), - (void **)&dev); - } - if(FAILED(hr)) { TEST_ERROR("D3D12CreateDevice failed: %x", hr); @@ -376,37 +336,6 @@ GraphicsWindow *D3D12GraphicsTest::MakeWindow(int width, int height, const char return new Win32Window(width, height, title); } -bool D3D12GraphicsTest::IsSupported() -{ - static bool checked = false, result = false; - - if(checked) - return result; - - checked = true; - - HMODULE d3d12 = LoadLibraryA("d3d12.dll"); - HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_46.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_45.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_44.dll"); - if(!d3dcompiler) - d3dcompiler = LoadLibraryA("d3dcompiler_43.dll"); - - if(d3d12) - FreeLibrary(d3d12); - if(d3dcompiler) - FreeLibrary(d3dcompiler); - - if(d3d12 && d3dcompiler) - result = true; - - return result; -} - void D3D12GraphicsTest::Shutdown() { GPUSync(); diff --git a/util/test/demos/d3d12/d3d12_test.h b/util/test/demos/d3d12/d3d12_test.h index 0d7cba3cc..69e195669 100644 --- a/util/test/demos/d3d12/d3d12_test.h +++ b/util/test/demos/d3d12/d3d12_test.h @@ -46,10 +46,10 @@ struct D3D12GraphicsTest : public GraphicsTest { static const TestAPI API = TestAPI::D3D12; - bool Init(int argc, char **argv); + void Prepare(int argc, char **argv); + bool Init(); void Shutdown(); GraphicsWindow *MakeWindow(int width, int height, const char *title); - bool IsSupported(); enum BufType { diff --git a/util/test/demos/d3d12/d3d12_video_textures.cpp b/util/test/demos/d3d12/d3d12_video_textures.cpp index 62b95628e..42ac4c796 100644 --- a/util/test/demos/d3d12/d3d12_video_textures.cpp +++ b/util/test/demos/d3d12/d3d12_video_textures.cpp @@ -170,10 +170,10 @@ float4 main(v2f IN) : SV_Target0 ID3D12ResourcePtr cb; }; - int main(int argc, char **argv) + int main() { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; ID3DBlobPtr vsblob = Compile(D3DDefaultVertex, "main", "vs_4_0"); diff --git a/util/test/demos/dx/d3d_helpers.cpp b/util/test/demos/dx/d3d_helpers.cpp index c5492895d..e7cb43b84 100644 --- a/util/test/demos/dx/d3d_helpers.cpp +++ b/util/test/demos/dx/d3d_helpers.cpp @@ -23,6 +23,8 @@ ******************************************************************************/ #include "d3d_helpers.h" +#include +#include "../test_common.h" std::string D3DFullscreenQuadVertex = R"EOSHADER( @@ -84,3 +86,75 @@ float4 main(v2f IN) : SV_Target0 } )EOSHADER"; + +IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv, bool &warp) +{ + struct AdapterInfo + { + IDXGIAdapterPtr adapter; + DXGI_ADAPTER_DESC desc; + }; + + std::vector adapters; + + HRESULT hr = S_OK; + + for(UINT i = 0; i < 10; i++) + { + IDXGIAdapterPtr a; + hr = factory->EnumAdapters(i, &a); + if(hr == S_OK && a) + { + DXGI_ADAPTER_DESC desc; + a->GetDesc(&desc); + adapters.push_back({a, desc}); + } + else + { + break; + } + } + + IDXGIAdapterPtr adapter = NULL; + + for(int i = 0; i < argc; i++) + { + if(!strcmp(argv[i], "--warp")) + { + warp = true; + adapter = NULL; + break; + } + if(!strcmp(argv[i], "--gpu") && i + 1 < argc) + { + std::string needle = strlower(argv[i + 1]); + + if(needle == "warp") + { + adapter = warp; + break; + } + + const bool nv = (needle == "nv" || needle == "nvidia"); + const bool amd = (needle == "amd"); + const bool intel = (needle == "intel"); + + for(size_t a = 0; a < adapters.size(); a++) + { + std::string haystack = strlower(Wide2UTF8(adapters[a].desc.Description)); + + if(haystack.find(needle) != std::string::npos || (nv && adapters[a].desc.VendorId == 0x10DE) || + (amd && adapters[a].desc.VendorId == 0x1002) || + (intel && adapters[a].desc.VendorId == 0x8086)) + { + adapter = adapters[a].adapter; + break; + } + } + + break; + } + } + + return adapter; +} diff --git a/util/test/demos/dx/d3d_helpers.h b/util/test/demos/dx/d3d_helpers.h index 12962a8bd..1b33fa546 100644 --- a/util/test/demos/dx/d3d_helpers.h +++ b/util/test/demos/dx/d3d_helpers.h @@ -24,8 +24,21 @@ #pragma once +#include #include +#include "dx/official/dxgi1_4.h" extern std::string D3DFullscreenQuadVertex; extern std::string D3DDefaultVertex; -extern std::string D3DDefaultPixel; \ No newline at end of file +extern std::string D3DDefaultPixel; + +#define COM_SMARTPTR(classname) _COM_SMARTPTR_TYPEDEF(classname, __uuidof(classname)) + +COM_SMARTPTR(IDXGISwapChain); +COM_SMARTPTR(IDXGISwapChain1); +COM_SMARTPTR(IDXGIFactory); +COM_SMARTPTR(IDXGIFactory4); +COM_SMARTPTR(IDXGIAdapter); +COM_SMARTPTR(IDXGISurface); + +IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv, bool &warp); \ No newline at end of file diff --git a/util/test/demos/gl/gl_buffer_updates.cpp b/util/test/demos/gl/gl_buffer_updates.cpp index e245d0264..9315a9ed8 100644 --- a/util/test/demos/gl/gl_buffer_updates.cpp +++ b/util/test/demos/gl/gl_buffer_updates.cpp @@ -60,10 +60,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_cbuffer_zoo.cpp b/util/test/demos/gl/gl_cbuffer_zoo.cpp index 0986156ea..2d8b7144d 100644 --- a/util/test/demos/gl/gl_cbuffer_zoo.cpp +++ b/util/test/demos/gl/gl_cbuffer_zoo.cpp @@ -311,10 +311,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_depthstencil_fbo.cpp b/util/test/demos/gl/gl_depthstencil_fbo.cpp index ab56607c7..e578aedb0 100644 --- a/util/test/demos/gl/gl_depthstencil_fbo.cpp +++ b/util/test/demos/gl/gl_depthstencil_fbo.cpp @@ -101,10 +101,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_dx_interop.cpp b/util/test/demos/gl/gl_dx_interop.cpp index a1441d741..c77d450d6 100644 --- a/util/test/demos/gl/gl_dx_interop.cpp +++ b/util/test/demos/gl/gl_dx_interop.cpp @@ -126,13 +126,20 @@ void main() )EOSHADER"; - int main(int argc, char **argv) - { - D3D11GraphicsTest d3d; + D3D11GraphicsTest d3d; + void Prepare(int argc, char **argv) + { d3d.headless = true; - if(!d3d.Init(argc, argv)) + d3d.Prepare(argc, argv); + + OpenGLGraphicsTest::Prepare(argc, argv); + } + + int main() + { + if(!d3d.Init()) return 4; ID3DBlobPtr vsblob = d3d.Compile(dxcommon + dxvertex, "main", "vs_5_0"); @@ -154,7 +161,7 @@ void main() d3d.ctx->ClearRenderTargetView(rtv2, black); // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; DefaultA2V quad[] = { diff --git a/util/test/demos/gl/gl_entry_points.cpp b/util/test/demos/gl/gl_entry_points.cpp index bdc2afc16..c7460f519 100644 --- a/util/test/demos/gl/gl_entry_points.cpp +++ b/util/test/demos/gl/gl_entry_points.cpp @@ -59,10 +59,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_large_bcn_arrays.cpp b/util/test/demos/gl/gl_large_bcn_arrays.cpp index 89070610b..3a3e30c0b 100644 --- a/util/test/demos/gl/gl_large_bcn_arrays.cpp +++ b/util/test/demos/gl/gl_large_bcn_arrays.cpp @@ -73,10 +73,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_map_overrun.cpp b/util/test/demos/gl/gl_map_overrun.cpp index a9dd29eae..e70499d96 100644 --- a/util/test/demos/gl/gl_map_overrun.cpp +++ b/util/test/demos/gl/gl_map_overrun.cpp @@ -72,10 +72,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_midframe_context_create.cpp b/util/test/demos/gl/gl_midframe_context_create.cpp index eb488e77f..8b22e3396 100644 --- a/util/test/demos/gl/gl_midframe_context_create.cpp +++ b/util/test/demos/gl/gl_midframe_context_create.cpp @@ -73,12 +73,12 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { coreProfile = false; // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_mip_gen_rt.cpp b/util/test/demos/gl/gl_mip_gen_rt.cpp index 2dbfd78ba..347b5a836 100644 --- a/util/test/demos/gl/gl_mip_gen_rt.cpp +++ b/util/test/demos/gl/gl_mip_gen_rt.cpp @@ -61,10 +61,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_multi_window.cpp b/util/test/demos/gl/gl_multi_window.cpp index 31e40b915..2e5a5692c 100644 --- a/util/test/demos/gl/gl_multi_window.cpp +++ b/util/test/demos/gl/gl_multi_window.cpp @@ -73,12 +73,12 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { debugDevice = true; // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_overlay_test.cpp b/util/test/demos/gl/gl_overlay_test.cpp index 17c1b9c0c..c5e447f34 100644 --- a/util/test/demos/gl/gl_overlay_test.cpp +++ b/util/test/demos/gl/gl_overlay_test.cpp @@ -73,10 +73,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_resource_lifetimes.cpp b/util/test/demos/gl/gl_resource_lifetimes.cpp index c8f8acb7f..848facb30 100644 --- a/util/test/demos/gl/gl_resource_lifetimes.cpp +++ b/util/test/demos/gl/gl_resource_lifetimes.cpp @@ -114,10 +114,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vb = MakeBuffer(); diff --git a/util/test/demos/gl/gl_runtime_bind_prog_to_pipe.cpp b/util/test/demos/gl/gl_runtime_bind_prog_to_pipe.cpp index d1a766316..91d5ea088 100644 --- a/util/test/demos/gl/gl_runtime_bind_prog_to_pipe.cpp +++ b/util/test/demos/gl/gl_runtime_bind_prog_to_pipe.cpp @@ -84,10 +84,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_separable_geometry_shader.cpp b/util/test/demos/gl/gl_separable_geometry_shader.cpp index ec5a5dcc7..f19d0d0b5 100644 --- a/util/test/demos/gl/gl_separable_geometry_shader.cpp +++ b/util/test/demos/gl/gl_separable_geometry_shader.cpp @@ -133,10 +133,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_simple_triangle.cpp b/util/test/demos/gl/gl_simple_triangle.cpp index 928295e42..1fa916536 100644 --- a/util/test/demos/gl/gl_simple_triangle.cpp +++ b/util/test/demos/gl/gl_simple_triangle.cpp @@ -74,10 +74,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_spirv_shader.cpp b/util/test/demos/gl/gl_spirv_shader.cpp index 9b2aa22b5..15012d6ce 100644 --- a/util/test/demos/gl/gl_spirv_shader.cpp +++ b/util/test/demos/gl/gl_spirv_shader.cpp @@ -72,12 +72,12 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { debugDevice = true; // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; if(!SpvCompilationSupported()) diff --git a/util/test/demos/gl/gl_structured_buffer_nested.cpp b/util/test/demos/gl/gl_structured_buffer_nested.cpp index 6da9feb11..9db0f938e 100644 --- a/util/test/demos/gl/gl_structured_buffer_nested.cpp +++ b/util/test/demos/gl/gl_structured_buffer_nested.cpp @@ -130,10 +130,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_test.cpp b/util/test/demos/gl/gl_test.cpp index 802a74399..b36993d0c 100644 --- a/util/test/demos/gl/gl_test.cpp +++ b/util/test/demos/gl/gl_test.cpp @@ -45,6 +45,9 @@ void OpenGLGraphicsTest::PostInit() glDebugMessageCallback(&debugCallback, NULL); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } + + TEST_LOG("Running GL test on %s / %s / %s", glGetString(GL_VENDOR), glGetString(GL_RENDERER), + glGetString(GL_VERSION)); } void OpenGLGraphicsTest::Shutdown() diff --git a/util/test/demos/gl/gl_test.h b/util/test/demos/gl/gl_test.h index 72c75af73..8c392d680 100644 --- a/util/test/demos/gl/gl_test.h +++ b/util/test/demos/gl/gl_test.h @@ -34,9 +34,9 @@ struct OpenGLGraphicsTest : public GraphicsTest { static const TestAPI API = TestAPI::OpenGL; - bool Init(int argc, char **argv); + void Prepare(int argc, char **argv); + bool Init(); void Shutdown(); - bool IsSupported(); GraphicsWindow *MakeWindow(int width, int height, const char *title); void *MakeContext(GraphicsWindow *win, void *share); void DestroyContext(void *ctx); diff --git a/util/test/demos/gl/gl_test_linux.cpp b/util/test/demos/gl/gl_test_linux.cpp index f67194b5a..10d9d7657 100644 --- a/util/test/demos/gl/gl_test_linux.cpp +++ b/util/test/demos/gl/gl_test_linux.cpp @@ -29,10 +29,28 @@ #include "../linux/linux_window.h" -bool OpenGLGraphicsTest::Init(int argc, char **argv) +void OpenGLGraphicsTest::Prepare(int argc, char **argv) { - // parse parameters here to override parameters - GraphicsTest::Init(argc, argv); + GraphicsTest::Prepare(argc, argv); + + static bool prepared = false; + static void *libGL = NULL; + + if(!prepared) + { + prepared = true; + + libGL = dlopen("libGL.so", RTLD_GLOBAL | RTLD_NOW); + } + + if(!libGL) + Avail = "libGL.so is not available"; +} + +bool OpenGLGraphicsTest::Init() +{ + if(!GraphicsTest::Init()) + return false; X11Window::Init(); @@ -65,23 +83,6 @@ bool OpenGLGraphicsTest::Init(int argc, char **argv) return true; } -bool OpenGLGraphicsTest::IsSupported() -{ - static bool checked = false, result = false; - - if(checked) - return result; - - checked = true; - - void *GL = dlopen("libGL.so", RTLD_GLOBAL | RTLD_NOW); - - if(GL) - result = true; - - return result; -} - GraphicsWindow *OpenGLGraphicsTest::MakeWindow(int width, int height, const char *title) { return new X11Window(width, height, title); diff --git a/util/test/demos/gl/gl_test_win32.cpp b/util/test/demos/gl/gl_test_win32.cpp index b1a0123b5..b13f39897 100644 --- a/util/test/demos/gl/gl_test_win32.cpp +++ b/util/test/demos/gl/gl_test_win32.cpp @@ -32,24 +32,41 @@ typedef BOOL(WINAPI *PFN_wglMakeCurrent)(HDC, HGLRC); typedef HGLRC(WINAPI *PFN_wglCreateContext)(HDC); typedef BOOL(WINAPI *PFN_wglDeleteContext)(HGLRC); -bool OpenGLGraphicsTest::Init(int argc, char **argv) +namespace { - // parse parameters here to override parameters - GraphicsTest::Init(argc, argv); +PFN_wglMakeCurrent makeCurrent = NULL; +PFN_wglCreateContext createContext = NULL; +PFN_wglDeleteContext deleteContext = NULL; +}; - HMODULE opengl = LoadLibraryA("opengl32.dll"); +void OpenGLGraphicsTest::Prepare(int argc, char **argv) +{ + GraphicsTest::Prepare(argc, argv); - if(!opengl) + static bool prepared = false; + + if(!prepared) { - TEST_ERROR("Couldn't load opengl32"); - return false; + prepared = true; + + HMODULE opengl = LoadLibraryA("opengl32.dll"); + + if(opengl) + { + makeCurrent = (PFN_wglMakeCurrent)GetProcAddress(opengl, "wglMakeCurrent"); + createContext = (PFN_wglCreateContext)GetProcAddress(opengl, "wglCreateContext"); + deleteContext = (PFN_wglDeleteContext)GetProcAddress(opengl, "wglDeleteContext"); + } } - PFN_wglMakeCurrent makeCurrent = (PFN_wglMakeCurrent)GetProcAddress(opengl, "wglMakeCurrent"); - PFN_wglCreateContext makeContext = - (PFN_wglCreateContext)GetProcAddress(opengl, "wglCreateContext"); - PFN_wglDeleteContext deleteContext = - (PFN_wglDeleteContext)GetProcAddress(opengl, "wglDeleteContext"); + if(!makeCurrent) + Avail = "opengl32.dll is not available"; +} + +bool OpenGLGraphicsTest::Init() +{ + if(!GraphicsTest::Init()) + return false; mainWindow = new Win32Window(screenWidth, screenHeight, screenTitle); @@ -76,7 +93,7 @@ bool OpenGLGraphicsTest::Init(int argc, char **argv) int pf = ::ChoosePixelFormat(dc, &pfd); ::SetPixelFormat(dc, pf, &pfd); - HGLRC rc = makeContext(dc); + HGLRC rc = createContext(dc); makeCurrent(dc, rc); @@ -110,27 +127,6 @@ bool OpenGLGraphicsTest::Init(int argc, char **argv) return true; } -bool OpenGLGraphicsTest::IsSupported() -{ - static bool checked = false, result = false; - - if(checked) - return result; - - checked = true; - - HMODULE opengl = LoadLibraryA("opengl32.dll"); - - if(opengl) - { - result = true; - - FreeLibrary(opengl); - } - - return result; -} - GraphicsWindow *OpenGLGraphicsTest::MakeWindow(int width, int height, const char *title) { if(!GLAD_WGL_ARB_pixel_format) @@ -255,9 +251,6 @@ void OpenGLGraphicsTest::DestroyContext(void *ctx) if(ctx == NULL) return; - PFN_wglDeleteContext deleteContext = - (PFN_wglDeleteContext)GetProcAddress(GetModuleHandleA("opengl32.dll"), "wglDeleteContext"); - deleteContext((HGLRC)ctx); } @@ -267,9 +260,6 @@ void OpenGLGraphicsTest::ActivateContext(GraphicsWindow *win, void *ctx) HDC dc = GetDC(win32win->wnd); - PFN_wglMakeCurrent makeCurrent = - (PFN_wglMakeCurrent)GetProcAddress(GetModuleHandleA("opengl32.dll"), "wglMakeCurrent"); - makeCurrent(dc, (HGLRC)ctx); ReleaseDC(win32win->wnd, dc); diff --git a/util/test/demos/gl/gl_unsized_ms_fbo_attachment.cpp b/util/test/demos/gl/gl_unsized_ms_fbo_attachment.cpp index 015515342..457b47131 100644 --- a/util/test/demos/gl/gl_unsized_ms_fbo_attachment.cpp +++ b/util/test/demos/gl/gl_unsized_ms_fbo_attachment.cpp @@ -73,10 +73,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; GLuint vao = MakeVAO(); diff --git a/util/test/demos/gl/gl_vao_0.cpp b/util/test/demos/gl/gl_vao_0.cpp index 097b54d15..20840b668 100644 --- a/util/test/demos/gl/gl_vao_0.cpp +++ b/util/test/demos/gl/gl_vao_0.cpp @@ -72,12 +72,12 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { coreProfile = false; // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; uint32_t idxs[3] = {0, 1, 2}; diff --git a/util/test/demos/linux/linux_platform.h b/util/test/demos/linux/linux_platform.h index cc2bc55f7..7566f08e4 100644 --- a/util/test/demos/linux/linux_platform.h +++ b/util/test/demos/linux/linux_platform.h @@ -24,6 +24,7 @@ #pragma once +#include #include #include diff --git a/util/test/demos/main.cpp b/util/test/demos/main.cpp index e6edbfd27..6a24b3a1d 100644 --- a/util/test/demos/main.cpp +++ b/util/test/demos/main.cpp @@ -256,6 +256,11 @@ Usage: %s Test_Name [test_options] --list-available Lists the available test names only, one per line. --validate --debug Run the demo with API validation enabled. + --gpu [identifier] Try to select the corresponding GPU where available and possible + through the API. Identifier is e.g. 'nv' or 'amd', or can be '1080' + --warp On D3D APIs, use the software rasterizer. + --width / -w Specify the window width. + --height / -h Specify the window height. --frames --max-frames --frame-count Only run the demo for this number of frames @@ -274,9 +279,26 @@ Usage: %s Test_Name [test_options] { check_tests(argc, argv); + TestAPI prev = TestAPI::Count; + for(const TestMetadata &test : tests) - printf("%s (%s %s) - %s\n", test.Name, test.APIName(), - test.IsAvailable() ? "Available" : test.AvailMessage(), test.Description); + { + if(test.API != prev) + { + if(prev != TestAPI::Count) + printf("\n\n"); + printf("======== %s tests ========\n\n", test.APIName()); + } + + prev = test.API; + + printf("%s: %s", test.Name, test.IsAvailable() ? "Available" : "Unavailable"); + + if(!test.IsAvailable()) + printf(" because %s", test.AvailMessage()); + + printf("\n\t%s\n\n", test.Description); + } fflush(stdout); return 1; @@ -286,12 +308,13 @@ Usage: %s Test_Name [test_options] { check_tests(argc, argv); + // output TSV + printf("Name\tAvailable\tAvailMessage\n"); + for(const TestMetadata &test : tests) { - if(!test.IsAvailable()) - continue; - - printf("%s\n", test.Name); + printf("%s\t%s\t%s\n", test.Name, test.IsAvailable() ? "True" : "False", + test.IsAvailable() ? "Available" : test.AvailMessage()); } fflush(stdout); @@ -375,6 +398,9 @@ Usage: %s Test_Name [test_options] for(int i = 0; i < (int)tests.size(); i++) { + if(!tests[i].IsAvailable()) + continue; + std::string name = tests[i].QualifiedName(); std::string lower_name = strlower(name); @@ -473,7 +499,14 @@ Usage: %s Test_Name [test_options] { TEST_LOG("\n\n======\nRunning %s\n\n", test.Name); test.test->Prepare(argc, argv); - int ret = test.test->main(argc, argv); + + if(!test.IsAvailable()) + { + TEST_ERROR("%s is not available: %s", test.Name, test.test->Avail.c_str()); + return 5; + } + + int ret = test.test->main(); test.test->Shutdown(); return ret; } diff --git a/util/test/demos/test_common.cpp b/util/test/demos/test_common.cpp index 5b8874b8c..f0cc623c0 100644 --- a/util/test/demos/test_common.cpp +++ b/util/test/demos/test_common.cpp @@ -189,6 +189,11 @@ void LoadXPM(const char **XPM, Texture &tex) static shaderc_compiler_t shaderc = NULL; +bool InternalSpvCompiler() +{ + return bool(USE_LINKED_SHADERC); +} + bool SpvCompilationSupported() { if(shaderc) @@ -201,7 +206,7 @@ bool SpvCompilationSupported() if(shaderc) return true; - FILE *pipe = popen("glslc" EXECUTABLE_SUFFIX " --help", "r"); + FILE *pipe = popen("glslc" EXECUTABLE_SUFFIX " --help 2>&1", "r"); if(!pipe) return false; @@ -349,9 +354,21 @@ std::vector CompileShaderToSpv(const std::string &source_text, SPIRVTa return ret; } -bool GraphicsTest::Init(int argc, char **argv) +int GraphicsTest::maxFrameCount = -1; +std::string GraphicsTest::dataRoot; +int GraphicsTest::screenWidth = 400; +int GraphicsTest::screenHeight = 300; +bool GraphicsTest::debugDevice = false; + +void GraphicsTest::Prepare(int argc, char **argv) { - srand(0U); + static bool prepared = false; + + // nothing to do per-test if we've already prepared + if(prepared) + return; + + prepared = true; dataRoot = GetEnvVar("RENDERDOC_DEMOS_DATA"); @@ -372,6 +389,26 @@ bool GraphicsTest::Init(int argc, char **argv) maxFrameCount = atoi(argv[i + 1]); } + if(i + 1 < argc && (!strcmp(argv[i], "--width") || !strcmp(argv[i], "-w"))) + { + screenWidth = atoi(argv[i + 1]); + + if(screenWidth < 1) + screenWidth = 1; + if(screenWidth > 7680) + screenWidth = 7680; + } + + if(i + 1 < argc && (!strcmp(argv[i], "--height") || !strcmp(argv[i], "-h"))) + { + screenHeight = atoi(argv[i + 1]); + + if(screenHeight < 1) + screenHeight = 1; + if(screenHeight > 4320) + screenHeight = 4320; + } + if(i + 1 < argc && !strcmp(argv[i], "--data")) { dataRoot = argv[i + 1]; @@ -380,29 +417,32 @@ bool GraphicsTest::Init(int argc, char **argv) dataRoot += "/"; } } +} + +bool GraphicsTest::Init() +{ + srand(0U); + + pRENDERDOC_GetAPI RENDERDOC_GetAPI = NULL; #if defined(WIN32) - HMODULE mod = GetModuleHandleA("renderdoc.dll"); if(mod) - { - pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI"); + RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI"); +#else + void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD); + if(mod) + RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI"); +#endif - int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_0, (void **)&rdoc); + if(RENDERDOC_GetAPI) + { + int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_0_0, (void **)&rdoc); if(ret != 1) rdoc = NULL; - - ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_0_0, (void **)&rdoc100); - - if(ret != 1) - rdoc100 = NULL; } -#else - -#endif - return true; } diff --git a/util/test/demos/test_common.h b/util/test/demos/test_common.h index 533400ded..c5d11aa5e 100644 --- a/util/test/demos/test_common.h +++ b/util/test/demos/test_common.h @@ -61,6 +61,7 @@ enum class ShaderStage comp }; +bool InternalSpvCompiler(); bool SpvCompilationSupported(); std::vector CompileShaderToSpv(const std::string &source_text, SPIRVTarget target, ShaderLang lang, ShaderStage stage, const char *entry_point); @@ -152,10 +153,9 @@ struct GraphicsTest { virtual ~GraphicsTest() {} virtual GraphicsWindow *MakeWindow(int width, int height, const char *title) { return NULL; } - virtual int main(int argc, char **argv) { return 9; } - virtual bool IsSupported() { return false; } - virtual void Prepare(int argc, char **argv) {} - virtual bool Init(int argc, char **argv); + virtual int main() { return 9; } + virtual void Prepare(int argc, char **argv); + virtual bool Init(); virtual void Shutdown(); std::string Avail; @@ -164,20 +164,20 @@ struct GraphicsTest bool FrameLimit(); - std::string dataRoot; - int curFrame = 0; - int maxFrameCount = -1; - int screenWidth = 400; - int screenHeight = 300; const char *screenTitle = "RenderDoc test program"; - bool fullscreen = false; - bool debugDevice = false; + bool headless = false; - RENDERDOC_API_1_0_0 *rdoc100 = NULL; - RENDERDOC_API_1_4_0 *rdoc = NULL; + RENDERDOC_API_1_0_0 *rdoc = NULL; + + // shared parameters + static int maxFrameCount; + static std::string dataRoot; + static int screenWidth; + static int screenHeight; + static bool debugDevice; }; enum class TestAPI @@ -248,8 +248,7 @@ void RegisterTest(TestMetadata test); test.Name = #TestName; \ test.Description = TestName::Description; \ test.test = &m_impl; \ - if(m_impl.IsSupported()) \ - RegisterTest(test); \ + RegisterTest(test); \ } \ }; \ }; \ diff --git a/util/test/demos/vk/vk_adv_cbuffer_zoo.cpp b/util/test/demos/vk/vk_adv_cbuffer_zoo.cpp index bed7e4a11..655f6e8f3 100644 --- a/util/test/demos/vk/vk_adv_cbuffer_zoo.cpp +++ b/util/test/demos/vk/vk_adv_cbuffer_zoo.cpp @@ -225,52 +225,55 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { - instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); devExts.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); devExts.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME); devExts.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME); devExts.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME); - VkPhysicalDevice16BitStorageFeaturesKHR _16bitFeatures = { + features.shaderFloat64 = true; + features.shaderInt64 = true; + + VulkanGraphicsTest::Prepare(argc, argv); + + if(!Avail.empty()) + return; + + static VkPhysicalDevice16BitStorageFeaturesKHR _16bitFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, }; - VkPhysicalDevice16BitStorageFeaturesKHR _8bitFeatures = { + static VkPhysicalDevice16BitStorageFeaturesKHR _8bitFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, }; - VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalarFeatures = { + static VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalarFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT, }; - _16bitFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE; - _8bitFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE; - scalarFeatures.scalarBlockLayout = VK_TRUE; + getPhysFeatures2(&_16bitFeatures); + getPhysFeatures2(&_8bitFeatures); + getPhysFeatures2(&scalarFeatures); + + if(!scalarFeatures.scalarBlockLayout) + Avail = "Scalar block layout feature 'scalarBlockLayout' not available"; + else if(!_8bitFeatures.uniformAndStorageBuffer16BitAccess) + Avail = "8-bit storage feature 'uniformAndStorageBuffer16BitAccess' not available"; + else if(!_16bitFeatures.uniformAndStorageBuffer16BitAccess) + Avail = "16-bit storage feature 'uniformAndStorageBuffer16BitAccess' not available"; devInfoNext = &_8bitFeatures; _8bitFeatures.pNext = &_16bitFeatures; _16bitFeatures.pNext = &scalarFeatures; + } - features.shaderFloat64 = true; - features.shaderInt64 = true; - + int main() + { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; - _16bitFeatures.uniformAndStorageBuffer16BitAccess = VK_FALSE; - _8bitFeatures.uniformAndStorageBuffer16BitAccess = VK_FALSE; - - vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(&_16bitFeatures)); - vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(&_8bitFeatures)); - - // a bit late, but... - TEST_ASSERT(_16bitFeatures.uniformAndStorageBuffer16BitAccess && - _8bitFeatures.uniformAndStorageBuffer16BitAccess, - "8-bit or 16-bit uniform storage not available"); - VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT}, })); diff --git a/util/test/demos/vk/vk_awkward_triangle.cpp b/util/test/demos/vk/vk_awkward_triangle.cpp index 88354e6ca..081aeb54c 100644 --- a/util/test/demos/vk/vk_awkward_triangle.cpp +++ b/util/test/demos/vk/vk_awkward_triangle.cpp @@ -81,12 +81,12 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { features.shaderFloat64 = true; // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo()); diff --git a/util/test/demos/vk/vk_buffer_address.cpp b/util/test/demos/vk/vk_buffer_address.cpp index 04d5773c1..d39995642 100644 --- a/util/test/demos/vk/vk_buffer_address.cpp +++ b/util/test/demos/vk/vk_buffer_address.cpp @@ -114,22 +114,32 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { - VkPhysicalDeviceBufferAddressFeaturesEXT bufaddrFeatures = { - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT, - }; - - bufaddrFeatures.bufferDeviceAddress = VK_TRUE; - - devInfoNext = &bufaddrFeatures; - - instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); devExts.push_back(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); devExts.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + VulkanGraphicsTest::Prepare(argc, argv); + + if(!Avail.empty()) + return; + + static VkPhysicalDeviceBufferAddressFeaturesEXT bufaddrFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT, + }; + + getPhysFeatures2(&bufaddrFeatures); + + if(!bufaddrFeatures.bufferDeviceAddress) + Avail = "Buffer device address feature 'bufferDeviceAddress' not available"; + + devInfoNext = &bufaddrFeatures; + } + + int main() + { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPipelineLayout layout = createPipelineLayout( diff --git a/util/test/demos/vk/vk_cbuffer_zoo.cpp b/util/test/demos/vk/vk_cbuffer_zoo.cpp index 82867c92e..04116df72 100644 --- a/util/test/demos/vk/vk_cbuffer_zoo.cpp +++ b/util/test/demos/vk/vk_cbuffer_zoo.cpp @@ -482,13 +482,17 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { - // needed for HLSL packing devExts.push_back(VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME); + VulkanGraphicsTest::Prepare(argc, argv); + } + + int main() + { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ diff --git a/util/test/demos/vk/vk_descriptor_index.cpp b/util/test/demos/vk/vk_descriptor_index.cpp index 480b5ba06..a88d4bbfb 100644 --- a/util/test/demos/vk/vk_descriptor_index.cpp +++ b/util/test/demos/vk/vk_descriptor_index.cpp @@ -214,28 +214,41 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { devExts.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); // dependencies of VK_EXT_descriptor_indexing devExts.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); features.fragmentStoresAndAtomics = VK_TRUE; - VkPhysicalDeviceDescriptorIndexingFeaturesEXT descIndexing = { + VulkanGraphicsTest::Prepare(argc, argv); + + if(!Avail.empty()) + return; + + static VkPhysicalDeviceDescriptorIndexingFeaturesEXT descIndexing = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, }; - descIndexing.descriptorBindingPartiallyBound = VK_TRUE; - descIndexing.runtimeDescriptorArray = VK_TRUE; - descIndexing.shaderSampledImageArrayNonUniformIndexing = VK_TRUE; + getPhysFeatures2(&descIndexing); + + if(!descIndexing.descriptorBindingPartiallyBound) + Avail = "Descriptor indexing feature 'descriptorBindingPartiallyBound' not available"; + else if(!descIndexing.runtimeDescriptorArray) + Avail = "Descriptor indexing feature 'runtimeDescriptorArray' not available"; + else if(!descIndexing.shaderSampledImageArrayNonUniformIndexing) + Avail = + "Descriptor indexing feature 'shaderSampledImageArrayNonUniformIndexing' not available"; devInfoNext = &descIndexing; + } + int main() + { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkDescriptorSetLayoutBindingFlagsCreateInfoEXT descFlags = { diff --git a/util/test/demos/vk/vk_discard_rects.cpp b/util/test/demos/vk/vk_discard_rects.cpp index b8f8495bf..9ea2f8332 100644 --- a/util/test/demos/vk/vk_discard_rects.cpp +++ b/util/test/demos/vk/vk_discard_rects.cpp @@ -74,13 +74,17 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { - instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); devExts.push_back(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME); + VulkanGraphicsTest::Prepare(argc, argv); + } + + int main() + { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPhysicalDeviceDiscardRectanglePropertiesEXT discardProps = { diff --git a/util/test/demos/vk/vk_draw_zoo.cpp b/util/test/demos/vk/vk_draw_zoo.cpp index e5d814ec8..d5112b939 100644 --- a/util/test/demos/vk/vk_draw_zoo.cpp +++ b/util/test/demos/vk/vk_draw_zoo.cpp @@ -81,10 +81,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo()); diff --git a/util/test/demos/vk/vk_indirect.cpp b/util/test/demos/vk/vk_indirect.cpp index c79c4ea86..c7472f42a 100644 --- a/util/test/demos/vk/vk_indirect.cpp +++ b/util/test/demos/vk/vk_indirect.cpp @@ -143,13 +143,19 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { - optDevExts.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); features.multiDrawIndirect = VK_TRUE; + VulkanGraphicsTest::Prepare(argc, argv); + } + + int main() + { + optDevExts.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); + // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; bool KHR_draw_indirect_count = diff --git a/util/test/demos/vk/vk_overlay_test.cpp b/util/test/demos/vk/vk_overlay_test.cpp index 447e31015..3aad98e6f 100644 --- a/util/test/demos/vk/vk_overlay_test.cpp +++ b/util/test/demos/vk/vk_overlay_test.cpp @@ -73,10 +73,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo()); diff --git a/util/test/demos/vk/vk_resource_lifetimes.cpp b/util/test/demos/vk/vk_resource_lifetimes.cpp index 1aa013822..1f2cc62b6 100644 --- a/util/test/demos/vk/vk_resource_lifetimes.cpp +++ b/util/test/demos/vk/vk_resource_lifetimes.cpp @@ -89,10 +89,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ diff --git a/util/test/demos/vk/vk_sample_locations.cpp b/util/test/demos/vk/vk_sample_locations.cpp index 5bc00877b..af37deec2 100644 --- a/util/test/demos/vk/vk_sample_locations.cpp +++ b/util/test/demos/vk/vk_sample_locations.cpp @@ -73,13 +73,17 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { - instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); devExts.push_back(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME); + VulkanGraphicsTest::Prepare(argc, argv); + } + + int main() + { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPhysicalDeviceSampleLocationsPropertiesEXT sampleProps = { diff --git a/util/test/demos/vk/vk_secondary_cmdbuf.cpp b/util/test/demos/vk/vk_secondary_cmdbuf.cpp index 09e021278..5d635bd8d 100644 --- a/util/test/demos/vk/vk_secondary_cmdbuf.cpp +++ b/util/test/demos/vk/vk_secondary_cmdbuf.cpp @@ -72,10 +72,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo()); diff --git a/util/test/demos/vk/vk_simple_triangle.cpp b/util/test/demos/vk/vk_simple_triangle.cpp index 8458718a2..57523ff54 100644 --- a/util/test/demos/vk/vk_simple_triangle.cpp +++ b/util/test/demos/vk/vk_simple_triangle.cpp @@ -74,10 +74,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo()); diff --git a/util/test/demos/vk/vk_structured_buffer_nested.cpp b/util/test/demos/vk/vk_structured_buffer_nested.cpp index 1f9382472..3168240c7 100644 --- a/util/test/demos/vk/vk_structured_buffer_nested.cpp +++ b/util/test/demos/vk/vk_structured_buffer_nested.cpp @@ -182,12 +182,12 @@ float4 main() : SV_Target0 )EOSHADER"; - int main(int argc, char **argv) + int main() { features.fragmentStoresAndAtomics = true; // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ diff --git a/util/test/demos/vk/vk_test.cpp b/util/test/demos/vk/vk_test.cpp index efda03acc..bedbe11ff 100644 --- a/util/test/demos/vk/vk_test.cpp +++ b/util/test/demos/vk/vk_test.cpp @@ -59,59 +59,265 @@ VulkanGraphicsTest::VulkanGraphicsTest() features.depthClamp = true; } -bool VulkanGraphicsTest::Init(int argc, char **argv) +namespace { - // parse parameters here to override parameters - GraphicsTest::Init(argc, argv); +bool volk = false; +bool spv = false; +VkInstance inst = VK_NULL_HANDLE; +VkPhysicalDevice selectedPhys = VK_NULL_HANDLE; +std::vector enabledInstExts; +std::vector enabledLayers; +}; - if(volkInitialize() != VK_SUCCESS) +void VulkanGraphicsTest::Prepare(int argc, char **argv) +{ + GraphicsTest::Prepare(argc, argv); + + static bool prepared = false; + + if(!prepared) { - TEST_ERROR("Couldn't init vulkan"); - return false; - } + prepared = true; - if(!SpvCompilationSupported()) - { - TEST_ERROR("glslc must be in PATH to run vulkan tests"); - return false; - } + volk = (volkInitialize() == VK_SUCCESS); - instExts.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + spv = SpvCompilationSupported(); + + if(volk && spv) + { + enabledInstExts.push_back(VK_KHR_SURFACE_EXTENSION_NAME); #if defined(WIN32) - instExts.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + enabledInstExts.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); #else - instExts.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); + enabledInstExts.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); - X11Window::Init(); + X11Window::Init(); #endif - if(debugDevice) - instExts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - else - optInstExts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + std::vector optInstExts; - std::vector layers; + // this is used by so many sub extensions, initialise it if we can. + optInstExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - std::vector supportedLayers; - CHECK_VKR(vkh::enumerateInstanceLayerProperties(supportedLayers)); + // enable debug utils when possible + optInstExts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - if(debugDevice) - { - for(const VkLayerProperties &layer : supportedLayers) - { - if(!strcmp(layer.layerName, "VK_LAYER_LUNARG_standard_validation")) + std::vector supportedLayers; + CHECK_VKR(vkh::enumerateInstanceLayerProperties(supportedLayers)); + + if(debugDevice) { - layers.push_back(layer.layerName); - break; + for(const VkLayerProperties &layer : supportedLayers) + { + if(!strcmp(layer.layerName, "VK_LAYER_LUNARG_standard_validation")) + { + enabledLayers.push_back(layer.layerName); + break; + } + } + } + + std::vector supportedExts; + CHECK_VKR(vkh::enumerateInstanceExtensionProperties(supportedExts, NULL)); + + // strip any extensions that are not supported + for(auto it = enabledInstExts.begin(); it != enabledInstExts.end();) + { + bool found = false; + for(VkExtensionProperties &ext : supportedExts) + { + if(!strcmp(ext.extensionName, *it)) + { + found = true; + break; + } + } + + if(found) + { + ++it; + } + else + { + DEBUG_BREAK(); + it = enabledInstExts.erase(it); + } + } + + // add any optional extensions that are supported + for(const char *search : optInstExts) + { + bool found = false; + for(VkExtensionProperties &ext : supportedExts) + { + if(!strcmp(ext.extensionName, search)) + { + found = true; + break; + } + } + + if(found) + enabledInstExts.push_back(search); + } + + vkh::ApplicationInfo app("RenderDoc autotesting", VK_MAKE_VERSION(1, 0, 0), + "RenderDoc autotesting", VK_MAKE_VERSION(1, 0, 0), VK_API_VERSION_1_0); + + VkResult vkr = vkCreateInstance(vkh::InstanceCreateInfo(app, enabledLayers, enabledInstExts), + NULL, &inst); + + if(vkr == VK_SUCCESS) + { + volkLoadInstance((VkInstance)inst); + + std::vector physDevices; + CHECK_VKR(vkh::enumeratePhysicalDevices(physDevices, inst)); + + std::vector physProps; + for(VkPhysicalDevice p : physDevices) + { + VkPhysicalDeviceProperties props; + vkGetPhysicalDeviceProperties(p, &props); + physProps.push_back(props); + } + + // default to the first discrete card + for(size_t i = 0; i < physDevices.size(); i++) + { + if(physProps[i].deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + { + selectedPhys = physDevices[i]; + break; + } + } + + // if none found, default to first + if(selectedPhys == VK_NULL_HANDLE && !physDevices.empty()) + selectedPhys = physDevices[0]; + + // allow command line override + for(int i = 0; i < argc; i++) + { + if(!strcmp(argv[i], "--gpu") && i + 1 < argc) + { + std::string needle = strlower(argv[i + 1]); + + const bool nv = (needle == "nv" || needle == "nvidia"); + const bool amd = (needle == "amd"); + const bool intel = (needle == "intel"); + + for(size_t p = 0; p < physDevices.size(); p++) + { + std::string haystack = strlower(physProps[p].deviceName); + + if(haystack.find(needle) != std::string::npos || + (nv && physProps[p].vendorID == 0x10DE) || (amd && physProps[p].vendorID == 0x1002) || + (intel && physProps[p].vendorID == 0x8086)) + { + selectedPhys = physDevices[p]; + break; + } + } + + break; + } + } } } } - std::vector supportedExts; - CHECK_VKR(vkh::enumerateInstanceExtensionProperties(supportedExts, NULL)); + instance = inst; + phys = selectedPhys; + instExts = enabledInstExts; - for(const char *search : instExts) + if(!volk) + Avail = "volk did not initialise - vulkan library is not available"; + else if(!spv) + Avail = InternalSpvCompiler() + ? "Internal SPIR-V compiler did not initialise" + : "Couldn't find 'glslc' in PATH - required for SPIR-V compilation"; + else if(instance == VK_NULL_HANDLE) + Avail = "Vulkan instance did not initialise"; + else if(phys == VK_NULL_HANDLE) + Avail = "Couldn't find vulkan physical device"; + + if(!Avail.empty()) + return; + + devExts.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + + VkPhysicalDeviceFeatures supported; + vkGetPhysicalDeviceFeatures(phys, &supported); + +#define CHECK_FEATURE(a) \ + if(features.a && !supported.a) \ + { \ + Avail = "Required physical device feature '" #a "' is not supported"; \ + return; \ + } + + CHECK_FEATURE(robustBufferAccess); + CHECK_FEATURE(fullDrawIndexUint32); + CHECK_FEATURE(imageCubeArray); + CHECK_FEATURE(independentBlend); + CHECK_FEATURE(geometryShader); + CHECK_FEATURE(tessellationShader); + CHECK_FEATURE(sampleRateShading); + CHECK_FEATURE(dualSrcBlend); + CHECK_FEATURE(logicOp); + CHECK_FEATURE(multiDrawIndirect); + CHECK_FEATURE(drawIndirectFirstInstance); + CHECK_FEATURE(depthClamp); + CHECK_FEATURE(depthBiasClamp); + CHECK_FEATURE(fillModeNonSolid); + CHECK_FEATURE(depthBounds); + CHECK_FEATURE(wideLines); + CHECK_FEATURE(largePoints); + CHECK_FEATURE(alphaToOne); + CHECK_FEATURE(multiViewport); + CHECK_FEATURE(samplerAnisotropy); + CHECK_FEATURE(textureCompressionETC2); + CHECK_FEATURE(textureCompressionASTC_LDR); + CHECK_FEATURE(textureCompressionBC); + CHECK_FEATURE(occlusionQueryPrecise); + CHECK_FEATURE(pipelineStatisticsQuery); + CHECK_FEATURE(vertexPipelineStoresAndAtomics); + CHECK_FEATURE(fragmentStoresAndAtomics); + CHECK_FEATURE(shaderTessellationAndGeometryPointSize); + CHECK_FEATURE(shaderImageGatherExtended); + CHECK_FEATURE(shaderStorageImageExtendedFormats); + CHECK_FEATURE(shaderStorageImageMultisample); + CHECK_FEATURE(shaderStorageImageReadWithoutFormat); + CHECK_FEATURE(shaderStorageImageWriteWithoutFormat); + CHECK_FEATURE(shaderUniformBufferArrayDynamicIndexing); + CHECK_FEATURE(shaderSampledImageArrayDynamicIndexing); + CHECK_FEATURE(shaderStorageBufferArrayDynamicIndexing); + CHECK_FEATURE(shaderStorageImageArrayDynamicIndexing); + CHECK_FEATURE(shaderClipDistance); + CHECK_FEATURE(shaderCullDistance); + CHECK_FEATURE(shaderFloat64); + CHECK_FEATURE(shaderInt64); + CHECK_FEATURE(shaderInt16); + CHECK_FEATURE(shaderResourceResidency); + CHECK_FEATURE(shaderResourceMinLod); + CHECK_FEATURE(sparseBinding); + CHECK_FEATURE(sparseResidencyBuffer); + CHECK_FEATURE(sparseResidencyImage2D); + CHECK_FEATURE(sparseResidencyImage3D); + CHECK_FEATURE(sparseResidency2Samples); + CHECK_FEATURE(sparseResidency4Samples); + CHECK_FEATURE(sparseResidency8Samples); + CHECK_FEATURE(sparseResidency16Samples); + CHECK_FEATURE(sparseResidencyAliased); + CHECK_FEATURE(variableMultisampleRate); + CHECK_FEATURE(inheritedQueries); + + std::vector supportedExts; + CHECK_VKR(vkh::enumerateDeviceExtensionProperties(supportedExts, phys, NULL)); + + for(const char *search : devExts) { bool found = false; for(VkExtensionProperties &ext : supportedExts) @@ -125,34 +331,41 @@ bool VulkanGraphicsTest::Init(int argc, char **argv) if(!found) { - TEST_ERROR("Required instance extension '%s' missing", search); - return false; - } - } - - // add any optional extensions that are supported - for(const char *search : optInstExts) - { - bool found = false; - for(VkExtensionProperties &ext : supportedExts) - { - if(!strcmp(ext.extensionName, search)) + // try the layers we're enabling + for(const char *layer : enabledLayers) { - found = true; - break; + std::vector layerExts; + CHECK_VKR(vkh::enumerateDeviceExtensionProperties(layerExts, phys, layer)); + + for(VkExtensionProperties &ext : layerExts) + { + if(!strcmp(ext.extensionName, search)) + { + found = true; + break; + } + } + + if(found) + break; + } + + if(!found) + { + Avail = "Required device extension '"; + Avail += search; + Avail += "' is not supported"; + return; } } - - if(found) - instExts.push_back(search); } +} - vkh::ApplicationInfo app("RenderDoc autotesting", VK_MAKE_VERSION(1, 0, 0), - "RenderDoc autotesting", VK_MAKE_VERSION(1, 0, 0), VK_API_VERSION_1_0); - - CHECK_VKR(vkCreateInstance(vkh::InstanceCreateInfo(app, layers, instExts), NULL, &instance)); - - volkLoadInstance((VkInstance)instance); +bool VulkanGraphicsTest::Init() +{ + // parse parameters here to override parameters + if(!GraphicsTest::Init()) + return false; if(debugDevice) { @@ -163,64 +376,6 @@ bool VulkanGraphicsTest::Init(int argc, char **argv) NULL, &debugUtilsMessenger)); } - std::vector physDevices; - CHECK_VKR(vkh::enumeratePhysicalDevices(physDevices, instance)); - - if(physDevices.empty()) - { - TEST_ERROR("No vulkan devices available"); - return false; - } - - std::vector physProps; - for(VkPhysicalDevice p : physDevices) - { - VkPhysicalDeviceProperties props; - vkGetPhysicalDeviceProperties(p, &props); - physProps.push_back(props); - } - - // default to the first discrete card - for(size_t i = 0; i < physDevices.size(); i++) - { - if(physProps[i].deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - { - phys = physDevices[i]; - break; - } - } - - // if none found, default to first - if(phys == VK_NULL_HANDLE) - phys = physDevices[0]; - - // allow command line override - for(int i = 0; i < argc; i++) - { - if(!strcmp(argv[i], "--gpu") && i + 1 < argc) - { - std::string needle = strlower(argv[i + 1]); - - const bool nv = (needle == "nv" || needle == "nvidia"); - const bool amd = (needle == "amd"); - const bool intel = (needle == "intel"); - - for(size_t p = 0; p < physDevices.size(); p++) - { - std::string haystack = strlower(physProps[p].deviceName); - - if(haystack.find(needle) != std::string::npos || (nv && physProps[p].vendorID == 0x10DE) || - (amd && physProps[p].vendorID == 0x1002) || (intel && physProps[p].vendorID == 0x8086)) - { - phys = physDevices[p]; - break; - } - } - - break; - } - } - std::vector queueProps; vkh::getQueueFamilyProperties(queueProps, phys); @@ -252,69 +407,9 @@ bool VulkanGraphicsTest::Init(int argc, char **argv) return false; }; - devExts.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - - VkPhysicalDeviceFeatures supported; - vkGetPhysicalDeviceFeatures(phys, &supported); - - const VkBool32 *enabledBegin = (VkBool32 *)&features; - const VkBool32 *enabledEnd = enabledBegin + sizeof(features); - - const VkBool32 *supportedBegin = (VkBool32 *)&features; - - for(; enabledBegin != enabledEnd; ++enabledBegin, ++supportedBegin) - { - if(*enabledBegin && !*supportedBegin) - { - TEST_ERROR("Feature enabled that isn't supported"); - return false; - } - } - - supportedExts.clear(); + std::vector supportedExts; CHECK_VKR(vkh::enumerateDeviceExtensionProperties(supportedExts, phys, NULL)); - for(const char *search : devExts) - { - bool found = false; - for(VkExtensionProperties &ext : supportedExts) - { - if(!strcmp(ext.extensionName, search)) - { - found = true; - break; - } - } - - if(!found) - { - // try the layers we're enabling - for(const char *layer : layers) - { - std::vector layerExts; - CHECK_VKR(vkh::enumerateDeviceExtensionProperties(layerExts, phys, layer)); - - for(VkExtensionProperties &ext : layerExts) - { - if(!strcmp(ext.extensionName, search)) - { - found = true; - break; - } - } - - if(found) - break; - } - - if(!found) - { - TEST_ERROR("Required device extension '%s' missing", search); - return false; - } - } - } - // add any optional extensions that are supported for(const char *search : optDevExts) { @@ -334,7 +429,7 @@ bool VulkanGraphicsTest::Init(int argc, char **argv) CHECK_VKR(vkCreateDevice(phys, vkh::DeviceCreateInfo({vkh::DeviceQueueCreateInfo(queueFamilyIndex, 1)}, - layers, devExts, features) + enabledLayers, devExts, features) .next(devInfoNext), NULL, &device)); @@ -382,29 +477,14 @@ bool VulkanGraphicsTest::Init(int argc, char **argv) vmaCreateAllocator(&allocInfo, &allocator); + VkPhysicalDeviceProperties physProps; + vkGetPhysicalDeviceProperties(phys, &physProps); + + TEST_LOG("Running Vulkan test on %s", physProps.deviceName); + return true; } -bool VulkanGraphicsTest::IsSupported() -{ - if(volkGetInstanceVersion() > 0) - return true; - - static bool glslcChecked = false; - static bool glslcSupported = false; - - if(!glslcChecked) - { - glslcChecked = true; - glslcSupported = SpvCompilationSupported(); - } - - if(!glslcSupported) - return false; - - return volkInitialize() == VK_SUCCESS; -} - GraphicsWindow *VulkanGraphicsTest::MakeWindow(int width, int height, const char *title) { #if defined(WIN32) @@ -919,6 +999,18 @@ void VulkanGraphicsTest::acquireImage() } } +void VulkanGraphicsTest::getPhysFeatures2(void *nextStruct) +{ + for(const char *ext : enabledInstExts) + { + if(!strcmp(ext, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) + { + vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(nextStruct)); + return; + } + } +} + VkResult VulkanGraphicsTest::CreateSurface(GraphicsWindow *win, VkSurfaceKHR *outSurf) { #if defined(WIN32) diff --git a/util/test/demos/vk/vk_test.h b/util/test/demos/vk/vk_test.h index 3fb6c8dd2..7c98fba22 100644 --- a/util/test/demos/vk/vk_test.h +++ b/util/test/demos/vk/vk_test.h @@ -140,9 +140,9 @@ struct VulkanGraphicsTest : public GraphicsTest VulkanGraphicsTest(); - bool Init(int argc, char **argv); + void Prepare(int argc, char **argv); + bool Init(); void Shutdown(); - bool IsSupported(); GraphicsWindow *MakeWindow(int width, int height, const char *title); VkResult CreateSurface(GraphicsWindow *win, VkSurfaceKHR *outSurf); @@ -182,20 +182,23 @@ struct VulkanGraphicsTest : public GraphicsTest void destroySwap(); void acquireImage(); + void getPhysFeatures2(void *nextStruct); + // requested features VkPhysicalDeviceFeatures features = {}; - // required extensions before Init(), enabled extensions after Init() + // enabled instance extensions std::vector instExts; + + // required extensions before Init(), enabled extensions after Init() std::vector devExts; + // optional extensions, will be added to devExts if supported (allows fallback paths) + std::vector optDevExts; + // a custom struct to pass to vkDeviceCreateInfo::pNext const void *devInfoNext = NULL; - // optional extensions - std::vector optInstExts; - std::vector optDevExts; - // core objects VkInstance instance; VkPhysicalDevice phys; @@ -244,4 +247,7 @@ struct VulkanGraphicsTest : public GraphicsTest // VMA VmaAllocator allocator = VK_NULL_HANDLE; + +private: + static bool prepared_vk; }; \ No newline at end of file diff --git a/util/test/demos/vk/vk_video_textures.cpp b/util/test/demos/vk/vk_video_textures.cpp index ed28628ec..ee011697e 100644 --- a/util/test/demos/vk/vk_video_textures.cpp +++ b/util/test/demos/vk/vk_video_textures.cpp @@ -219,18 +219,22 @@ void main() VkDescriptorSet descset; }; - int main(int argc, char **argv) + void Prepare(int argc, char **argv) { devExts.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); - // add required extensions + // add required dependency extensions devExts.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); devExts.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); devExts.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + VulkanGraphicsTest::Prepare(argc, argv); + } + + int main() + { // initialise, create window, create device, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ diff --git a/util/test/demos/vk/vk_vs_max_desc_set.cpp b/util/test/demos/vk/vk_vs_max_desc_set.cpp index 499aa005f..59c24d464 100644 --- a/util/test/demos/vk/vk_vs_max_desc_set.cpp +++ b/util/test/demos/vk/vk_vs_max_desc_set.cpp @@ -73,10 +73,10 @@ void main() )EOSHADER"; - int main(int argc, char **argv) + int main() { // initialise, create window, create context, etc - if(!Init(argc, argv)) + if(!Init()) return 3; VkPhysicalDeviceProperties props = vkh::getPhysicalDeviceProperties(phys);