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);