diff --git a/Content/Documentation/WickedEngine-Documentation.md b/Content/Documentation/WickedEngine-Documentation.md index 4c6e4f95ee..d088988980 100644 --- a/Content/Documentation/WickedEngine-Documentation.md +++ b/Content/Documentation/WickedEngine-Documentation.md @@ -69,9 +69,10 @@ This is a reference for the C++ features of Wicked Engine 15. [RayTracingAccelerationStructure](#raytracingaccelerationstructure) 16. [RayTracingPipelineState](#raytracingpipelinestate) 17. [Variable Rate Shading](#variable-rate-shading) - 2. [GraphicsDevice_DX11](#wigraphicsdevice_dx11) - 3. [GraphicsDevice_DX12](#wigraphicsdevice_dx12) - 4. [GraphicsDevice_Vulkan](#wigraphicsdevice_vulkan) + 17. [Video decoding](#video-decoding) + 2. [GraphicsDevice_DX11](#graphicsdevice_dx11) + 3. [GraphicsDevice_DX12](#graphicsdevice_dx12) + 4. [GraphicsDevice_Vulkan](#graphicsdevice_vulkan) 2. [Renderer](#renderer) 1. [DrawScene](#drawscene) 2. [DrawScene_Transparent](#drawscene_transparent) @@ -693,6 +694,17 @@ The final shading rate will be determined from the above methods using the maxim To read more about variable rate shading, refer to the [DirectX specifications.](https://microsoft.github.io/DirectX-Specs/d3d/VariableRateShading) +##### Video Decoding +Video decoding can be used to decode compressed video bitstream in real time on the GPU. Currently only the H264 format is supported. To decode a video, the following steps need to be taken: +- Provide H264 slice data in a `GPUBuffer`. The slice data offset needs to be aligned within the buffer with `GraphcisDevice::GetVideoDecodeBitstreamAlignment()`. The bitstream buffer needs to be an `UPLOAD` buffer currently. +- Create `VideoDecoder` object, while providing appropriate paraemters parsed from H264 such as resolution, picture parameters, sequence parameters. The decode format must be `Format::NV12` which is a multi planar YUV420 format. +- Create a "Decode Picture Buffer" (DPB), which is a texture array storing reference and decoded images in the native video format (currently only `Format::NV12` is supported). Indicate in the `misc_flags` that it will be used as `ResourceMiscFlags::VIDEO_DECODE`. +- Run the `GraphicsDevice::VideoDecode` operation providing correct arguments to decode a single video frame. You are responsible to provide correct H264 arguments and DPB picture indices. +- You will need to manually read from the DPB texture (eg. in a shader) and resolve the YUV format to RGB if you want. + +All this is demonstrated in the [wi::video](../../WickedEngine/wiVideo.cpp) implementation. + + #### GraphicsDevice_DX11 The DirectX11 interface has been removed after version 0.56 @@ -752,14 +764,14 @@ Hardware accelerated ray tracing API is now available, so a variety of renderer After the acceleration structures are updated, ray tracing shaders can use it after binding to a shader resource slot. #### Ray tracing (legacy) -Ray tracing can be used in multiple ways to render the scene. The `RayTraceScene()` function will render the scene with the rays that are provided as the `RayBuffers` type argument. For example, to render the scene from the camera perspective, first create rays that originate from the camera and shoot towards the caera far plane for every pixel. The `GenerateScreenRayBuffers()` helper function implements this functionality, by expecting a [CameraComponent](#cameracomponent) argument and returns a `RayBuffers` structure. The result will be written to a texture that is provided as parameter. The texture must have been created with `UNORDERED_ACCESS` bind flags, because it will be written in compute shaders. The scene BVH structure must have been already built to use this, it can be accomplished by calling [wi::renderer::BuildSceneBVH()](#build-scene-bvh). The [RenderPath3D_Pathracing](#renderpath3d_pathtracing) uses this ray tracing functionality to render a path traced scene. +Ray tracing can be used in multiple ways to render the scene. The `RayTraceScene()` function will render the scene with path tracing. The result will be written to a texture that is provided as parameter. The texture must have been created with `UNORDERED_ACCESS` bind flags, because it will be written in compute shaders. The scene BVH structure must have been already built to use this, it can be accomplished by calling `wi::renderer::UpdateRaytracingAccelerationStructures()`. The [RenderPath3D_Pathracing](#renderpath3d_pathtracing) uses this ray tracing functionality to render a path traced scene. Other than path tracing, the scene BVH can be rendered by using the `RayTraceSceneBVH` function. This will render the bounding box hierarchy to the screen as a heatmap. Blue colors mean that few boxes were hit per pixel, and with more bounding box hits the colors go to green, yellow, red, and finaly white. This is useful to determine how expensive a the scene is with regards to ray tracing performance. The lightmap baking is also using ray tracing on the GPU to precompute static lighting for objects in the scene. [Objects](#objectcomponent) that contain lightmap atlas texture coordinate set can start lightmap rendering by setting `ObjectComponent::SetLightmapRenderRequest(true)`. Every object that have this flag set will have their lightmaps updated by performing ray traced rendering by the [wi::renderer](#wi::renderer) internally. Lightmap texture coordinates can be generated by a separate tool, such as the Wicked Engine Editor application. Lightmaps will be rendered to a global lightmap atlas that can be used by all shaders to read static lighting data. The global lightmap atlas texture contains lightmaps from all objects inside the scene in a compact format for performance. Apart from that, each object contains its own lightmap in a full precision texture format that can be post-processed and saved to disc for later use. To denoise lightmaps, follow the same steps as the path tracer denoiser setup described in the [Denoiser](#denoiser) section. #### Scene BVH -The scene BVH can be rebuilt from scratch using the `wi::renderer::BuildSceneBVH()` function. This will use the global scene to build the BVH hierarchy and global material atlases. The [ray tracing](#ray-tracing) features require the scene BVH to be built before using them. This is using the [wiGPUBVH](#wigpubvh) facility to build the BVH using compute shaders running on the GPU. +The scene BVH can be rebuilt from scratch using the `wi::renderer::UpdateRaytracingAccelerationStructures()` function. The [ray tracing](#ray-tracing) features require the scene BVH to be built before using them. This is using the [wiGPUBVH](#wigpubvh) facility to build the BVH using compute shaders running on the GPU when hardware ray tracing is not available. Otherwise it uses ray tracing acceleration structure API objects. #### Decals The [DecalComponents](#decalcomponent) in the scene can be rendered differently based on the rendering technique that is being used. The two main rendering techinques are forward and deferred rendering. diff --git a/Editor/VideoWindow.cpp b/Editor/VideoWindow.cpp index f6113a966b..2cb9c2e4d9 100644 --- a/Editor/VideoWindow.cpp +++ b/Editor/VideoWindow.cpp @@ -31,7 +31,7 @@ void VideoWindow::Create(EditorComponent* _editor) { editor = _editor; wi::gui::Window::Create(ICON_VIDEO " Video", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); - SetSize(XMFLOAT2(440, 600)); + SetSize(XMFLOAT2(440, 840)); closeButton.SetTooltip("Delete VideoComponent"); OnClose([=](wi::gui::EventArgs args) { @@ -163,7 +163,7 @@ void VideoWindow::Create(EditorComponent* _editor) AddWidget(&preview); infoLabel.Create(""); - infoLabel.SetSize(XMFLOAT2(800, 600)); + infoLabel.SetSize(XMFLOAT2(800, 500)); AddWidget(&infoLabel); diff --git a/README.md b/README.md index 9408b39efa..c0d0e2d2e2 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@
- + Wicked Engine is an open-source C++ engine focusing on modern rendering techniques and performance. Use this as a framework for your graphics projects, or learning. Some programming skills are required for the best experience, but some simple tools like an Editor are also included. It is free to be used for anything good.
This project is hosted on GitHub. @@ -25,8 +25,7 @@ You can download the source code by using Git and cloning the repository, or dow Tip: try loading models or scripts from the Content folder using the Editor app to see how everything works.
- - + ### Platforms: - Windows 10 or newer @@ -38,11 +37,13 @@ Tip: try loading models or scripts from the Content folder using the Editor app #### Windows To build Wicked Engine for Windows 10, use Visual Studio and the provided `WickedEngine.sln` solution file. There are a couple of projects that you can run up front: Editor, Tests and Template. You just have to set either as startup project and press F5 in Visual Studio to build and run. For optimal performance, choose `Release` mode, for the best debugging experience, choose `Debug` mode. - + If you want to develop an application that uses Wicked Engine, you can build the WickedEngine static library project for the appropriate platform, such as `WickedEngine_Windows` and link against it. Including the `"WickedEngine.h"` header will attempt to link the binaries for the appropriate platform, but search directories should be set up beforehand. For example, you can set additional library directories to `$(SolutionDir)BUILD\$(Platform)\$(Configuration)` by default. For examples, see the `Template`, `Tests`, and `Editor` projects. -You can also download prebuilt and packaged versions of the Editor and Tests here: [![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions) +You can also download prebuilt and packaged versions of the Editor and Tests here (requires Github sign in): [![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions) + + If you have questions or stuck, please use the `windows` communication channel on Discord: [![Discord chat](https://img.shields.io/discord/602811659224088577?logo=discord)](https://discord.gg/CFjRYmE) @@ -52,6 +53,9 @@ Cmake: It is possible to build the windows version with Cmake, but the recommend #### Linux To build the engine for Linux, use Cmake. You can find a sample build script for Ubuntu 20.04 [here](.github/workflows/build.yml) (in the linux section). You might need to install some dependencies, such as Cmake (3.7 or newer), g++ compiler (C++ 17 compliant version) and SDL2. For Ubuntu 20.04, you can use the following commands to install dependencies: + + + ```bash sudo apt update sudo apt install libsdl2-dev @@ -67,7 +71,7 @@ make If you want to develop an application that uses Wicked Engine, you will have to link to libWickedEngine.a and `#include "WickedEngine.h"` into the source code. For examples, look at the Cmake files, or the Tests and the Editor applications. -You can also download prebuilt and packaged versions of the Editor and Tests here: [![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions) +You can also download prebuilt and packaged versions of the Editor and Tests here (requires Github sign in): [![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions) If you have questions or stuck, please use the `linux` communication channel on Discord: [![Discord chat](https://img.shields.io/discord/602811659224088577?logo=discord)](https://discord.gg/CFjRYmE) @@ -76,7 +80,7 @@ If you have questions or stuck, please use the `linux` communication channel on #### Initialization (C++): - + ```cpp // Include engine headers: @@ -96,6 +100,8 @@ while(true) { #### Basics (C++): ```cpp +wi::initializer::InitializeComponentsImmediate(); // (Optional) allows to initialize all components immediately and block the application until finished. Otherwise the initialization will take place at the first application.Run() asynchronously. This is useful if you want to start using other parts of the engine before application.Run() is called. + wi::RenderPath3D myGame; // Declare a game screen component, aka "RenderPath" (you could also override its Update(), Render() etc. functions). application.ActivatePath(&myGame); // Register your game to the application. It will call Start(), Update(), Render(), etc. from now on... @@ -174,7 +180,7 @@ For more code samples and advanced use cases, please see the example projects, l ### Scripting API: - + You can use a great number of engine features through the Lua scripting api, which can even be used real time while the program is running. The included applications, like the Editor, contain a scripting input method toggled by the "Home" key. A blue screen will be presented where the user can type in LUA commands. It is very minimal in regards to input methods. @@ -191,6 +197,8 @@ In addition, the Editor supports the importing of some common model formats (the The preferred workflow is to import models into the Editor, and save them as WISCENE, then any Wicked Engine application can open them.
+ + ### Graphics API: The default renderer is `DirectX 12` on Windows and `Vulkan` on Linux. The `DirectX 11` renderer is no longer available starting from version 0.57.0, but it can be found on the dx11-backup branch. You can specify command line arguments (without any prefix) to switch between render devices or other settings. Currently the list of options: @@ -229,8 +237,8 @@ You can specify command line arguments (without any prefix) to switch between re - +
### Other software using Wicked Engine @@ -245,78 +253,11 @@ If you are having trouble getting the applications to run, make sure that you sa - If you built the application with Visual Studio, run it from the Visual Studio environment, where the executable working directory is set up to be the Project directory (not the build directory where the exe will be found) - If you want to run an application without Visual Studio, either copy the executable from the BUILD directory to the correct project directory, or set the working directory appropriately. You can also check the Working directory setting in Visual Studio to find out the right working directory of every project. - If you want to build UWP application, then you will first need to build the shaders into a shader dump. For that, build and run the `offlineshadercompiler` project with the `hlsl6 shaderdump` command line arguments. If the `wiShaderDump.h` file is successfully generated, rebuilding the engine will embed all the shader files so they are not loaded separately. But embedded shaders also cannot be recompiled during runtime. + + + - If you experience crashes, follow these steps to find out the problem: - make sure your environment is up to date, with latest graphics drivers and operating system updates. - see if there is a wiBackLog.txt in your user temp folder (for example: C:\Users\username\AppData\Local\Temp), and request help on Discord or Github issue - build the engine in Debug mode and try to run it, see where it crashes, provide call stack on Discord or Github issue - run the engine with the `debugdevice` command argument and post the text from your console output window when the crash happens - -
- -### Screenshots: - -Procedural terrain generator: -![ProceduralTerrain](https://turanszkij.files.wordpress.com/2022/04/procedural_terrain.png) - -Path tracing: -![PathTracing](https://turanszkij.files.wordpress.com/2022/04/sanmiguel.png) - -Dynamic Diffuse Global Illumination (DDGI): -![DDGI](https://turanszkij.files.wordpress.com/2022/04/ddgi.png) - -Snow storm with particle systems: -![SnowStorm](https://turanszkij.files.wordpress.com/2022/04/snowstorm.png) - -Sponza scene with voxel GI enabled: -![Sponza](https://turanszkij.files.wordpress.com/2020/08/vxgi_sponza_small.png) - -Damaged Helmet sample model imported from GLTF: -![Sponza](https://turanszkij.files.wordpress.com/2019/03/damagedhelmet.png) - -Bokeh Depth of Field (Lain model by woopoodle at Sketchfab): -![DepthOfField](https://turanszkij.files.wordpress.com/2020/08/dof_bokeh_small.png) - -Motion blur (fighting game sample): -![MotionBlur](https://turanszkij.files.wordpress.com/2019/12/motionblur.png) - -Stochastic Screen Space Reflections: -![ScreenSpaceReflections](https://turanszkij.files.wordpress.com/2020/08/ssr.png) - -Real time ray traced shadows and ambient occlusion (DXR, VK_KHR_raytracing): -![RaytracedShadows](https://turanszkij.files.wordpress.com/2020/08/dxr_rtao_rtshadow_small.png) - -Bloom: -![Bloom](https://turanszkij.files.wordpress.com/2020/08/bloom_new.png) - -Path tracing in the living room (model from Morgan McGuire's graphics archive): -![LivingRoom](https://turanszkij.files.wordpress.com/2019/09/livingroom.jpg) - -City scene with a light map (model by Michael Gallie at CgTrader): -![City](https://turanszkij.files.wordpress.com/2019/01/city1.png) - -Path tracing in the city: -![Balcony](https://turanszkij.files.wordpress.com/2019/01/city2.png) - -Path traced caustics: -![Caustics](https://turanszkij.files.wordpress.com/2019/01/trace.png) - -Vegetation particle system and depth of field: -![Vegetation](https://turanszkij.files.wordpress.com/2020/08/grass.png) - -Bistro scene from Amazon Lumberyard (model from Morgan McGuire's graphics archive): -![Bistro_out](https://turanszkij.files.wordpress.com/2019/01/bistro_out_0.png) - -Bistro scene from the inside: -![Bistro_in](https://turanszkij.files.wordpress.com/2019/01/bistro_in_2.png) - -Parallax occlusion mapping: -![ParallxOcclusionMapping](https://turanszkij.files.wordpress.com/2019/01/pom.png) - -Large scale particle simulation on the GPU: -![ParticleSimulation](https://turanszkij.files.wordpress.com/2020/08/particles_2.png) - -Tiled light culling in the Bistro: -![TiledLightCulling](https://turanszkij.files.wordpress.com/2019/02/bistro_heatmap-1.png) - -GPU-based BVH builder: -![GPU_BVH](https://turanszkij.files.wordpress.com/2019/07/bvh_livingroom.png) diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index c4e0a9fa0a..5c6f7980c9 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -2978,7 +2978,7 @@ using namespace dx12_internal; wi::helper::messageBox(ss.str(), "Warning!"); } - wi::backlog::post("Created GraphicsDevice_DX12 (" + std::to_string((int)std::round(timer.elapsed())) + " ms)"); + wi::backlog::post("Created GraphicsDevice_DX12 (" + std::to_string((int)std::round(timer.elapsed())) + " ms)\Adapter: " + adapterName); } GraphicsDevice_DX12::~GraphicsDevice_DX12() { diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index a3d4cb8eb4..8cd0d473bc 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -1466,7 +1466,7 @@ using namespace vulkan_internal; cbSubmitInfo.commandBuffer = cmd.transitionCommandBuffer; signalSemaphoreInfos[0].semaphore = cmd.semaphores[1]; // signal for compute queue - signalSemaphoreInfos[1].semaphore = cmd.semaphores[2]; // signal for video decode queue + signalSemaphoreInfos[0].stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; // signal for compute queue submitInfo.waitSemaphoreInfoCount = 1; submitInfo.pWaitSemaphoreInfos = &waitSemaphoreInfo; @@ -1474,6 +1474,8 @@ using namespace vulkan_internal; submitInfo.pCommandBufferInfos = &cbSubmitInfo; if (device->queues[QUEUE_VIDEO_DECODE].queue != VK_NULL_HANDLE) { + signalSemaphoreInfos[1].semaphore = cmd.semaphores[2]; // signal for video decode queue + signalSemaphoreInfos[1].stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; // signal for video decode queue submitInfo.signalSemaphoreInfoCount = 2; } else @@ -1490,7 +1492,7 @@ using namespace vulkan_internal; if (device->queues[QUEUE_VIDEO_DECODE].queue != VK_NULL_HANDLE) { waitSemaphoreInfo.semaphore = cmd.semaphores[2]; // wait for graphics queue - waitSemaphoreInfo.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + waitSemaphoreInfo.stageMask = VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR; submitInfo.waitSemaphoreInfoCount = 1; submitInfo.pWaitSemaphoreInfos = &waitSemaphoreInfo; @@ -3492,7 +3494,7 @@ using namespace vulkan_internal; assert(res == VK_SUCCESS); } - wi::backlog::post("Created GraphicsDevice_Vulkan (" + std::to_string((int)std::round(timer.elapsed())) + " ms)"); + wi::backlog::post("Created GraphicsDevice_Vulkan (" + std::to_string((int)std::round(timer.elapsed())) + " ms)\nAdapter: " + adapterName); } GraphicsDevice_Vulkan::~GraphicsDevice_Vulkan() { @@ -3896,6 +3898,7 @@ using namespace vulkan_internal; } if (has_flag(buffer->desc.bind_flags, BindFlag::UNORDERED_ACCESS)) { + barrier.dstAccessMask |= VK_ACCESS_2_SHADER_READ_BIT; barrier.dstAccessMask |= VK_ACCESS_2_SHADER_WRITE_BIT; } if (has_flag(buffer->desc.misc_flags, ResourceMiscFlag::INDIRECT_ARGS)) @@ -4324,9 +4327,9 @@ using namespace vulkan_internal; barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.baseArrayLayer = 0; - barrier.subresourceRange.layerCount = imageInfo.arrayLayers; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; barrier.subresourceRange.baseMipLevel = 0; - barrier.subresourceRange.levelCount = imageInfo.mipLevels; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index dcaaa5ed1c..c93c0bc412 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -243,11 +243,11 @@ namespace wi::graphics renderpass_barriers_end.clear(); } - inline VkCommandPool GetCommandPool() const + constexpr VkCommandPool GetCommandPool() const { return commandPools[buffer_index][queue]; } - inline VkCommandBuffer GetCommandBuffer() const + constexpr VkCommandBuffer GetCommandBuffer() const { return commandBuffers[buffer_index][queue]; }